my question about new Spring-Security-Authorization-Server, i create auth-server and resource-server, and generating public and private keys in auth-server. I set jwkSetUri in resource-server, can't understand how resource-server checks token. Who understood how the verification principle works, how should I implement it correctly?
My purpose get correct implementation of new auth server and resource server.
I found the answer after reading the book how to work with asymmetric keys, we generate a token based on public and private keys in the auth-server, and we have an address for the public key /oauth2/jwks with which the resource-server checks whether this jwt is really generated by auth-server
Related
I want to secure a REST API via JWTs provided as Authorization Header in the requests. I am have a quarkus application and would like to use their official guide - https://quarkus.io/guides/security-jwt
The guide specifies:
mp.jwt.verify.publickey.location=publicKey.pem
mp.jwt.verify.issuer=https://example.com/issuer
So far so good, now we can check if JWTs are signed by a private key that corresponds to this public key. The problem I have is that I have different APIs and different OAuth integrations, let's say 3. So different API Endpoints expect different JWTs and hence also have different public keys. Is this even supported in mp?
Spring Security allows multiple WebSecurity with different #Order and integrating multiple oAuth Servers works there. How can this be done in Quarkus/MP JAX-RS?
Yes. But using a JSON Jwt Key Set:
mp.jwt.verify.publickey.location=my-pubkeys.json
The Jwt Ket Set allows to provide several public keys in row. You can also provide an URL instead.
Also, forget about mp.jwt.verify.issuer: the property expects a string representing a single issuer. This property is not mandatory, so if you really want to control the issuer you will have to control it by yourself in your request filter.
If you only have PEM files for your pubkeys, you can turn them into Jwt Key Set using PEM to JWT convertor like this one (online). Then you just have to serve the .json file.
I am trying out an example to add user attributes to the claim. I am following the example here. I am trying to access the claim in a filter and am unsuccessful.
I would want to understand how the protocol mappers work behind the scenes, namely how and in which order are those claims from that protocol added into the token.
In Keycloak, the function of the protocol mappers is to add additional claims to a JWT besides those that are added by default by Keyloack.
Different Protocol Mapper will have different options, but for most of them you can chose to add the claims that those mappers will produce into the:
ID Token;
Access Token;
UserInfo;
I would want to understand how the protocol mappers work behind the
scenes.
Roughly, what will happen is the following the JWT is basically an encoded JSON Object based on a specific standard, Keycloak creates that object with the Registered claims (e.g., Issuer, Subject and so on), and then it will apply the custom claims (i.e., protocol Mappers) into that temporary object by the Priority Order that you have defined for that given protocol Mapper.
The end result (i.e., the token) will be a JWT with the default claims, and with the claims added with the protocol mappers.
For a few reasons I cannot use refresh tokens on client, is it possible to implement RemoteTokenServices on ResourceServer so that it checks the token is not revoked on auth server, but get auth information like user details from JWT-token itself, not from authentication server, like default implementation does using uuid tokens?
upd: this question is not duplicate, it's about JS and general
approach, I'm fine with approach I explained, I wonder if and how I can implement it using spring boot and spring security.
JWT consists of three sections:
Header #info about used algorithm
Payload #contains data, this one is important in your case
Signature #basically a hash of the first two items on this list
You should read about Payload (and JWT itself) here https://jwt.io/introduction
Long story short, you can include public data in the payload. If it comes to the mentioned RemoteTokenServices - sure, you can do that but I'm not sure if it's a good idea. You could just add public expiration-date (or expires) property to the payload.
Also, take a look at this: https://jwt.io/
I'm talking about the case when these two are separate apps. I'm not interested in merging them in one app.
So, in a authorization server we extend AuthorizationServerConfigurerAdapter class and in resource server ResourceServerConfigurerAdapter and in both we create exactly the same beans like JwtAccessTokenConverter, DefaultTokenServices etc. but mostly I don't get why do we need TokenStore in both.
Does this mean that we store for example in memory the same token in different applications?
What's the best approach to remove this code duplication? Create a library for common classes? Make request to auth server to validate the token? But how are we going to extract more info from JWT token if we don't have the decoding logic in resource server?
Does this mean that we store for example in memory the same token in different applications?
https://auth0.com/learn/json-web-tokens/
This is a stateless authentication mechanism as the user state is never saved in the server memory. The server’s protected routes will check for a valid JWT in the Authorization header, and if there is, the user will be allowed. As JWTs are self-contained, all the necessary information is there, reducing the need of going back and forward to the database.
What's the best approach to remove this code duplication? Create a library for common classes?
If you use a symmetric key:
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
JwtAccessTokenConverter, DefaultTokenServices etc will be identical beans in both resource server and authentication server, so you could have a common project for both with the declarations of these beans, and add them as a dependency in both projects.
But, if you use an asymmetric KeyPair, the beans declaration changes completely and they couldn't be the same.
You can see more information about this difference here:
https://www.baeldung.com/spring-security-oauth-jwt
Make request to auth server to validate the token?
JWT's main advantage is not having to do that.
But how are we going to extract more info from JWT token if we don't have the decoding logic in resource server?
If you use a symmetric key, you can decoding logic in resource server.
The best way to resolve this case in the microservice system - is to create some entities: API composer, authorization service and business services.
Base mechanism of this scheme is:
Firstly, you separate your requests with unauthorized and authorized with a token header. Usually, it's named something like "X-AUTHORIZATION-HEADER" or anything like this. In this header, you put your JWT-token and send it on the server's gateway, which role is performing 'API Composer' - It's some kind of router, which accept requests, and delivery them to the appropriate recipients.
In particular, API composer accepting a response, parsing headers, finding the appropriate header with a token, and sending it to Auth Service and receiving a response with user or error. And in this scheme, you need entities like JwtAccessTokenConverter and else only in Auth Service
Then, aggregated response payload will be complete, your API will send the response to the client.
I use this scheme when I developing my microservice systems, for me it's working fine.
Hope, I correctly understood your question and my answer is will help you) Best Regards.
I have two services.
service1 generates one token and passes to client,
client receives token,
service2 receives toekn from client,
Now how to check token generated by service1 is same as token received by service2
Sign the token digitally using some pre-defined keypair for which the public key is known and trusted.
If the token you describe is for authentication, you are best off using an existing library such as apache shiro or picket-link. Coding this yourself is unlikely to be secure unless you put in a lot of time and effort.