Аутентификация JWT без извлечения пользовательских данных по каждому запросу - PullRequest
0 голосов
/ 28 мая 2018

Я внедряю аутентификацию JWT в Spring Security.У меня есть предопределенные роли, например.обычный пользователь, администратор и т. д.

У меня есть следующая полезная нагрузка токена:

{
  "sub": "nick",
  "iat": "<some_date>",
  "exp": "<some_date+1h>",
  "scopes": [
    "ROLE_USER",
    "ROLE_ADMIN"
  ]
}

Большинство реализаций, которые я видел до сих пор, извлекают данные пользователя из базы данных на основе идентификатора / имени пользователя / электронной почты, а затемиспользуйте эти данные для создания аутентификации (например, путем аутентификации UsernamePasswordAuthenticationToken).Для меня это на самом деле предпочтительный способ, потому что у меня всегда есть последние привилегии и ограничения (например, был ли пользователь забанен), а временные затраты не так велики по сравнению с преимуществами.

Мне просто любопытнокак я могу реализовать авторизацию в Spring Security только на основе ролей, включенных во входящий запрос (в его токене заголовка авторизации).Я хочу просто иметь возможность доступа к идентификатору пользователя в контроллере после того, как запрос направлен соответствующим образом.Достаточно ли будет проверки токена, основанной только на проверке срока действия и валидности ролей?

1 Ответ

0 голосов
/ 01 июня 2018

Поскольку информация о ролях пользователя является частью вашего токена (в утверждении 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 ...
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...