I have a problem about sending some requests from management service to advertisement service through the port number of management service.
http://localhost:9002/api/v1/admin_role/alladvertisements
http://localhost:9002/api/v1/user_role/alladvertisements
I got 403 forbidden issue for two urls shown above. I used access token as bearer token for both user and admin. While admin is responsible for its own requests, user can only handle with its process.
Here are the results of two urls.
{
"timestamp": "2022-08-31T23:58:15.250+00:00",
"status": 403,
"error": "Forbidden",
"path": "/api/v1/admin_role/alladvertisements"
}
{
"timestamp": "2022-08-31T23:58:15.250+00:00",
"status": 403,
"error": "Forbidden",
"path": "/api/v1/user_role/alladvertisements"
}
Here is the web security part of management service.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/api/v1/admin_role/*").hasAnyRole("ROLE_ADMIN")
.antMatchers("/api/v1/user_role/*").hasAnyRole("ROLE_USER")
.antMatchers("/actuator/health").hasAnyRole("ROLE_ADMIN")
.antMatchers("/actuator/circuitbreakerevents").hasAnyRole("ROLE_ADMIN")
.anyRequest()
.permitAll();
}
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider provider = keycloakAuthenticationProvider();
provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(provider);
}
@Override
@Bean
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
}
How can I fix it?
Here is my github repository : Link
If you did not change the default GrantedAuthority
prefix - "ROLE_", then
SecurityExpressionRoot
's .hasRole()
and .hasAnyRole()
methods will add this prefix to passed arguments. You can read it here and here.
Also, as stated in the javadoc, SimpleAuthorityMapper
also adds "ROLE_" prefix to roles, when it maps GrantedAuthority
.
That means, when you pass "ROLE_ADMIN" to there methods, it converts it into "ROLE_ROLE_ADMIN", and you get 403 status as a result.
So, try to configure security without prefixes, like this:
.antMatchers("/api/v1/admin_role/*").hasRole("ADMIN")
.antMatchers("/api/v1/user_role/*").hasRole("USER")
Or you can use .hasAuthority()
or .hasAnyAuthority()
method instead, which doesn't change passed argument:
.antMatchers("/api/v1/admin_role/*").hasAuthority("ROLE_ADMIN")
.antMatchers("/api/v1/user_role/*").hasAuthority("ROLE_USER")