Hejka!
Chcę w moim projekcie w springu używać do kontroli dostępu adnotacji @PermitAll
.
Co ciekawe adnotacja @PreAuthorize("hasRole()")
działa bez problemu.
Config:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {
private UserDetailsService customerUserDetailsService;
private Filter jwtRequestFilter;
public SecurityConfigurer(UserDetailsService customerUserDetailsService, Filter jwtRequestFilter) {
this.customerUserDetailsService = customerUserDetailsService;
this.jwtRequestFilter = jwtRequestFilter;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customerUserDetailsService);
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues())
.and()
.authorizeRequests().antMatchers("/v1/login", "/v1/register", "/h2-console/**", "/v1/health-check").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Filtr JWT (tak, wiem, jeszcze przed refactorem)
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
public static final String BEARER = "Bearer ";
private JwtUtil jwtUtil;
private UserDetailsService userDetailsService;
public JwtRequestFilter(JwtUtil jwtUtil, UserDetailsService userDetailsService) {
this.jwtUtil = jwtUtil;
this.userDetailsService = userDetailsService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String jwt = Optional.ofNullable(request.getHeader("Authorization"))
.filter(header -> header.startsWith(BEARER))
.map(header -> header.substring(7))
.orElse(null);
String username = null;
if (jwt != null) {
username = jwtUtil.extractUsername(jwt);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
Jakieś pomysły? Przeglądnąłem już chyba pół internetów