The documentation states: API Gateway validates the token on behalf of your API, so you don't have to add any code in your API to process the authentication.
My question is how?
To authenticate a user, a client application must send a JSON Web Token (JWT) in the authorization header of the HTTP request to the backend API.
So for API Gateway to authenticate the user it needs to know the secret key to calculate signature of a header and payload of JWT to compare it with the signature from JWT.
How does it do that?
My code to verify token is like below and I imagine the API gateway would be using something similar to that - so the _appSettings.Secret is needed:
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
tokenHandler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
// set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
ClockSkew = TimeSpan.Zero
}, out SecurityToken validatedToken);
Assuming you're talking about AWS API Gateway; It does require the secret key used for signing the original JWT token but mostly for custom authorization schemes as the documentation states.
A Lambda authorizer is useful if you want to implement a custom authorization scheme that uses a bearer token authentication strategy such as OAuth or SAML, or that uses request parameters to determine the caller's identity.
To achieve this the API Gateway takes a Lambda authorizer to use in the authorization process. You provide the Lambda authorizer with the required details such as the secret key used to sign your JWT token and it can then verify the token based on that. See this AWS example for more details on the implementation.
The API Gateway will then use the provided detail to verify your JWT tokens and authorize a request.
Related
I've been looking for an example or tutorial for a few hours and thought I should post something at this point.
I'm trying to validate a bearer token from a custom Auth provider inside my .Net 4.7.2 Web Api 2 project. I have a SPA app that gets a bearer token from this auth provider, and sends the bearer token to my WebApi endpoints. I need to turn around and validate the token in each request. I thought there would be a way to point the classes in the Microsoft.Owin.Security.Jwt namespace to validate the token based on the auth providers well known discovery information url.
Has anyone done this before or point me towards a good library/documentation/tutorial?
I know I can write my own auth request filter and go out and pull down the public certificate from the auth server and parse the token and validate the signature, but it seems like a horrible idea for me to write that myself vs using the appropriate libraries.
Ok turns out I found a good example here
The following code sets up our webapi to validate tokens with our custom auth provider while discovering the public key through the OIDC discovery url.
var issuer = "https://my-auth-provider-here/";
IConfigurationManager<OpenIdConnectConfiguration> configurationManager =
new ConfigurationManager<OpenIdConnectConfiguration>($"{issuer}.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration openIdConfig = configurationManager.GetConfigurationAsync(CancellationToken.None).Result;
appBuilder.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions()
{
AuthenticationMode = AuthenticationMode.Active,
TokenValidationParameters = new TokenValidationParameters()
{
AuthenticationType = "Bearer",
ValidIssuer = issuer,
ValidateAudience = false,
IssuerSigningKeys = openIdConfig.SigningKeys
}
});
I start building new application with JWT authorization. Our team already have OAuth 2 server written in java, so my target is: check key with public key.
But I don't know how to do it. If I use .net identity I have to use entity framework but I use only Cassandra as a database.
How I can implement it without using EF? Do you know any tutorials?
You don't need any ASP.NET Core stuff. A simple approach would be:
Nu-get the Packages
System.IdentityModel.Tokens.Jwt,
Microsoft.IdentityModel.Tokens
Set up some validation parameters:
var validationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
ValidateLifetime = true,
IssuerSigningKeys = keys, // Your public keys.
ValidAudience = "my valid audience",
ValidIssuer = "my valid issuer"
}
Call ValidateToken to get a ClaimsPrincipal with claims and stuff.
token is your JWT string, e.g. parsed from Authorization HTTP header.
var handler = new JwtSecurityTokenHandler();
handler.ValidateToken(token, validationParameters, out SecurityToken validatedToken);
Using JsonWebKeySet from the above IdentityModel.Tokens package, you can automagically obtain keys from an OpenID Connect configuration:
https://github.com/IdentityModel/IdentityModel/blob/master/source/IdentityModel.Shared/Jwt/JsonWebKeySet.cs
There are quite a few Microsoft (and other) documents available (make sure you are looking at documents relevant to the version that you are working with!) - googling will find them pretty easily, but EF is certainly not required as seen below.
No identity or user information is managed by the app directly. Instead, it will get all the user information it needs directly from the JWT token that authenticates a caller.
https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/
Here is a simple example for version 1.1
https://github.com/williamhallatt/aspnet-core-webapi-jwt-auth-example
and the same example for 2.0
https://github.com/williamhallatt/aspnet-core-webapi-jwt-auth-example/tree/dotnecore2.0
I have an Identity Server which is built by using IdentityServer4.
I have 2 applications (1 .NET, 1 PHP) accessing resource each other and using this Identity Server to validate access token in request header.
In Identity Server application I add a client config as below
clients.Add(
new Client
{
ClientId = "myClientId",
ClientName = "My Client Name",
ClientSecrets = new List<Secret>
{
new Secret("secret".Sha256())
},
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = new List<string>
{
"php.es.api"
}
});
From .NET application I can get access token easily by calling method RequestClientCredentialsAsync with scope "php.es.api". Then add this bearer token and send request to PHP API.
The problem is I don't know whether IdentityServer4 has API so that PHP application can call it to authenticate the access token. I google and don't find any document mentions about this API.
Do I have to write new API in Identity Server application for PHP or other applications not .NET to validate token?
.NET application access resource from PHP application as below.
There is a standard endpoint for this called the introspection endpoint and it is supported by IdentityServer4. Your best bet is to find an oauth client in PHP that does this. If you are using self-contained bearer tokens you can validate tokens without the need for back-channel communication because the bearer tokens are signed by your provider and your provider has its keys listed in the discovery document required to validate the tokens (/.well-known/openid-configuration). I am not too familiar with PHP to point you in the right direction as to what cool libraries there might be out there
My Jwt Token looks like below:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxMzU2OTk5NTI0LCJuYmYiOjEzNTcwMDAwMDAsImV4cCI6MTQwNzAxOTYyOSwianRpIjoiaWQxMjM0NTYiLCJ0eXAiOiJodHRwczpcL1wvZXhhbXBsZS5jb21cL3JlZ2lzdGVyIiwidGVzdC10eXBlIjoiZm9vIn0.UGLFIRACaHpGGIDEEv-4IIdLfCGXT62X1vYx7keNMyc
If I Copy the above JWT token and paste it in https://jwt.io/ then the actual information is showing like this
Image
I want to encrypt the JWT token with no one can access my information in Web Api. So, I want to use any encryption algorithm, If so please provide me proper solution
Here is my Startup.cs file to authorize JWT Token.
// Api controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { audience },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
}
});
}
Why exactly do you think that it is a problem that someone can see this information? If you are using JWT for authentication, then it's only the user who was just authenticated will get this token and it probably contains the information about this user. So it does not hurt for a user to be able to see information about himself.
Most importantly the token is mac'ed so that no one can forge it and pretend to be another user and that should be sufficient.
And as mentioned in the comments you should be using TLS anyway, so it's encrypted in the transition.
I have a separate angular client that I want to authenticate to using Azure AD. I am using ADAL JS and all of that seems to be working fine. I get redirected to the AD login page, and then sent back to my application. I can see the token getting passed with each subsequent http request.
However, when I try to make a secured request to my Web API I receive a 401 Unauthorized error. I am loosely following the guide here for setup. I say loosely because I'm not using MVC, my client is in a separate codebase entirely.
I am positive that my user has access to this application.
My Auth Configuration stuff looks like:
app.UseWindowsAzureActiveDirectoryBearerAuthentication(new WindowsAzureActiveDirectoryBearerAuthenticationOptions()
{
TokenValidationParameters = new TokenValidationParameters()
{
ValidAudience = ConfigurationManager.AppSettings["AzureADAudience"],
},
Tenant = ConfigurationManager.AppSettings["AzureADTenant"],
AuthenticationType = "OAuth2Bearer"
});
Audience: https://login.windows.net/xyz.onmicrosoft.com/myappname
Tenant: xyz.onmicrosoft.com
The controller I'm locking down is decorated like this:
[HostAuthentication("OAuth2Bearer")]
[Authorize]
[RoutePrefix("Auth")]
Is your SPA hosted with your backend? If so, then you need to change your audience to the Client ID.
ValidAudience = ConfigurationManager.AppSettings["ida:ClientID"]