I am getting Unauthorized error despite being logged in with User having the required roles. In SecurityConfig, I used antMatchers, which allow me to do permitAll() but authorize when I use hasAnyAuthority(). On using annotations in methods, @PreAuthorize/@Secured , I am getting unauthorized error. When I debugged and checked all the Granted Authorities (in UserDetails) it was showing all the required roles but still the method with pre/post auth do not get authorized.
Here is what I coded:
SecurityConfig
@Configuration
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig {
@Autowired
UserDetailsServiceImpl userDetailsService;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new ShaPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth ->
auth.antMatchers("/authorizedAccess/**").permitAll()
.antMatchers("/api/v1/**").permitAll()
.antMatchers("/access/**").permitAll()
.anyRequest().authenticated()
);
http.authenticationProvider(authenticationProvider());
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
Method:
@RestController
@RequestMapping(value = "/authorizedAccess")
public class AuthorizedAccessControl {
@Autowired
someService someService;
private static final Logger LOG = LogManager.getLogger(AuthorizedAccessController.class);
/**
*
* @return
*/
@Secured("hasAnyAuthority('ROLE_ADMIN')")
@GetMapping(value = "/environments", produces = MediaType.APPLICATION_JSON_VALUE)
public List<String> getAllEnvironments() {
LOG.debug(">>>Environments");
return someService.getEnvironments();
}
AuthTokenFilter
public class AuthTokenFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsServiceImpl userDetailsService;
private static final Logger LOG = LogManager.getLogger(AuthTokenFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
String username = jwtUtils.getUserNameFromJwtToken(jwt);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
LOG.info(userDetails.getAuthorities());
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
List<GrantedAuthority> authorities = new ArrayList<>(authentication.getAuthorities());
LOG.info(authorities);
}
} catch (Exception e) {
LOG.error("Cannot set user authentication: {}", e);
}
filterChain.doFilter(request, response);
}
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
return headerAuth.substring(7);
}
return null;
}
}
I tried putting checks on antMatcher and methods both. permitAll() works on antMatcher but neither permitAll() and hasAnyAuthority() work on both antMatcher or Method.