I have a reactjs project (running on port 3000), a JAVA API REST with Spring (running on 8080) and I have to configure it to work with an OpenID server.
I'm able to login to the OpenId from the front-end project (using Implicit Flow), but if I try to access the API, this throws me a 302 and tries me to redirect to the login page of the Auth server.
I have installed pac4 in the API.
How Can I send something to the API and how can I configure the API to validate this token? Because now, the API is answering a 302 to the login page of the OpenId.
The idea of my question is to know if I can do the following thing:
1- Login to the OpenId from the Node server.
2- Send the id_token to the API Rest
3- The API REST validates this token (I think against OpenId Server)
4- If the token is valid, return the petition.
Thanks!
Okay, I saw a lot of people with the same problem or doubt so I'll post my solution.
I used for the front-end project an openId javascript client account. You need to ask for "token id_token". This means it will retrieve the access_token in the callback.
With this access_token, you can hit the API. I used HeaderClient (pac4j library), and I send the access_token in the header as "Authorization": "Bearer ...".
In the API I created an interceptor and added the following validation:
final HeaderClient headerClient = new HeaderClient("Authorization", "Bearer " , (credentials, ctx) -> {
final String token = ((TokenCredentials) credentials).getToken();
JWSAlgorithm jwsAlg = JWSAlgorithm.RS256;
try {
URL jwkSetURL = new URL(authority + jwks);
try {
if (CommonHelper.isNotBlank(token)) {
// Set up a JWT processor to parse the tokens and then check their signature
// and validity time window (bounded by the "iat", "nbf" and "exp" claims)
ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor();
// The public RSA keys to validate the signatures will be sourced from the
// OAuth 2.0 server's JWK set, published at a well-known URL. The RemoteJWKSet
// object caches the retrieved keys to speed up subsequent look-ups and can
// also gracefully handle key-rollover
JWKSource keySource = new RemoteJWKSet(jwkSetURL , new DefaultResourceRetriever() );
// Configure the JWT processor with a key selector to feed matching public
// RSA keys sourced from the JWK set URL
JWSKeySelector keySelector = new JWSVerificationKeySelector(jwsAlg, keySource);
jwtProcessor.setJWSKeySelector(keySelector);
// Process the token
JWTClaimsSet claimsSet = jwtProcessor.process(token, null);
// Print out the token claims set
if (claimsSet != null) {
CommonProfile profile = new CommonProfile();
profile.setId(token);
// save in the credentials to be passed to the default AuthenticatorProfileCreator
credentials.setUserProfile(profile);
}
}
} catch (BadJOSEException e) {
System.out.println("Invalid Authorization token");
} catch (JOSEException e) {
System.out.println("Error on Authorization token");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
});