我编写了一个示例spring应用程序,它使用spring-security-oauth2
保护了一些其他服务。现在我想将这些服务移动到使用spring security form登录的原始应用程序。
在原始应用程序中,我希望保护其他服务不受spring-security-oauth2
和其他弹簧控制器的影响,使用表单登录进行保护。我想知道的是,这种方法是对还是错,如果正确的话,我怎么能完成这个动作。
这是示例应用代码,使用ouath2,
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService; // Is this really needed?
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@Configuration
public class OAuth2ServerConfiguration {
private static final String RESOURCE_ID = "restservice";
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
// @formatter:off
resources.resourceId(RESOURCE_ID);
// @formatter:on
}
@Override
public void configure(HttpSecurity http) throws Exception {
// http.authorizeRequests().antMatchers("/test").not().permitAll();
http.authorizeRequests().antMatchers("/test").authenticated();
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private TokenStore tokenStore = new InMemoryTokenStore();
@Autowired
// @Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// @formatter:off
endpoints.tokenStore(this.tokenStore).authenticationManager(this.authenticationManager);
// @formatter:on
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// @formatter:off
clients.inMemory().withClient("clientapp").authorizedGrantTypes("password", "refresh_token").authorities("USER")
.scopes("read", "write").resourceIds(RESOURCE_ID).secret("123456");
// @formatter:on
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
}
}
以下是原始应用配置的一部分。
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MyStaysureSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.inMemoryAuthentication().withUser("mycompany").password("mypsswd").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/rest/*", "/api-docs/**").permitAll().antMatchers("/**").authenticated().and().formLogin().defaultSuccessUrl("/dashboard").and().csrf().disable();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
答案 0 :(得分:2)
Spring Security构建在一个有序的过滤器链列表上,对于每个请求,第一个具有匹配路径的请求处理认证。您在组合应用中有3个过滤器链,一个由@EnableAuthorizationServer
创建(默认顺序= 0),一个由@EnableResourceServer
创建(默认顺序= 3),另一个由{{1创建(也是order = 0)。您不能拥有2个具有相同订单的过滤器,因此您需要重新排列它们并为它们提供对您的用例有意义的请求匹配器。也许你无论如何都不需要MyStaysureSecurityConfiguration
(从问题中不清楚)?无论如何它很简单 - 你有两个选择(大致):
从@EnableAuthorizationServer
中的请求匹配器中排除oauth2资源,并允许资源服务器过滤器处理它们。
将资源服务器过滤器重新排序为较低的顺序,并为其提供仅匹配oauth2资源的请求匹配器。