bearer JWT token client authentication and access token issued by authorization server - authentication

authorization server issues an access token with issuer details which are exposed in well-known api of that server. this server uses client authentication JWT token with clients configured , these JWT tokens are sent as a part of request from clients to authorization server and having one of the claim audience of authorization server with URL and port.
Now, the question is should well-known api have the same issuer URL(access token) details as audience in (JWT), or the JWT audience can be different URL with port of authorization server.
payload of client authentication JWT
{
"aud":"https://server:port"
}
payload of access token JWT
{
"iss":"https://server/address/abc"
}

CLIENT ASSERTIONS
The rules for using JWTs as client assertions are explained in RFC7523. This is different to JWT access tokens issued by the authorization server. A typical header and payload looks like this:
{
"kid": "1",
"alg": "RS256"
}
{
"sub": "my-client",
"iss": "my-client",
"aud": "urn:mycompany.com",
"jti": "7eb87efb-2094-ecf0-531a-357c1d570582",
"scope": "read",
"iat": 1651070751703,
"exp": 1651070811703
}
The client application has its own private key and uses a JWT library to issue the JWT. The corresponding public key used by the authorization server to verify client assertions can be pasted into the OAuth client registered in the authorization server.
Alternatively an external JWKS URI can be configured against the OAuth client. The party providing the client then provides the JWKS endpoint.
ISSUER
This must always the client application when using client assertions, as explained in section 3.1 of the above spec. In my example this is the value my-client.
AUDIENCE
The aud claim must represent the authorization server, as explained in point 3.3 of the above spec.
This can be the URL of the token endpoint, or the issuer URL or your issuer identifier, eg urn:mycompany.com.
The most cutting edge behaviour is described in the FAPI 2.0 profile, for higher security apps. Point 20 says that the issuer identifier should be accepted in the aud claim. This is a requirement in order for the authorization server to be considered FAPI 2.0 compliant - not all auth servers are.
ANSWER TO YOUR QUESTION
This is the standards based way to do it:
In your app's code, set iss to a value representing your client application, as in my example.
In your app's code, set aud to the issuer identifier of the auth server.
In the auth server, register an OAuth client. Configure the public key for the keypair used to create the assertion there. Either by value (pasting it in) or hy reference (JWKS URI). If there is a setting for issuer, configure the value of the client, which is my-client in the above example.
So the behaviour you describe seems correct and expected. Test with invalid values, and ensure that you get a 401 error.

Related

What do I verify within a client bearer token?

I've got service A, an OAuth 2 authentication server, and service B.
Service A has an API and trusts the authentication server.
Service B needs to call service A's API, and to do so it needs to include a client (i.e., non-user-specific) bearer token in the request header.
Aside from client_id and sub (which should be the same as client_id), what information from the bearer token does service A need to use to verify with the authentication server that service B is who it says it is, that the bearer token is valid?
what information from the bearer token does service A need to use to verify with the auth server that service B is who it says it is, that the bearer token is valid?
In addition to sub, you should validate:
That it is not expired.
That the token issuer iss is the server that you trust.
That the token is signed e.g. with RSA and signed by the issuers private certificate.
Common OAuth servers on the market can typically do these validations for you by using a http endpoint.

Ktor application.conf - Jwt configuration

