Spring Boot で実装している Web API に、Spring Security を使って認証を追加することにした。
最終的には OAuth にする予定だけど、今はまだ検証用のプロトタイプを作っている段階なので、とりあえず Basic 認証で。
まず build.gradle を修正して、Spring Security を追加する。
buildscript {
ext {
springBootVersion = '1.5.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
compile('org.springframework.boot:spring-boot-starter-security')
}
Basic 認証を組み込んだ、最小の Spring Boot アプリケーションがこちら。
package jp.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class BasicAuthExampleApplication {
public static void main(String[] args) {
SpringApplication.run(BasicAuthExampleApplication.class, args);
}
@RestController
public static class HomeController {
@GetMapping("/api/goodmorning")
public String goodMorning() {
return "Good morning";
}
@GetMapping("/api/hello")
public String hello() {
return "Hello world";
}
}
@Configuration
@EnableWebSecurity
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.inMemoryAuthentication()
.withUser("test_user").password("test_pass").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/api/goodmorning")
.permitAll()
.anyRequest()
.authenticated();
}
}
}
Python の REPL で動作確認。
>>> import requests
>>> requests.get("http://localhost:8080/api/goodmorning").text
u'Good morning'
>>> requests.get("http://localhost:8080/api/hello").text
u'{"timestamp":1498106201915,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/api/hello"}'
>>> requests.get("http://localhost:8080/api/hello", auth=("test_user", "test_pass")).text
u'Hello world'