How to get jwt token from Authorization - spring

I'm sending the request with jwt token in Authorization. I need to fetch it somehow and I tried by this way:
#GetMapping
fun getUser(#AuthenticationPrincipal jwt: Jwt<*, *>): ResponseEntity<UserDto?> {
val allClaimsFromToken: Claims? = getAllClaimsFromToken(jwt.toString());
val userNameFromJwtToken: Any? = allClaimsFromToken?.get("sub");
....
}
Unfortunately I get all the time null as jwt variable. Could you tell me what am I doing wrong?

Probably the most straight forward way of doing this would be to get the raw header value and then parse it with JJWT.
#GetMapping
fun getUser(#RequestHeader (name="Authorization") tokenEncoded: String): ResponseEntity<UserDto?> {
Jwt myToken = Jwts.parserBuilder()
.setSigningKey(yourKeyHere)
.build()
.parseClaimsJws(tokenEncoded.removePrefix("Bearer").trim());
// do something
}
You could also look into using the Spring library for OAuth2 it automates a bit more. Or you can create a filter that does the parsing so you don't have to repeat this on every web call.
Also see this post for further ideas Accessing JWT Token from a Spring Boot Rest Controller . It's Java, but basically the same applies.

Related

Obtaining Refresh Token from MSAL during ADAL to MSAL migration

We are migrating from ADAL4J to MSAL4J. In ADAL, we store the refresh token in database and shared it between different micro services for token exchange. With MSAL, the refresh token is not easily accessible. We have built the code in a way that it's very difficult to get rid of the usage of the "refresh token". So we are seeking a solution to obtain the refresh token in MSAL.
Currently we have a few proposals (code examples are in scala):
Option 1. Convert package-scoped class msal.AuthenticationResult to a customized Result class
the helper class is defined under com.microsoft.aad.msal4j
package com.microsoft.aad.msal4j
trait AADTokenExchangeHelper(...) {
def acquireToken(...) = {
val result = app.acquireToken(requestParams).get.asInstanceOf[AuthenticationResult]
// store result.getRefreshToken
}
}
Option 2. Parse TokenCache and get refresh token
val tokenCache: String = app.tokenCache().serialize()
val tokensMap = ObjectMapper.fromJson[String, Map[String, Any]](tokenCache)
val refreshTokensMeta = tokensMap("RefreshToken")
.asInstanceOf[Map[String, Map[String, String]]]
.values
.toSeq
// may filter by client_id
val refreshTokens = refreshTokensMeta.map(m => m("secret"))
Option 3. Customize TokenCache
I don't have full details here. It seems that we need to parse the cache string as in Option 2
Are these options acceptable? Any suggestions are appreciated!
Looking at the solutions listed in your post, I believe retrieving token from the Token Cache (Option 2) is the best way to go about it.
Just make sure to check the token’s expiration date before using it.

Unable to find the group information of the logged in user -JWT token OKTA

I am new to Okta so apologies if my questions are not clear.
So what I want to do is basically parse the JWT token generated by
okta and extract the group information of the logged in user
associated with it.
I am under the impression that this information should be there in the
OidcUser object. I do see user name/email id / token validity etc
information inside this object. Unfortunately I can't see group id
which I need for further processing.
#RequestMapping("/")
public String hello(#AuthenticationPrincipal OidcUser user){
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, Object> entry : user.getClaims().entrySet()) {
sb.append(entry.getKey() + ":" + entry.getValue().toString());
sb.append("\n");
}
sb.append("|");
sb.append(user.getClaims());
return sb.toString();
}
Here is my okta plugin inside spring boot
okta.oauth2.issuer=https://dev-XXXXXXXX.okta.com/oauth2/default
okta.oauth2.client-id=XXXXXXXXXX
okta.oauth2.client-secret=XXXXXXXXXXXX
I am wondering if my approach is proper and what more I need to do to extract User group from Okta JWT token.
To get user groups you need to make an additional request to /userinfo endpoint, assuming you requested groups scope during /authorize call.
Please see a guide here
Not exactly spring-boot response, but it's always beneficial to know how things work under-the-hood

How to send JWT from spring boot to Flutter?

