Аутентификация на основе ролей на конечных точках Restful в Java - PullRequest
1 голос
/ 07 апреля 2019

Я пытаюсь реализовать какую-то проверку подлинности на основе ролей. Я использую токены JWT. Я смотрел на руководства, но все они упоминают использование «Spring boot». Как настроить аутентификацию на основе ролей на моей конечной точке отдыха в Java? Желательно через какой-то фильтр.

Я ищу способ просто добавить: @Role(Role.ADMIN) перед конечной точкой.

У меня уже установлены следующие классы:

  • Enum Роль:

    public enum Role {
        User,
        Admin
    }
    
  • Простой токен JWT:

    {
     "sub": "users/TzMUocMF4p",
     "exp": 1554646441,
     "username": "username@gmail.com",
     "ID": 6,
     "Role": "Admin",
     "iat": 1554641041
    }
    
  • Простая конечная точка CRUD

    @Path("User")
    public class UserResource {
    
       @EJB
       private UserDAO userappDAO;
    
    
       @GET
       @JWTTokenNeeded
       @Produces("application/json")
       public List<Userapp> all() {
           return userappDAO.getAll();
       }
    }
    
  • Класс проверки JWT (@JWTTokenNeeded) ниже:

    @javax.ws.rs.NameBinding
    @Retention(RUNTIME)
    @Target({TYPE, METHOD})
    public @interface JWTTokenNeeded {
    }
    

    Фактический фильтр:

    @Provider
    @JWTTokenNeeded
    @Priority(Priorities.AUTHENTICATION)
    public class JWTTokenNeededFilter implements ContainerRequestFilter {
    
    
        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
    
    // Get the HTTP Authorization header from the request
    String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
    
    try {
        // Extract the token from the HTTP Authorization header
        String token = authorizationHeader.substring("Bearer".length()).trim();
        // Validate the token
        Jwts.parser().setSigningKey("MYSECRET".getBytes("UTF-8")).parseClaimsJws(token);
    
    }
    catch (Exception e) {
        requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
    }
    }
    }
    

Если пользователь не авторизован, я хотел бы выйти с: requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());

Если пользователь авторизован, конечная точка должна сделать это.

1 Ответ

2 голосов
/ 08 апреля 2019

Я нашел рабочее решение.Он включает добавление нескольких строк в интерфейс @JWTTokenNeeded и класс JWTTokenNeededFilter.

Я получил следующий код:

JWTTokenNeededFilter:

@Provider
@JWTTokenNeeded
@Priority(Priorities.AUTHENTICATION)
public class JWTTokenNeededFilter implements ContainerRequestFilter {
    @Context
    private ResourceInfo resourceInfo;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        // Get the HTTP Authorization header from the request
        String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

        try {
            // Extract the token from the HTTP Authorization header
            String token = authorizationHeader.substring("Bearer".length()).trim();
            // Validate the token
            Claims claims =  Jwts.parser().setSigningKey("MYSECRET".getBytes("UTF-8")).parseClaimsJws(token).getBody();

            Method method =resourceInfo.getResourceMethod();
            if( method != null){
                // Get allowed permission on method
                JWTTokenNeeded JWTContext = method.getAnnotation(JWTTokenNeeded.class);
                Role permission =  JWTContext.Permissions();

                if(permission != Role.NoRights ) {
                    // Get Role from jwt
                    String roles = claims.get("Role", String.class);
                    Role roleUser = Role.valueOf(roles);

                    // if role allowed != role jwt -> UNAUTHORIZED
                    if (!permission.equals(roleUser)) {
                        throw new Exception("no roles");
                    }

                }
            }

        }
        catch (Exception e) {
            e.printStackTrace();
            requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
        }
    }
}

Интерфейс @JWTTokenNeeded:

@javax.ws.rs.NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface JWTTokenNeeded {
    Role Permissions() default Role.NoRights;
}

Разрешение роли для доступа к конечной точке так же просто, как добавление @JWTTokenNeeded(Permissions = Role.Admin)

Это пример:

@Path("User")
public class UserResource {
    @EJB
    private UserappDAO userDAO;


    @GET
    @JWTTokenNeeded(Permissions = Role.Admin)
    @Produces("application/json")
    public List<Userapp> all() {
        return userDAO.getAll();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...