JWT身份验证无需在每个请求上获取用户详细信息

时间:2018-05-28 19:12:55

标签: spring spring-security jwt

我正在Spring Security中实现JWT身份验证。 我有预定义的角色,例如。普通用户,管理员等。

我有跟随令牌的有效负载:

Sub DeleteSheets1()
    Dim xWs As Worksheet, s As String, i As Long
    Dim skp As Boolean
    arr = Array("Sheet1", "Sheet2", "Sheet3")

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    n = ActiveWorkbook.Worksheets.Count
    For i = n To 1 Step -1
        s = Sheets(i).Name
        skp = False
        For Each a In arr
            If s = a Then skp = True
        Next a
        If Not skp Then Sheets(i).Delete
    Next

    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
End Sub

到目前为止,我看到的大多数实现都是基于id / username / email从数据库中检索用户详细信息,然后使用此数据创建身份验证(例如,通过验证UsernamePasswordAuthenticationToken)。 对我而言,它实际上是一种可取的方式,因为我总是拥有最新的特权和限制(例如,用户是否被禁止),与利益相比,时间开销并不大。

我只是好奇我怎样才能基于传入请求中包含的角色(在其授权标头令牌中)实现Spring Security的授权。我希望能够在适当路由请求后访问控制器中的用户标识符。仅基于检查到期时间和角色有效性的令牌验证是否足够?

1 个答案:

答案 0 :(得分:1)

由于有关用户角色的信息是您的令牌的一部分(在scopes声明中),因此可以单独基于令牌创建身份验证对象,而无需进一步访问数据库。

在以下示例中,createAuthentication()方法将令牌转换为Spring Security Authentication对象。

public class JWTFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
        throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String jwt = // resolveToken(httpServletRequest);

        this.createAuthentication(jwt).ifPresent(authentication -> {
            SecurityContextHolder.getContext().setAuthentication(authentication);
        });

        filterChain.doFilter(servletRequest, servletResponse);
    }


    public Optional<Authentication> createAuthentication(String token) {

        Jws<Claims> jwsClaims = validateToken(token);
        if (jwsClaims == null) {
            return Optional.empty();
        }

        Claims claims = jwsClaims.getBody();

        String scopesString = claims.get("scopes").toString();
        String[] authStrings = scopesString.split(",");

        Collection<? extends GrantedAuthority> authorities =
            Arrays.stream(authStrings)
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());

        String subject = claims.getSubject();
        org.springframework.security.core.userdetails.User principal = new User(subject, "", authorities);

        return Optional.of(new UsernamePasswordAuthenticationToken(principal, token, authorities));
    }

    private Jws<Claims> validateToken(String authToken) {
        try {
            Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken);
            return claims;
        } catch ...
    }

}