I would like to know what's the best and secured way to send the JWT generated in my spring boot app to my Flutter mobile app. I can send it in the response body which I know that's not a good practice in web but is it a problem when it comes to mobile?
This is how I return the JWT:
public ResponseEntity<?> signin(String username, String password) {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
String token= jwtTokenProvider.createToken(username, userRepository.findByUsername(username).getRoles());
//return new JwtResponse(token,username,userRepository.findByUsername(username).getRoles());
return ResponseEntity.ok(new AuthToken(token));
} catch (AuthenticationException e) {
throw new CustomException("Invalid username/password supplied", HttpStatus.UNPROCESSABLE_ENTITY);
}
}
IT doesn't matter how you send your JWT token, in the Header or in the body portion. it can easily be seen and copied by others through some app on the client-side.
The steps you can take to secure your data is
firstly You need to check if the Token is tampered with by the client, every time you receive a JWT token from the client
Secondly, you should add a created-at field where you send a timestamp of when the Token was created. This will prevent someone to pose as the owner of the token forever after this is stolen, as this Token will be invalid after some time.
and you can send your token simply in the body part of the response after taking those security measures. Of course, there are many more best practices to follow but these are a good starting point.

Kotlin/Spring - Fowarding post request from one service to another

We had a spring web-app that used to handle all front and back end logic. As we need to scale we have split that into two microservices. How would I go about 'forwarding' a post request to another url (including its body and authentication headers). For example:
microservice1 has an endpoint /api/doSomething
microservice2 has an endpoint /privateUrl/doSomething
I want the user to hit the endpoint on microservice1 which will post to microservice2 and return the result.
I have tried with RestTemplate without much luck, i keep getting error "Could not write JSON: No serializer found for class..." from microservice1, i suspect this is because microservice1 doesnt know how to parse the body object microservice2 requires.
microservice1:
#PostMapping("/api/DoSomething")
fun postIT(request: HttpServletRequest, #PathVariable one: String, #PathVariable two: String){ ...}
microservice2:
#CrossOrigin
#PostMapping("/privateUrl/doSomething")
fun postIT(request: HttpServletRequest, #RequestParam one: String, #RequestParam(required = false, defaultValue = "true") two: String,#RequestBody it: IT) { ... }
I know i can parse the entire request in microservice1 and then send it to microservice2, however is there a way to just 'forward' the http request to a new url?
I am not sure what you mean , but if you want to communicate from one server to another you can always use rest template (or any other) and send http request from one service to another, you can see examples here
https://www.tutorialspoint.com/spring_boot/spring_boot_rest_template.htm
https://spring.io/guides/tutorials/bookmarks/
take a look it should work for you.

How to skip Azure active directory authentication in Web API depends on Url request header value

How to skip the [Authorization](Azure AD authentication) from Web Api controller depends on the value from header request?
[Authorize]
public class ExampleController : ApiController
{
//code
private string _clientid;
var req = Request.Headers;
_clientid = string.IsNullOrEmpty(req.GetValues("clientid").First())
? null :
req.GetValues("clientid").First();
}
The above mentioned _clientid is a header value, I want to skip authentication for some _clientid values.
In my opinion you essentially have an alternative way of authentication.
It would make the most sense to define your own authentication scheme that checks that header and creates a user principal based on that.
Then you can keep on using [Authorize] as usual.
Writing an example would be quite time-consuming, the best I can offer at the moment is the Security repo, which contains all of the built-in authentication schemes, like JWT Bearer here: https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs Check those for examples on how to implement an authentication handler.
You can create a custom authentication handler similar to the one here .
Then, where you add authorization in Startup.cs, you can add a custom policy like this:
services.AddAuthorization(
o =>
{
// create a policy called ApiKeyPolicy which requires a Role defined in
// ApiKeyAuthenticationOptions.
// The policy is used by the API controllers.
o.AddPolicy(
"ApiKeyPolicy", builder =>
{
builder.AddAuthenticationSchemes(
ApiKeyAuthenticationOptions.AuthenticationSchemeName);
});
});
and add the scheme to the services.AddAuthentication builder:
builder.AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(
"ApiKey", "ApiKey", o =>
{
o.AllowedApiKeys = config["Api:AllowedApiKeys"];
o.ApiKeyHeaderName = config["Api:ApiKeyHeaderName"];
});
In my example, I have an ApiKeyAuthenticationOptions class that is configured with some API keys and the http header name to check. In your case, you would probably want the valid client IDs.
Finally, you need to tell the [Authorize] attribute which policy is needed:
[Authorize(Policy = "ApiKeyPolicy")]
In your case, you want to be able to handle both the client IDs and regular auth, so you could add the regular auth scheme to the policy builder expression (the first snippet above).

Resources