Spring Security - adnotacja @PermitAll

0

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

0

@Shalom:
https://github.com/Burdzi0/Pizzeria-Backend
Branch development
Korzystam z definicji dostępu w ten sposób:

.authorizeRequests().antMatchers("/v1/login", "/v1/register", "/h2-console/**", "/v1/health-check").permitAll()

a chciałbym mieć to zdecentralizowane (per endpoint) korzystając z adnotacji @PermitAll. Użycie jej nie przynosi efektu

0

https://github.com/Burdzi0/Pizzeria-Backend/tree/mail-sending-on-register

Kontroller:

@RestController
@RequestMapping(value = "/v1/pizza")
public class PizzaController {

    private PizzaService pizzaService;

    public PizzaController(PizzaService pizzaService) {
        this.pizzaService = pizzaService;
    }

    @PermitAll
    @GetMapping(value = "/{id}")
    public PizzaDto getPizza(@PathVariable int id) {
        return pizzaService.getPizza(id);
    }

    @PermitAll
    @GetMapping
    public List<PizzaDto> getAll() {
        return pizzaService.getAll();
    }
}

Mimo @PermitAll zwraca 403.

Config - whitelist zostało na razie wywalone, bo nie chcę z niej korzystać, chcę ją zastąpić adnotacją @PermitAll:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {

    private static final String[] WHITELIST = {
            "/v1/login",
            "/v1/register",
            "/h2-console/**",
            "/v1/ingredient",
            "/v1/mail/**",
            "/v1/reset"
    };

    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().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();
    }
}

Projekt się buduje i startuje jak coś.

1 użytkowników online, w tym zalogowanych: 0, gości: 1