Ignorar métodos no Interceptor Vraptor

Estou tentando implementar autenticação com JWT está dando certo, porém o primeiro método que é responsável por criar o token tem que ser ignorado pelo Interceptor.

Criei uma anotação Public:

    @Documented
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.TYPE})
    public @interface Public {
    }

E coloquei isso em meu Interceptor:

   @Accepts
    public boolean accepts(ControllerMethod method) {
        return !method.containsAnnotation(Public.class);
    }

Porém só funciona quando faço a requisição por GET Se eu tento por POST a anotação e o Accepts não funcionam.

Ex:

    @Public
    @Post
    @Path("/")
    @Consumes(value = "application/json", options = WithoutRoot.class)
    public void autenticar(Usuario usuario) {
        Usuario u = usuarioDAO.autenticar(usuario.getNome(), usuario.getSenha());
        if (u != null) {
            String token = JWTUtil.createToken(u.getId());
            result.use(Results.json()).from(token).serialize();
        } else {
            result.use(Results.status()).notAcceptable();
        }

    }

Como posso resolver esse problema?

Só uma dúvida…

Já que o recurso anotado com @Public não tem restrição nenhuma de acesso, porque você tá interceptando ele e depois fazendo um accept?

O ideial nao seria interceptar só métodos que teriam algum tipo de restrição … alguma anotação tipo @DevePossuirTokenValidoNoRequest por exemplo, e dali p/ frente realizar alguma validação p/ permitir ou não a continuidade do processo?

Att

Por isso que fiz o @Accepts. Pra não interceptar nada com essa anotação. Quando utilizo GET funciona, porém quando tento utilizar POST tenho esse erro: java.lang.IllegalStateException: token not set

Mas quando você nao quer interceptar nada … é soh “não interceptar” :smiley:

Como você está fazendo isso ?

Coloca a classe de interceptor ai …

Ou então da uma olhada lá no projeto que te passei… faço esse tipo de operção lá tbm.

https://github.com/guivirtuoso/app/blob/master/src/main/java/br/com/empresa/app/interceptors/PrecisaEstarLogadoInterceptor.java

Interceptador:

@Intercepts
@RequestScoped
public class SecurityInterceptor {

    private HttpServletRequest request;
    private Result result;

    public SecurityInterceptor() {
        this(null, null);
    }

    @Accepts
    public boolean accepts(ControllerMethod method) {
        return !method.containsAnnotation(Public.class);
    }

    
    @Inject
    public SecurityInterceptor(HttpServletRequest request, Result result) {
        this.request = request;
        this.result = result;
    }

    @AroundCall
    public void intercept(SimpleInterceptorStack stack) {
        System.out.println("Interceptando");
        String token = request.getHeader("authorization");

        Map<String, Object> claims;
        try {
            claims = JWTUtil.decode(token);

            Integer userId = (Integer) claims.get("user");
            if (userId != 1) {
                result.use(Results.http()).setStatusCode(401);
                result.use(Results.json()).from("This user does not exist", "msg").serialize();
            } else {
                result.use(Results.http()).addHeader("Authorization", token);

                stack.next();
            }
        } catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException | SignatureException
                | IOException | JWTVerifyException e) {
            e.printStackTrace();
            result.use(Results.http()).setStatusCode(401);
            result.use(Results.json()).from(e.getMessage(), "msg").serialize();
        }
    }

}

Será que ele tá fazendo alguma distinção entre “Authorization” e “authorization” ???

E outra… será que tem diferença entre Get ou Post quando se quer pegar os Headers da requisição?

Eu pesquisaria algo nessa linha…debugando e tal…

Beleza, vou debugar.

Acho que deu certo, coloquei a anotação que você passou: @AcceptsWithAnnotations e funcionou, kk tem alguma maneira de fazer uma negação nessa anotação? Exemplo: @AcceptsWithAnnotations(!Public.class) ?

Cara, na minha opnião (que provavelmente deve estar errada :sweat_smile: ) , quando você não quer interceptar algo, basta não anotar, ai todo o fluxo seguirá normalmente.

Nesse caso ai do Publico… tipo… tudo já é publico.

Você quer apenas validar os endpoints que tem restrição de consumo…

Por isso acho que você está vendo a coisa um pouco invertida.

Ou então você pode ir vendo as implementações do @AcceptsWithAnnotations e criar a anotação @AcceptsWithoutAnnotations

:wink:

1 curtida