Projekt

Obecné

Profil

Stáhnout (3.69 KB) Statistiky
| Větev: | Tag: | Revize:
1
package cz.zcu.kiv.backendapi.security.jwt;
2

    
3
import com.auth0.jwt.JWT;
4
import com.auth0.jwt.JWTVerifier;
5
import com.auth0.jwt.algorithms.Algorithm;
6
import com.auth0.jwt.interfaces.DecodedJWT;
7
import com.google.common.base.Strings;
8
import lombok.RequiredArgsConstructor;
9
import lombok.extern.slf4j.Slf4j;
10
import org.springframework.http.HttpHeaders;
11
import org.springframework.http.HttpMethod;
12
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
13
import org.springframework.security.core.authority.SimpleGrantedAuthority;
14
import org.springframework.security.core.context.SecurityContextHolder;
15
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
16
import org.springframework.web.filter.OncePerRequestFilter;
17

    
18
import javax.servlet.FilterChain;
19
import javax.servlet.ServletException;
20
import javax.servlet.http.HttpServletRequest;
21
import javax.servlet.http.HttpServletResponse;
22
import java.io.IOException;
23
import java.util.Collection;
24
import java.util.List;
25
import java.util.Map;
26
import java.util.stream.Collectors;
27

    
28

    
29
/**
30
 * Class that verifies JWT per request
31
 */
32
@Slf4j
33
@RequiredArgsConstructor
34
public class JwtTokenVerifier extends OncePerRequestFilter {
35

    
36
    /**
37
     * JWT utils
38
     */
39
    private final JwtUtils jwtUtils;
40

    
41
    /**
42
     * Map of permitted endpoints with HTTP method (user does not need to be authenticated perform the request)
43
     */
44
    private final Map<String, HttpMethod> skipFilterEndpoints;
45

    
46
    /**
47
     * Filters request - checks for JWT token and validates it
48
     *
49
     * @param request     request
50
     * @param response    response
51
     * @param filterChain filter chain
52
     * @throws ServletException servlet exception
53
     * @throws IOException      I/O exception
54
     */
55
    @Override
56
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
57
        String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
58
        if (Strings.isNullOrEmpty(authorizationHeader) || !authorizationHeader.startsWith(jwtUtils.getTokenPrefix())) {
59
            filterChain.doFilter(request, response);
60
            return;
61
        }
62

    
63
        try {
64
            String token = authorizationHeader.substring(jwtUtils.getTokenPrefix().length());
65
            Algorithm algorithm = jwtUtils.getAlgorithm();
66
            JWTVerifier verifier = JWT.require(algorithm).build();
67
            DecodedJWT decodedJWT = verifier.verify(token);
68
            String username = decodedJWT.getSubject();
69
            List<String> authorities = decodedJWT.getClaim(jwtUtils.getClaimAuthoritiesName()).asList(String.class);
70
            Collection<SimpleGrantedAuthority> simpleGrantedAuthorities = authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet());
71

    
72
            UsernamePasswordAuthenticationToken authenticationToken =
73
                    new UsernamePasswordAuthenticationToken(username, null, simpleGrantedAuthorities);
74
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
75
        } catch (Exception e) {
76
            log.error("Error logging in: " + e.getMessage());
77
            jwtUtils.writeErrorToResponse(response, e);
78
        }
79
        filterChain.doFilter(request, response);
80
    }
81

    
82
    /**
83
     * Tells filter whether given request should not be scanned for JWT
84
     *
85
     * @param request request
86
     * @return true if given request should not be scanned for JWT, false otherwise
87
     */
88
    @Override
89
    protected boolean shouldNotFilter(HttpServletRequest request) {
90
        return skipFilterEndpoints.entrySet().stream().anyMatch(e -> new AntPathRequestMatcher(e.getKey(), e.getValue().toString()).matches(request));
91
    }
92
}
(1-1/4)