对REST端点使用基于令牌的@Secured授权

时间:2018-09-08 10:09:05

标签: java spring spring-security

我一直在尝试为我的Spring应用程序执行基于令牌(JWT)的身份验证和授权。当然可以通过Spring Security。我已经能够通过过滤器执行身份验证部分。但是,我似乎无法基于HTTP请求上发送的JWT令牌来授权请求​​。请参阅下面的示例代码。

TestRest.java(RestController)

@RestController
public class TestRest {

    @GetMapping(value="/protected")
    @Secured("ROLE_USER")
    public @ResponseBody String protectedMethod () {
        logger.info("Entering Proceted Method! is {}" , SecurityContextHolder.getContext().getAuthentication().getAuthorities());
        return "I am Protected!";
    }
}

JwtAuthTokenFilter.java(令牌过滤器)

@Component
public class JwtAuthTokenFilter extends OncePerRequestFilter{
... some code ...

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        logger.info("Firing JWT Token Filter.");

        String authHeader = request.getHeader(this.prop.getHeader());
        String authToken = null;
        String username = null;
        Date expiry = null; 
        Collection<? extends GrantedAuthority> authorities = null;;
        //if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
        if (authHeader != null && authHeader.startsWith(bearer)) {
            authToken = authHeader.substring(bearer.length());

            try {
                logger.info("Token: {}",authToken);
                username = jwtUtil.getUsernameFromToken(authToken);
                authorities = AuthorityUtils.createAuthorityList(jwtUtil.getAudienceFromToken(authToken));
                logger.info("Username: {}", username);
                logger.info("Roles: {}", authorities);
                logger.info("Issue At: {}", jwtUtil.getIssuedAtDateFromToken(authToken));
                logger.info("Expiration: {}", jwtUtil.getExpirationDateFromToken(authToken));

            } catch (IllegalArgumentException e) {
                logger.error("Error Occurred {}", e);
            } catch (ExpiredJwtException e) {
                logger.warn("Token Expired! {}", e);
            }

            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                logger.info("authorizingi user!!!");

                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, null, authorities);
                auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                logger.info("{} is authorized", username);
                SecurityContextHolder.getContext().setAuthentication(auth);
            }

        }else {
            logger.info("No header, ignoring");
        }

        filterChain.doFilter(request, response);
        logger.info("Closing JWT TOken Filter.");
    }
... some code ...
}

以上过滤器大致基于我已阅读的有关认证JWT令牌的指南。归功于这家伙当前,我正在执行@Secured java配置以保护我所有的REST-API端点。由于需要在antMatchers中定义的可维护性部分,因此我不会在Web配置中设置用户角色。因此,我将在每个REST-API端点上实现@Secured。但是,我似乎无法使所有REST-API端点中的用户(使用JWT令牌)都得到授权。

如何设置授权,以便@Secured可以识别它?

0 个答案:

没有答案