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.