I have configured a custom Filter
that grants a spring authority for every URL other than /login
:
public class TokenFilter impleme
I know that this is a very old question but I just had the same error and I didn't find any solution on the internet.
It is correct that 403 means that the user is authenticated but not authorized to get a resource. This is related to the claims part in your JWT.
Your JWT builder needs to set proper claims for the user :
List<GrantedAuthority> grantedAuthorities = AuthorityUtils
.commaSeparatedStringToAuthorityList("ROLE_USER");
Jwts.builder()//
.setIssuer(...)//
.setSubject(...)//
.setAudience(...)
// This is the part that you missed
.claim("authorities",
grantedAuthorities.stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList()))
// Ends here
.setIssuedAt(date)//
.setExpiration(new Date(date.getTime() + jwtExpirationMs))
.signWith(SignatureAlgorithm.HS512, signingKey)//
.compact();
My WebSecurity configuration :
public class WebSecurity extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()//
.authorizeRequests()//
.antMatchers(...).permitAll()//
.anyRequest().authenticated()
.and()
.sessionManagement()//
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterAfter(authenticationJwtTokenFilter(), BasicAuthenticationFilter.class);
}
The only (obvious) thing that might result to 403 is the users role is not set to ROLE_myAuthority
.
Getting a 403 instead of a 401 usually means that you were logged in but you are not permitted (via authority) to see a resource.
Debug and confirm that the user you are logging in has that authority (I know your code sets it, but maybe you are setting something else wrong).
I have the same issue to you, every request is blocked by 403 error, except the [/] request. After a lot of time in crazy, I found the root cause, that is the [csrf].
Then my security config is like as following:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/delete/**").authenticated().and().httpBasic().and().csrf().disable();
}
This configuration says that: only [delete/**] should be authorized.
And I mark the [delete] action as following:
@PreAuthorize("hasRole('ROLE_ADMIN')")
void delete(String id);
Hope to help someone.
Pretty old question but just in case someone stumble upon this post, an application had the same problem and it turns out to be an issue with @ControllerAdvice
.
Basically, the setup was like this:
@ControllerAdvice
class MainController {
@PreAuthorize("...")
class AdminController extends MainController {
And for a strange reason, any controller extending from MainController
would trigger the @PreAuthorize
of the AdminController
class even though there were no relationships between this controller and the latter.
In my case, it was an easy fix as removing the @ControllerAdvice
was enough but if you need @ControllerAdvice
, you might move the annotation to a class that is never used as a superclass.
As others have said 403 means that user is logged in but doesn't have the right permission to view the resource; I would check the following:
@Secured( {"ROLE_myAuthority"} )
new SimpleGrantedAuthority("ROLE_myAuthority");
Filter is been injected correctly
Authentication auth = new UsernamePasswordAuthenticationToken(username, authentication.getCredentials(), authorities);
Collection<? extends GrantedAuthority> auths = auth.getAuthorities();`
Iterator authsIterator = auths.iterator();
while (authsIterator.hasNext()) {
SimpleGrantedAuthority sga = (SimpleGrantedAuthority) authsIterator.next();
sga.getAuthority();
// ...
}