Как мне идиоматически проверять и обрабатывать пользовательские утверждения JWT?

#java #spring-boot #jwt #authorization #auth0

#java #весенняя загрузка #jwt #авторизация #auth0

Вопрос:

Я использую Auth0 для аутентификации и имею пользователей с различными ролями и разрешениями. Возвращаемые токены JWT не имеют разрешений, перечисленных в scope утверждении — они являются частью permissions утверждения. Образец полезной нагрузки выглядит следующим образом:

 {
  "iss":"...",
  "sub":"...",
  "scope":"openid profile email",
  "permissions":[
    "x:create",
    "x:read",
    "x:update",
    "x:delete"
  ]
}
  

Мне нужно убедиться, что токен JWT имеет правильный набор разрешений перед обработкой запроса. Мое текущее решение состоит из пользовательской аннотации, HasPermissions , которую я добавляю к соответствующим методам контроллера:

   @DeleteMapping("/{id}")
  @HasPermissions({"x:delete"})
  public ResponseEntity<Item> delete(@PathVariable("id") Long id) {
    service.delete(id);
    return ResponseEntity.noContent().build();
  }
  

Затем аннотация и соответствующие разрешения проверяются в пользовательском HandlerInterceptor :

 class PermissionsInterceptor extends HandlerInterceptorAdapter {
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if (handler instanceof HandlerMethod) {
      HandlerMethod method = (HandlerMethod) handler;
      HasPermissions perms = method.getMethodAnnotation(HasPermissions.class);
      if (perms != null) {
        String[] permissions = perms.value();
        if (!hasPermissions(token(), permissions)) {
          response.sendError(HttpServletResponse.SC_FORBIDDEN);
          return false;
        }
      }
    }
    return true;
  }

  JwtAuthenticationToken token() {
    SecurityContext context = SecurityContextHolder.getContext();
    if (context == null) {
      return null;
    }
    Authentication auth = context.getAuthentication();
    if (auth instanceof JwtAuthenticationToken amp;amp; auth.isAuthenticated()) {
      return (JwtAuthenticationToken) auth;
    }
    return null;
  }

  // other methods ommited.
}
  

hasPermissions Метод проверяет, присутствуют ли разрешения, перечисленные в аннотации permissions , в заявке на токен.

Вопрос: Является ли приведенное выше разумным решением или существует более идиоматичный / оптимальный / безопасный способ проверки и / или обработки пользовательских утверждений JWT?

Комментарии:

1. То, что вы пытаетесь, больше похоже на ABAC (управление доступом на основе атрибутов) И у него есть много полных решений. Проверьте это. По сути, ABAC — это обобщенный способ делать то, что вы делаете. Он предоставляет политику, правила в зависимости от того, какой тип объекта, какие поля, какое действие может быть выполнено пользователем, имеющим какую роль.

2. Глядя на вашу реализацию, похоже, что вы реализуете логику безопасности низкого уровня. Такая логика уже предусмотрена Spring Security. Чтобы извлечь полномочия, вы можете сделать что-то вроде этого: docs.spring.io/spring-security/site/docs/current/reference /…