我試圖在同一個Spring Boot MVC應用程序中集成正常形式+會話登錄和OAuth2。這可能是我對Spring Security配置如何工作的誤解。我也嘗試在Sparklr示例應用中修改配置,但我無法解決這個問題。Spring Security Web + OAuth2
我希望任何與「/ web/**」匹配的url可以通過表單登錄(包括重定向到登錄頁面)進行驗證,除了「resources/**」,「/ web/register」以及當然「/login「 我還需要任何匹配」/ api/**「的url來要求除」/ api/register「之外的OAuth2令牌
目前看起來只有ResourceServerConfigurerAdapter
正在生效。我嘗試過無數個規則組合,但似乎無法獲得我想要的效果。在查看調試輸出時,我可以看到它試圖匹配OAuth端點,然後匹配我的API端點,但不匹配任何Web端點。
如果我得到表單登錄工作,那麼我需要通過OAuth2加以保護的網址才允許匿名訪問。理解這個/獲得它的任何幫助表示讚賞。
這裏是我的配置:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login", "/resources/**", "/web/register").permitAll()
//.anyRequest().authenticated()
.antMatchers("/web/**").authenticated()
.and()
.exceptionHandling().accessDeniedPage("/login?authorization_error=true")
.and()
.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/api/users/register")).disable()
.logout().logoutUrl("/logout").logoutSuccessUrl("/login")
.and()
.formLogin().loginProcessingUrl("/login").failureUrl("/login?authorization_error=true").defaultSuccessUrl("/web/home").loginPage("/login");
}
@Autowired
private CustomDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@Configuration
public class OAuth2ServerConfig {
private static final String TEST_RESOURCE_ID = "test";
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(TEST_RESOURCE_ID).stateless(false); }
@Override
public void configure(HttpSecurity http) throws Exception {
http
// Since we want the protected resources to be accessible in the UI as well we need
// session creation to be allowed (it's disabled by default in 2.0.6)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and().authorizeRequests()
.antMatchers("/api/users/register").permitAll()
.antMatchers("/api/**").access("#oauth2.isOAuth() and hasRole('ROLE_USER')")
;
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("testapp")
.resourceIds(TEST_RESOURCE_ID)
.authorizedGrantTypes("authorization_code", "refresh_token",
"password")
.authorities("USER")
.scopes("read", "write")
.secret("secret");
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore)
.userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm("test/client");
}
}
protected static class Approvals {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private TokenStore tokenStore;
@Bean
public ApprovalStore approvalStore() throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
@Bean
@Lazy
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public CustomUserApprovalHandler userApprovalHandler() throws Exception {
CustomUserApprovalHandler handler = new CustomUserApprovalHandler();
handler.setApprovalStore(approvalStore());
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
handler.setUseApprovalStore(true);
return handler;
}
}
}