I'm trying to set up JWT authentication in my ktor app. Documentation suggests to define a jwt verifier into application.conf file like below:
jwt {
domain = "https://jwt-provider-domain/"
audience = "jwt-audience"
realm = "ktor sample app"
}
I'm not an expert of jwt authentication, so I was wondering what's the meaning of domain, audience and realm settings, documentation unfortunately lacks of these details.
By taking a look to the generated jwt token it turns out that:
audience is solves in the RFC 7519 "aud" claim:
The "aud" (audience) claim identifies the recipients that the JWT is
intended for.
Normally it's an array of case-sensitive strings, containing clients identifiers. For example it may be the app(s) package name, something like:
ios.organization.appname, android.organization.appname
domain solves in the RFC 7519 "iss" claim:
The "iss" (issuer) claim identifies the principal that issued the
JWT.
It's application specific, in my case I chose the identifier of my authentication server (Single sign on), something like:
sso.organization.com
Realm there's not any trace of this field in my generated jwt token, but from the ktor documentation seems that this field is used in the WWW-Authenticate response header
As far as I know, the documentation refers to domain as the issuer (iss) claim and the audience as the aud claim (described in https://www.rfc-editor.org/rfc/rfc7519#section-4.1). Other settings may not be neccessary.

How to validate x509 signing credentials with IdentityServer4

I have two .Net Core APIs - an authorization server that issues a JWT identity token using IdentityServer4, and a resource API that is protected and requires that token.
The auth server is using a self-signed x509 certificate (for now).
In the the auth server I have something like this in ConfigureServices:
var certificate = new X509Certificate2(//path.to.my.certificate//);
services.AddIdentityServer().AddSigningCredential(certificate)
But my understanding of how the resource API will validate the signing credentials is not clear.
All I have in ConfigureServices for the resource API is:
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(
options =>
{
options.Authority = "//MyAuthAPI";
});
Should the resource API use the same certificate to validate the JWT token? Is that necessary?
If so, how should that be done?
Basically the ASP.Net Core middleware downloads the identity provider configuration from https://{yourDomain}/.well-known/openid-configuration which is your options.Authority uri. If you actually navigate to one sub url https://{yourDomain}/.well-known/openid-configuration/jwks, you will also see that identity provider publishes the public key that it uses to sign the tokens.
With the public key acquired, the middleware is able to verify that the tokens were indeed issue by the expected authority uri using the headers (Authorize : Bearer {token}) included in the api requests using regular asymmetric encryption verification methods.

Why JWT is a stateless authentication?

I am trying to understand how JWT authentication is stateless. In stateful authentication, there will be a session id. Here there is a JWT token which is signed. So the authentication server issues the JWT token, but can I say the validation of the JWT token in subsequent requests are done by the endpoint server (application server) rather than the authentication server. I believe this is possible as JWT is signed with expiry date (and also some other information) and the public certificate of authentication server is available to all endpoint servers.
So the authentication server will be only responsible for issuing the tokens and not validation. The validation will be done by the endpoint server.
Is my understanding correct? Is this how JWT is made stateless? Otherwise, I don't see how it is different from a stateful authentication as both can be implemented using tokens.
In stateful authentication, the centralized server will be responsible for issuing the tokens as well as validation is each request.
JSON Web Tokens (JWT) are referred to as stateless because the authorizing server needs to maintain no state; the token itself is all that is needed to verify a token bearer's authorization.
JWTs are signed using a digital signature algorithm (e.g. RSA) which cannot be forged. Because of this, anyone that trusts the signer's certificate can safely trust that the JWT is authentic. There's no need for a server to consult the token-issuing server to confirm its authenticity.
Notice in this diagram that the Resource Server does not need to check back with the Authorization Server:
Source: https://jwt.io/introduction/
In stateless authentication there is no need to store user information in the session. We can easily use the same token for fetching a secure resource from a domain other than the one we are logged in to.
Refer : https://www.jbspeakr.cc/purpose-jwt-stateless-authentication/

Thinktecture Identity Server: Securing Web APIs (Authorization Best Approach)

When protecting APIs using bearer token authorization:Is there a need to validate that the token was issued from my identity server or its already happening in the background and how do I do that?
What role do scopes play when it comes to bearer tokens?
In short, yes you need to validate that bearer tokens are issued by a issuer you trust. That means either by validating that it's signed by a trusted issuer, or making a API call to the isser you trust to ask it if it indeed is issued by the issuer you trust.
In practice: when talking about Katana, this is done by using a combination of [Authorize] filters/attributes and Owin middleware:
Option 1
The middleware from Microsoft:
app.UseOAuthBearerAuthentication(opts)
https://msdn.microsoft.com/en-us/library/owin.oauthbearerauthenticationextensions.useoauthbearerauthentication(v=vs.113).aspx
https://www.nuget.org/packages/Microsoft.Owin.Security.OAuth
Or, optionally, the middleware from Brock Allen og Dominic Baier:
Option 2
using the following abstraction that builts on top if Microsofts middleware (IF you need the extra features it provides):
app.UseIdentityServerBearerTokenAuthentication(opts)
Source: https://github.com/IdentityServer/IdentityServer3.AccessTokenValidation
NuGet: https://www.nuget.org/packages/IdentityServer3.AccessTokenValidation/
Scopes
When it comes to scopes & API access, scopes are something that represents the resources you want to protect. When a client asks for a access token, it can ask for a token to include a given scope. Your identityprovider then validates that this client is indeed allowed to receive a token with this scope. If successful, the end result is a token allowing the client to call a API using this token.
Since the API trusts token issued by this identityprovider (or token provider), all it has to do is to
Validate that that the token is issued by someone that API trusts
Check that the token contains the scope that represents it's resource