スプリング ブート アプリケーションでスプリング セキュリティ oauth2 とフォーム ログインを機能させようとしています。
https://github.com/spring-projects/spring-security-oauth/tree/master/samples/oauth2/sparklrからヒントを得ました
と
https://github.com/royclarkson/spring-rest-service-oauth/issues/11
以下は私の構成です
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Inject
private AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler;
@Inject
private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler;
@Inject
private AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler;
@Inject
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/scripts/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/assets/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/account/reset_password/init")
.antMatchers("/api/account/reset_password/finish")
.antMatchers("/api/home/**")
.antMatchers("/api/product/**")
.antMatchers("/test/**")
.antMatchers("/devadmin/**")
.antMatchers("/signin")
.antMatchers("/static/api-guide.html");
}
@Override
@Order(Ordered.HIGHEST_PRECEDENCE)
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable().authorizeRequests().antMatchers("/web/**","/for","/admin","/here").authenticated()
.and()
.formLogin()
.loginProcessingUrl("/web/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.logout()
.logoutUrl("/web/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.exceptionHandling()
;
}
@Configuration
@EnableAuthorizationServer
@EnableConfigurationProperties(SecurityConfigurationProperties.class)
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter implements EnvironmentAware {
private static final String ENV_OAUTH = "authentication.oauth.";
private static final String PROP_CLIENTID = "clientid";
private static final String PROP_SECRET = "secret";
private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds";
private RelaxedPropertyResolver propertyResolver;
@Inject
private DataSource dataSource;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Inject
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.tokenStore(tokenStore())
.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient(propertyResolver.getProperty(PROP_CLIENTID))
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
.authorizedGrantTypes("password", "refresh_token")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800));
}
@Override
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH);
}
}
@Order(2)
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.requestMatchers().antMatchers("/api/**")
.and()
.authorizeRequests().antMatchers("/api /**").access("#oauth2.hasScope('read') and hasRole('ROLE_USER')");
// @formatter:on
}
}
}
上記の構成では、認証を試みると oauth2 ログインが正常に機能します
/oauth/トークン
ただし、経由でログインします
/ウェブ/認証
常に表示
405リクエストメソッド「POST」はサポートされていません
usernamepasswordauthenticationfilter が呼び出されていません。
上記のコードの ResourceServerConfiguration 部分をコメントした後、
フォームログイン
/ウェブ/認証
正常に動作しています。
また、ログから usernamepasswordauthenticationfilter が呼び出されていることも確認できます。
私の質問は、エンドポイントでさえ oauth2 リソース サーバーとフォーム ログインで異なるように構成されていることです。なぜ oauth2 がフォーム ログインの httpsecurity をオーバーライドし、リソース サーバーの構成時に usernamepasswordauthenticationfilter が呼び出されないのですか?