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')
// Spring Security を追加
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() // Basic 認証を有効にする .and() .authorizeRequests() .antMatchers("/api/goodmorning") // /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'