简体   繁体   中英

JWT.decode(token) Fails Silently

I have written a JAX-RS ContainerRequestFilter to implement JWT-based access controls on a set of REST services but the application fails to decode the JWT id_token.

My web client successfully executes the Azure AD login process and gets back a JWT id_token and then requests and receives a JWT access_token.

On my server I am using the https://github.com/auth0/java-jwt library to decode the id_token but the call to

    DecodedJWT jwtIdent = JWT.decode(identificationHeader); 

fails without any exceptions.

I have a simple Java program that executes the same JWT.decode(id_token) call on a String version of the same id_token from the web server and that call to works fine.

The http request object from the client is:

    var request = {
        method: 'POST',
        url: url,
        headers: {
            'Content-Type': 'application/json;charset=utf-8',
            'Authorization': "Bearer " + $scope.tokens.accessToken,
            'Identification': $scope.tokens.idToken
        }
    };

The top of the ContainerRequestFilter is as follows:

    public void filter(ContainerRequestContext requestContext) throws IOException {

logger.info("public void filter(ContainerRequestContext requestContext) - Begin");

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

    try {

        Method method = resourceInfo.getResourceMethod();
        logger.info("REST Method Called: " + method.getName());

        // Is access allowed for all?
        if( ! method.isAnnotationPresent(PermitAll.class)) {                

            // Is access denied for all?
            if(method.isAnnotationPresent(DenyAll.class)) {
                logger.info("Method: " + method.getName() + " has protections " + DenyAll.class.getName());
                logger.info("ACCESS_FORBIDDEN");
                requestContext.abortWith(ACCESS_FORBIDDEN);
                return;
            }                

            if (authorizationHeader == null) {
                logger.info(HttpHeaders.AUTHORIZATION + " = <null>");
                requestContext.abortWith(BAD_REQUEST);
            }                

            if (identificationHeader == null) {
                logger.info(IDENTIFICATION_PROPERTY +" = <null>");
                requestContext.abortWith(BAD_REQUEST);
            }

            logger.info("IdentificationHeader: \n   <" + identificationHeader + ">\n\n");

            DecodedJWT jwtIdent = JWT.decode(identificationHeader);

The call to JWT.decode(...) happens but never returns and the client gets back a "500" error code.

I can System.out.println(...) the tokens when they arrive on the server and they look fine. I can paste them into my other Java application and they decode fine and they decode fine at https://jwt.io/ .

Is there something else I need to do to protect the integrity of the UTF-8 data as it transits from my client to my server?

Upon further investigations I figured out that the authorizationHeader and the identificationHeader values were not actually Base64 encoded as I expected them to be.

I removed the call to JWT.decode() and then split the content of the identificationHeader on a period ('.') which return the three JWT components. I was then able to simply parse one of the strings as JSON and retrieve the necessary JWT claims.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM