2
respostas

Swagger retornando 403 em uri livre

Após adicionar o campo do token, uma url que não necessita de token fica dando erro 403, via postman funciona corretamente.

@Configuration
public class SwaggerConfigurations {

    @Bean
    public Docket forumApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.dnia.eaascloud"))
                .paths(PathSelectors.ant("/**"))
                .build()
                .ignoredParameterTypes(User.class)        
                .globalOperationParameters(
                        Arrays.asList(new ParameterBuilder().name("Authorization").description("Header for token JWT")
                                .modelRef(new ModelRef("string")).parameterType("header").required(false).build()));
    }

}

{ "timestamp": "2022-01-31T19:36:10.201+00:00", "status": 403, "error": "Forbidden", "message": "Access Denied", "path": "/client/create" }

cache-control: no-cache, no-store, max-age=0, must-revalidate connection: keep-alive content-type: application/json date: Mon, 31 Jan 2022 19:36:10 GMT expires: 0 keep-alive: timeout=60 pragma: no-cache transfer-encoding: chunked x-content-type-options: nosniff x-frame-options: DENY x-xss-protection: 1; mode=block

2022-01-31 16:43:46.695 WARN 15420 --- [nio-9090-exec-4] c.d.e.security.AutheticationTokenFilter : Token data recovery issues {}

java.lang.IllegalArgumentException: JWT String argument cannot be null or empty. at io.jsonwebtoken.lang.Assert.hasText(Assert.java:135) ~[jjwt-0.9.1.jar:0.9.1] at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:479) ~[jjwt-0.9.1.jar:0.9.1] at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:541) ~[jjwt-0.9.1.jar:0.9.1] at com.dnia.eaascloud.security.TokenService.getIdUser(TokenService.java:48) ~[classes/:na] at com.dnia.eaascloud.security.AutheticationTokenFilter.doFilterInternal(AutheticationTokenFilter.java:69) ~[classes/:na] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.14.jar:5.3.14] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.6.1.jar:5.6.1]

2022-01-31 16:43:46.696 WARN 15420 --- [nio-9090-exec-4] c.d.e.security.AutheticationTokenFilter : Token validation was required from 0:0:0:0:0:0:0:1 for id -1. 2022-01-31 16:43:46.696 DEBUG 15420 --- [onPool-worker-3] c.d.e.monitoring.services.EventService : Started async block at 2022-01-31T19:43:46.696851500Z Hibernate: insert into event (created_at, message, origin, response, submission_end, submission_start, type, updated_at, user_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) 2022-01-31 16:43:46.797 DEBUG 15420 --- [onPool-worker-3] c.d.e.monitoring.services.EventService : Register changes to processed files collection 2022-01-31 16:43:46.797 DEBUG 15420 --- [onPool-worker-3] c.d.e.monitoring.services.EventService : Ended async block at 2022-01-31T19:43:46.797963Z

2 respostas

Oi Bruno,

Posta aqui a sua classe AutheticationTokenFilter.

Oi Professor Rodrigo.

Obrigado pela atenção!

public class AutheticationTokenFilter extends OncePerRequestFilter {

    private TokenService tokenService;
    private UserRepository userRepository;
    private EventService eventService;

    public AutheticationTokenFilter(TokenService tokenService,
            UserRepository userRepository, EventService eventService) {

        this.tokenService = tokenService;
        this.userRepository = userRepository;
        this.eventService = eventService;
    }

    @Override
    public void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        String token = getToken(request);

        if (tokenService.isValid(token)) {
            authenticationUser(token);
        } else {
            // Collect necessary data only if invalid so, everything is here

            // Getting remote ip
            String remoteAddr = "";
            if (request != null) {
                //From Proxy
                remoteAddr = request.getHeader("X-FORWARDED-FOR");
                if (remoteAddr == null || remoteAddr.isBlank()) {
                    remoteAddr = request.getRemoteAddr();
                }
            }

            // Register attempt fail
            // Try to write event in database handle with exceptions
            Long userId = -1L;
            // If token service can not extract information, 
            // userId keep original value
            try {
                userId = tokenService.getIdUser(token);
            } catch (ExpiredJwtException ex) {
                // If expired we will recover user id from subject
                userId = Long.parseLong(ex.getClaims().getSubject());
            } catch (UnsupportedJwtException | MalformedJwtException
                    | SignatureException | IllegalArgumentException ex) {
                // another exceptions log in console
                log.warn("Token data recovery issues {}", ex);
            }

            // Write event to database
            try {
                eventService.treatEventAsTokenValidation(userId, remoteAddr,
                        HttpStatus.FORBIDDEN);
            } catch (InterruptedException | ExecutionException ex) {
                log.warn("Recording event issues {}", ex);
            }
            log.warn("Token validation was required from {} for id {}.",
                    remoteAddr, userId);
        }

        chain.doFilter(request, response);
    }

    private void authenticationUser(String token) {

        Long idUsuario = tokenService.getIdUser(token);
        User user = userRepository.findById(idUsuario).get();

        UsernamePasswordAuthenticationToken authentication
                = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());

        if (user.getActive())
        {
        SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        else
        {
            authentication.setAuthenticated(false);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
    }

    private String getToken(HttpServletRequest request) {

        String token = request.getHeader("Authorization");

        if (token == null || token.isBlank() || !token.startsWith("Bearer ")) {
            return null;
        }

        return token.substring(7, token.length());
    }

}