I have a REST API secured with OAuth2.0
I am able to get the access-token using http://localhost:8085/auth/token?grant_type=password&[email protected]&password=mypass(along with username pass basic auth).
But when I am trying to access http://localhost:8085/api/v1/signup , API returns a 401 unauthorized
error.
Though I have used antMatchers("/signup").permitAll()
, why API is expecting a access-token
to access this resource? Passing access-token
along with this request would signup a user.
This is my resource server configuration
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
//require beans and methods here
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider());
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.csrf().disable();
}
}
Update: As suggested by this thread, I ignored /signup
at ``, but that also didn't worked.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@ComponentScan(basePackages = { "com.sample.rest.security" })
@Order(2)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//other Beans & methods
@Override
protected void configure(HttpSecurity http) throws Exception {
List<RequestMatcher> requestMatchers = new ArrayList<RequestMatcher>();
requestMatchers.add(new AntPathRequestMatcher("/signup/**"));
http.
requestMatcher(new OrRequestMatcher(requestMatchers)).
authorizeRequests().antMatchers("/signup/**")
.permitAll();
}
}
I got the issue. It was the context path which was causing the issue. I am having a dispatcher servlet defined with a mapping URL /api/v1/*
and as one can see my signup
request, it contains a context path i.e http://localhost:8085/api/v1/signup
For OAuth2 configuration in Spring, we need to take extra care of context path. First, it should be defined in the AuthorizationServer
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.prefix("/api/v1") //here
.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
}
Then, the context must be added to the permitAll()
path like this
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/v1/signup").permitAll() //context path here
.anyRequest().authenticated();
}
Up till now, the signup request is still expected to pass a access token with it. For removing the OAuth security from signup, we need to remove security at the WebSecurity
, which can be done using WebSecurityConfigurerAdapter
@EnableWebSecurity
@EnableGlobalMethodSecurity
@ComponentScan(basePackages = { "com.sample.rest.security" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers("/signup");
}
//////////// OR use below method ///////////
/* @Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().antMatchers("/signup/**").permitAll();
}
*/
}
Note, there is no use to add context path to the WebSecurityConfigurerAdapter
configuration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With