when i generate jwt token on server, one of my claim is ClaimType.Name,
but in blazor web assembly when i parse jwt token and get claims,
it's name changed to unique_name.
can anyone explain why this is happen?
on server
new Claim(ClaimTypes.Name, user.Username);
on blazor web assembly
"unique_name" = "myUsername"
This is by design. This post has the details with excerpts from the JwtSecurityTokenHandler code.
The rule you found is from this Dictionary entry that is used to do a mapping:
{ JwtRegisteredClaimNames.UniqueName, ClaimTypes.Name },
Basically, Microsoft Identity Claims are converted (when appropriate) to JWT standard names.
Related
Background
On the Google Kubernetes Engine we've been using Cloud Endpoints, and the Extensible Service Proxy (v2) for service-to-service authentication.
The services authenticate themselves by including the bearer JWT token in the Authorization header of the HTTP requests.
The identity of the services has been maintained with GCP Service Accounts, and during deployment, the Json Service Account key is mounted to the container at a predefined location, and that location is set as the value of the GOOGLE_APPLICATION_CREDENTIALS env var.
The services are implemented in C# with ASP.NET Core, and to generate the actual JWT token, we use the Google Cloud SDK (https://github.com/googleapis/google-cloud-dotnet, and https://github.com/googleapis/google-api-dotnet-client), where we call the following method:
var credentials = GoogleCredential.GetApplicationDefault();
If the GOOGLE_APPLICATION_CREDENTIALS is correctly set to the path of the Service Account key, then this returns a ServiceAccountCredential object, on which we can call the GetAccessTokenForRequestAsync() method, which returns the actual JWT token.
var jwtToken = await credentials.GetAccessTokenForRequestAsync("https://other-service.example.com/");
var authHeader = $"Bearer {jwtToken}";
This process has been working correctly without any issues.
The situation is that we are in the process of migrating from using the manually maintained Service Account keys to using Workload Identity instead, and I cannot figure out how to correctly use the Google Cloud SDK to generate the necessary JWT tokens in this case.
The problem
When we enable Workload Identity in the container, and don't mount the Service Account key file, nor set the GOOGLE_APPLICATION_CREDENTIALS env var, then the GoogleCredential.GetApplicationDefault() call returns a ComputeCredential instead of a ServiceAccountCredential.
And if we call the GetAccessTokenForRequestAsync() method, that returns a token which is not in the JWT format.
I checked the implementation, and the token seems to be retrieved from the Metadata server, of which the expected response format seems to be the standard OAuth 2.0 model (represented in this model class):
{
"access_token": "foo",
"id_token": "bar",
"token_type": "Bearer",
...
}
And the GetAccessTokenForRequestAsync() method returns the value of access_token. But as far as I understand, that's not a JWT token, and indeed when I tried using it to authenticate against ESP, it responded with
{
"code": 16,
"message": "JWT validation failed: Bad JWT format: Invalid JSON in header",
..
}
As far as I understand, normally the id_token contains the JWT token, which should be accessible via the IdToken property of the TokenResponse object, which is also accessible via the SDK, I tried accessing it like this:
var jwtToken = ((ComputeCredential)creds.UnderlyingCredential).Token.IdToken;
But this returns null, so apparently the metadata server does not return anything in the id_token field.
Question
What would be the correct way to get the JWT token with the .NET Google Cloud SDK for accessing ESP, when using Workload Identity in GKE?
To get an IdToken for the attached service account, you can use GoogleCredential.GetApplicationDefault().GetOidcTokenAsync(...).
I am using the Swagger OpenAPI 3.0.2 version for describing my API.
I built swagger-codegen 3.0.5 snapshot from the Swagger gihub repo.
I want a Java client that will obtain the OAUTH2 token for a grant type of client_credentials. I want client credentials because this is one machine talking to another, I am not asking a user for their credentials. I have the following bit in my spec file:
securitySchemes:
oAuth2ClientCredentials:
type: oauth2
description: Standard OAUTH2
flows:
clientCredentials:
tokenUrl: my_token_url
scopes: {}
security:
- oAuth2ClientCredentials: []
I want a Basic Authentication header with the client ID and the client secret in the standard base64 encoding with the grant_type as a URL encoded form. This is pretty standard OAuth2 authentication.
I seem to sometimes get code for the OAuth authentication and sometimes not. The python library has nothing for OAuth other than me proving the access token by hand. The Java library doesn't have it unless I ask for retrofit as the base library, but it generates a Bearer Authentication header, rather than a Basic Authentication Header. Retrofit2 doesn't even work, the handlebars template has an illegal character in it that handlebars barfs on.
So what do people do to get their access tokens when they have a client ID and a client secret? Do you craft the code to get the access token by yourself? Or is there some magic way of getting swagger-codegen-cli to generate the code for me, depending on the libraries that I use?
If anyone has managed to get swagger-codegen-cli to generate everything they need for OAuth 2 client credentials with an OpenAPI 3.0 specification, please let me know.
I have an Identity Server running based on IdentityServer 4 (.Net Core v2) targeting the full .Net framework, and I have an ASP.NET WebAPI built against ASP.Net Web API 2 (i.e. NOT .Net Core) that is using the Identity Server 3 OWIN middleware for token authentication.
When running locally, everything works just fine - I can use Postman to request an Access Token from the Identity Server using a RO Password flow, and I can then make a request to the WebAPI sending the token as a Bearer token - all works fine.
Now, when everything is hosted on our test servers, I get a problem when calling the WebAPI - I simply get an Unauthorized response. The token returned from the Identity server is ok (checked using http://jwt.io), but validation of the JWT is failing in the WebAPI.
On further investigation, after adding Katana logging, I see that a SecurityTokenInvalidAudienceException is being reported.
Audience validation failed. Audiences:
'https://11.22.33.44:1234/resources, XXXWebApi'. Did not match:
validationParameters.ValidAudience: 'https://localhost:1234/resources'
or validationParameters.ValidAudiences: 'null'
Looking at the JWT audience, we have:
aud: "https://11.22.33.44:1234/resources", "XXXWebApi"
In the WebAPI Startup, I have the call to
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = , // path to our local ID Server
ClientId = "XXXWebApi",
ClientSecret = "XXX_xxx-xxx-xxx-xxx",
RequiredScopes = new[] { "XXXWebApi" }
});
So the JWT audience looks ok, but its obviously not matching with what is supplied by the middleware (built from the IdP discovery end point). I would have thought that because I am specifying the RequiredScopes to include XXXWebApi that would have been enough to match the JWTs audience but that seems to be ignored.
I'm unsure what to change in the WebAPI authentication options to make this work.
EDIT: I changed the WebAPI Token auth options to use the validation endpoint, and this also fails in the IdentityServer with the same error.
If I call the Identity Server introspection endpoint directly from Postman with the same token though, it succeeds.
Ok, so after a lot of head scratching and trying various things out I at least have something working.
I had to ensure the Identity Server was hosted against a publicly available DNS, and configure the Authority value in the IdentityServerBearerTokenAuthenticationOptions to use the same value.
That way, any tokens issued have the xx.yy.zz full domain name in the JWT audience (aud), and when the OWIN validation middleware in the WebAPI verifies the JWT it uses the same address for comparison rather than localhost.
I'm still slightly confused why the middleware cant just use the scope value for validation because the token was issued with the API resource scope (XXXWebAPi) in the audience, and the API is requesting the same scope id/name in the options as shown.
As far as I understand your WebAPI project is used as an API resource.
If so - remove the 'clientId' and 'clientSecret' from the UseIdentityServerBearerTokenAuthentication, keep the 'RequiredScopes' and the authority (you may also need to set ValidationMode = ValidationMode.Both).
You need them, when you are using reference tokens. From what you've said - you are using a JWT one. Check here, here and here.
I went through this tutorial on KONG
https://getkong.org/plugins/jwt/
I have an understanding of JWT and authorization concepts. I have prototyped JWT with Spring Boot where I could put my own key value like this {"authorizations":"role_admin, role_user"}.
It is easy to do that in Spring Boot but I am not able to find information on how to do this with KONG. Anyone has any info about it?
Kong community edition can handle only the authentication process, (give or deny access to a customer).
Authorization process (what a given customer can do in your application) is handled by your application or by https://getkong.org/plugins/ee-oauth2-introspection/ oauth2 introspection plugin which is enterprise edition only
you can write your own authorization server based on X-Consumer-Username request header if user passed authentication or original token header proxied by kong
hope helps
The kong jwt plugin does not support sending custom payload parameters to the upstream api. It does however seem like you can use this plugin (I have not tested it):
https://github.com/wshirey/kong-plugin-jwt-claims-headers
Update:
If you set Kong to forward all headers you'll get the raw Authorization header with the jwt token. So you could base64 decode the jwt token and pull out the claims/payload parameters you need manually in your service.
I am using WSO2 5.1 – STS service. With the stsclient (java program) I am making a SAML token request. However, I am not getting the claims details as part of the SAML token response from IS.
The same request is returning the claims when a request is sent to WSO2 IS 5.0.
For SSO requirement Looks like I have to set “Attribute Consuming Service Index”. But not sure where to set this attribute in the SAML request while using the stsclient java program.
This resembles this question but not related to STS.
In your Service Provider's SAML configuration, you have to make sure following two checkboxes are checked.
Enable Attribute Profile
Include Attributes in the Response Always
Then, inside the Claim Configuration section of the Service Provider, you have to add the particular user claims that you wish to receive in SAML response as the Requested Claims.
Then you should be able to receive the user claims in SAML response, provided that user's profile already contains values for these claims.
Refer [1] for more details.
[1] http://tharindue.blogspot.com/2016/08/retrieving-user-claims-in-saml-response.html