I have written a sample spring application which have some rest services protected using spring-security-oauth2
. Now I want to move these services to the original application which uses spring security form login.
In the original application I want rest services to be protected from spring-security-oauth2
and other spring controllers to be protected using a form login. What I want to know is, is this approach is right or wrong, if right, how could I complete this action.
This is Sample app codes, which uses 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;
}
}
}
Here is a part of the original app configuration.
@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();
}
}
Spring Security is built on an ordered list of filter chains, and for each request the first one with a matching path handles the authentication. You have 3 filter chains in your combined app, one created by @EnableAuthorizationServer
(with default order=0), one created by @EnableResourceServer
(with default order=3), and one created by your MyStaysureSecurityConfiguration
(also with order=0). You aren't allowed to have 2 filters with the same order so you need to re-arrange them and give them request matchers that make sense for your use case. Maybe you didn't need the @EnableAuthorizationServer
anyway (it was unclear from the question)? In any case it is pretty simple - you have 2 choices (roughly):
exclude the oauth2 resources from the request matchers in your
MyStaysureSecurityConfiguration
and allow them to be handled by the resource server filter.re-order the resource server filter to a lower order and give it a request matcher that only matches the oauth2 resources.
来源:https://stackoverflow.com/questions/29893602/spring-security-form-logging-and-outh2-in-same-app