I'm trying to validate (and read roles from) a JWT Token. Sadly I can't use any adapter or auto configuration due to my overall application architecture.
It's no problem to decode the token like any other JWT Token, but I wonder if there is a library from Keycloak to archive this goal. (For example Just Parse the token to something like a KeycloakJWTToken and verify it by grabbing the secret from Keycloak Server or so)
Any easy-to-use client or so?
I'm using the Jose4J library:
https://bitbucket.org/b_c/jose4j/wiki/Home
Reading the claims inside a JWT token is straightforward:
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
public void parseJWT(String token) throws Exception {
JwtConsumer consumer = new JwtConsumerBuilder()
.setSkipAllValidators()
.setDisableRequireSignature()
.setSkipSignatureVerification()
.build();
JwtClaims claims = consumer.processToClaims(token);
System.out.println("* Parsed token: "+ claims.getRawJson() );
System.out.println("* Expiration date: " + new Date(claims.getExpirationTime().getValueInMillis()) );
}
More examples are available on GitHub:
https://github.com/pvliesdonk/jose4j/blob/master/src/test/java/org/jose4j/examples/ExamplesTest.java
Last remark: you do not need a key nor a secret to parse the JWT, but if needed, you can use the server (public) key to verify the token was signed by the keycloak server you are trusting.
The JWT website is listing all libraries for Token Signing/Verification:
https://jwt.io/#libraries-io
Keycloak access tokens are indeed JWT tokens. So, you can make full use of existing JWT libraries, including for validation as stated in the Keycloak official documentation:
If you need to manually validate access tokens issued by Keycloak you can invoke the Introspection Endpoint. The downside to this approach is that you have to make a network invocation to the Keycloak server. This can be slow and possibily overload the server if you have too many validation requests going on at the same time. Keycloak issued access tokens are JSON Web Tokens (JWT) digitally signed and encoded using JSON Web Signature (JWS). Because they are encoded in this way, this allows you to locally validate access tokens using the public key of the issuing realm. You can either hard code the realm’s public key in your validation code, or lookup and cache the public key using the certificate endpoint with the Key ID (KID) embedded within the JWS. Depending what language you code in, there are a multitude of third party libraries out there that can help you with JWS validation.
Besides, in Java EE, using the Keycloak Java adapter, the roles are typically mapped on the user Principal and i.e. allows isUserInRole(). That's one of the goals.
Also it is possible to cast the Principal from the SecurityContext as a KeycloakPrincipal, then obtain in turn a KeycloakSecurityContext from it. Using the KeycloakSecurityContext you have access to both ID and Access tokens (when applicable) and can read their properties, attributes and claims.
Note that it is also good practice, and simply useful, to use the Keycloak UI to "evaluate" your tokens. For instance, you can see the generated token in the Client Scopes tab (under Evaluate), as well as evaluate your policies and permissions in the Authorization tab of your Client(s) (under Evaluate).
Cf. https://www.keycloak.org/docs/latest/server_admin/#_client_scopes_evaluate
That's probably the best way to debug and test, while setting up your Client(s).
If you select a user in the Evaluate screen, the following example data is generated:
Generated Access Token (...)
Generated ID Token (...)
Generated User Info (...)
All examples are generated for the particular user and issued for the particular client, with the specified value of scope parameter. The examples include all of the claims and role mappings used.
Source: https://www.keycloak.org/docs/latest/server_admin/#generating-example-tokens-and-user-info
Related
Is there a way of using Keycloak only to Authenticate user, but with own mapping to roles with Spring?
I would like to authenticate API Gateway in keycloak first, but then provide internal JWT Token with authorized roles inside my microservice world.
In this article, I do map Spring authorities from roles that Keycloak sets in JWTs. Is that what you are looking for?
If what you want is having a hand on access token claims, two cases:
the claim is already in the token but with a different value than what you expect (missing roles, outdated email, ...). Then, it is very likely that Keycloak admin API exposes what you need to update users data. Check that a "confidential" client with required roles is declared with client-credentials flow enabled (or declare a new one) and have relevent resource-server call admin API for updates (with WebClient, RestTemplate, #FeignClient or whatever is capable of using client-credentials flow).
the claim does not exist yet. Then, define a new Keycloak "mapper" to add a private claim. Here is a sample. You can have a look at security module to figure out how this new private claim is parsed (by ProxiesClaimSet) into an Authentication custom implementation.
In any case, the authorization-server (Keycloak) is the only place to define claims, issue JWT and sign it. JWT validation by JWT decoder on resource-server involves much more than just checking expiration date: issuer, issued-at, token integrity (server signs the payload with a private key and exposes a public one to ensure the token content was not modified), and more are verified too.
You want to make access control inside resource-servers? Great! Ensure that authorization header with Bearer access-token is forwarded by the gateway from client(s) to resource-server(s) and configure your resource-server(s) as described in the article above.
P.S.
In the article you'll also find a way to test security rules (both unit and integration) with mocked authentication. This is what, in my opnion, makes resource-server(s) a better place to implement access-control: security rules are of primary business importance and fine grained unit-testing is essential.
Other note, if you go for additional private claim(s) with Keycloak mapper(s), pay attention to pom.xml file, java/main/resources and implemented interfaces of ProxiesMapper into proxies-keycloak-mapper module.
Last, you should also follow the first 3 of those tutorials (for real: write the code and run the tests), it will take you less than an hour and will save you many more hours struggling with your resource-server(s) security implementation.
I'm learning about access tokens and refresh tokens. I understand...
An access token is an artifact that proves the user has been authorized to access a resource and allows a client application to perform specific actions on behalf of the user.
A refresh token is an artifact that lets a client application get new access tokens without having to ask the user to log in again.
I don't understand the following paragraph from this JWT book:
The key aspect of the separation between access and refresh tokens lies in the possibility of making access tokens easy to validate. An access token that carries a signature (such as a signed JWT) may be validated by the resource server on its own. There is no need to contact the authorization server for this purpose. Refresh tokens, on the other hand, require access to the authorization server.
The text is referring to the following image:
What exactly does "validate" mean here? How can the resource server validate the access token on its own? If the authorization server generates the access token, which it does in this case, isn't the authorization server required to validate the access token?
The only thing I can think of is that the resource server has a copy of the key used to sign the access token (see here). If so, doesn't that render the authorization server redundant?
JSON Web Tokens can be validated because, as you guess correctly, the resource server will have beforehand the public key of the private key that was used to sign that token. It means, that if someone in the middle tried to tamper the JWT, the validation will fail and the JWT should not be processed.
Also, the JWT contains fields as the expiration time that can be checked by the resource to understand if the token is still valid or not.
When you authenticate with an OIDC provider you get back an id token and if you specified scopes for an API you get back an access token so that client applications can make requests to protected resources on the end user's behalf. Typically the access token is also a JWT.
But what is to stop someone from spoofing one of these access tokens, and creating one and passing it to an API? I understand there are safeguards to prevent modification because the signature will be different than what any validation logic is expecting, but what if a malicious user created a brand new one manually? Especially because these tokens can be validated 'in place' by any API that requires an access token (not all API's use the introspection endpoint... especially with a JWT). I do understand there is metadata around the signing keys for JWT's from OpenID Connect providers and that it is available in the OIDC discovery document. For example, here is Google's JWK metadata. Given that you have signing information publicly available, and JWT access token's can be validated without any requests to the OIDC provider, how are JWT's secure? What is preventing a person from creating one and passing it as a bearer token to an API that requires an access token?
But what is to stop someone from spoofing one of these access tokens, and creating one and passing it to an API?
Spoofing and reconstruction of signature is nearly impossible without the private key (assuming you are using asymmetric signing algorithm like RS256) that used for signing the original JWT.
The JWK information available via OIDC discovery document only contains the public key.
Also Use HTTPS for authorization / token exchange to avoid token sniffing.
JWT OAuth2 Token is prefetched from Spring Auth Server and stored in Redis Storage.
I don't want to request access token in OAuth2RestTemplate and I want to use my JWT Token for requests.
Can I do it with OAuth2RestTemplate or I should use usual RestTemplate?
The documentation for spring-security-oauth is useful here, basically the two sections: JWT Tokens and Accessing Protected Resources:
JWT Tokens
To use JWT tokens you need a JwtTokenStore in your Authorization
Server. The Resource Server also needs to be able to decode the tokens
so the JwtTokenStore has a dependency on a JwtAccessTokenConverter,
and the same implementation is needed by both the Authorization Server
and the Resource Server. The tokens are signed by default, and the
Resource Server also has to be able to verify the signature, so it
either needs the same symmetric (signing) key as the Authorization
Server (shared secret, or symmetric key), or it needs the public key
(verifier key) that matches the private key (signing key) in the
Authorization Server (public-private or asymmetric key). The public
key (if available) is exposed by the Authorization Server on the
/oauth/token_key endpoint, which is secure by default with access rule
"denyAll()". You can open it up by injecting a standard SpEL
expression into the AuthorizationServerSecurityConfigurer (e.g.
"permitAll()" is probably adequate since it is a public key).
To use the JwtTokenStore you need "spring-security-jwt" on your
classpath (you can find it in the same github repository as Spring
OAuth but with a different release cycle).
Accessing Protected Resources
Once you've supplied all the configuration for the resources, you can
now access those resources. The suggested method for accessing those
resources is by using the RestTemplate introduced in Spring 3. OAuth
for Spring Security has provided an extension of RestTemplate that
only needs to be supplied an instance of
OAuth2ProtectedResourceDetails.
This basically means to me that you'll use the same spring-security-jwt JwtAccessTokenConverter class in both the authorization server and the resource server and that the token services in each need to be setup with the JwtTokenStore(). The extension to the RestTemplate class they're referring to is the OAuth2RestTemplate from spring-security-oauth2. You'd use it in your resource server with it's JWT smarts being provided by an equivalent token recognizer.
Because the spring-security-oauth2 code is already set up to handle JWT tokens, you just need to provide a few key pieces and let the framework do the heavy lifting of inspecting the token and putting the security into scope for each protected resource.
As it would happen, someone's posted a nice example of this which goes into detail: baeldung spring-security-oauth-jwt example and here: github project of the same including how one could provide a more customized JWT (claims/payload).
Okay, i'm developing an Angular 2 app. I've added auth0 authentication, but to me it handles sessions very insecurely. The jwt token is not encrypted and saved inside localStorage. The claims are visible for anyone, they can easily be decoded and revealed. Not to mention, Web Storage itself isn't a secure place.
I'm opting for JWTs because later i want to transform this web app to desktop app with electron and so i cannot use cookie-sessions. My users will have additional information such as roles, which i don't want to look up in db on every request, that's why i would like to store them in jwt. It makes sense to encrypt the data, but auth0 doesn't seem to provide that function.
If claims like roles are stored in localStorage unprotected, what's stopping me to go to firefox console and change the token, e.g. make myself an admin?
If claims like roles are stored in localStorage unprotected, what's stopping me to go to firefox console and change the token, e.g. make myself an admin?
Because JWT is signed, so any alteration to the content or the signature will be detected during validation
The digital signature, the third part of a JWT token like this hhhhhh.ppppppp.ssssss is created using server private key, and is the way you can verify the identity of the issuer of the token and also that it has not been altered
If you want to hide the payload, the JWT specification allows use encryption (see Json Web Encryption-JWE at RFC). If auth0 does not support it, you have a lot of libraries listed in jwt.io
JWT token has two parts: explicit (codet by base64 algorithm) - with payload data like for example exp time or user Id and role etc. and implicit - hash key which guarantee with extremely high probability that any part of explicit data was not change after token was created (by server using it's private key). So in Local/Session storage you can store this explicit part. The full token should be store in httpOnly cookies - then you will be protected against XSS attack (where hacker want to stole you token).
So you can read and change jwt token payload from firefox, but you will be unable to generate implicit hash - and server will reject your token.
So the answer to title question is: because Auth0 id_token is JWT token :)