What is the OpenID Connect access token for? - http

The OpenID Connect JWT token contains both an id_token and an access_token (Like "access_token": "SlAV32hkKG"). What is the access_token for?
ANSWER EXAMPLE
Just adding an example to complement the answers taken from this linked article
User Info Endpoint Request
GET /userinfo HTTP/1.1
Host: openid.c2id.com
Authorization: Bearer SlAV32hkKG
User Info Endpoint Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"sub" : "alice",
"email" : "alice#wonderland.net",
"email_verified" : true,
"name" : "Alice Adams",
"picture" : "https://c2id.com/users/alice.jpg"
}

The answer to your question lies in the section 5.3 and 16.4 of the specification. The access token is used to access the userinfo endpoint which is a protected resource.
16.4. Access Token Disclosure
Access Tokens are credentials used to access Protected Resources, as defined in Section 1.4 of OAuth 2.0 [RFC6749]. Access Tokens represent an End-User's authorization and MUST NOT be exposed to unauthorized parties.
[...]
5.3. UserInfo Endpoint
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User. To obtain the requested Claims about the End-User, the Client makes a request to the UserInfo Endpoint using an Access Token obtained through OpenID Connect Authentication. These Claims are normally represented by a JSON object that contains a collection of name and value pairs for the Claims.

tl;dr - Access token grants authorization to access a protected resource where the ID token is consumed by the client for authentication.
Access token
Being an extention to OAuth2.0, OpenID Connect keep tokens/prameters defined in OAuth2.0 specification. Access token is one such thing. As defined by the protocol, access token is used to access protected resources. It replaces user credentials, manually generated tokens or security keys which were used in good old days (ex:- Think about basic authentication).
Note the access token could be an opaque string. Which means it's nothing that could be consumed by the client which recieves it. But the authorization server knows what it is. For example, introspection endpoint (RFC7662) can be used to validate the validity of an access token. And access token can be a JWT too depending on the usage and implementation.
ID token
This is what OpenID Connect introduced to OAuth2.0. ID token is a JWT and it is consumed by client to authenticate the end user(the resource owner). By validating an ID token, client have the ability to authenticate. Due to this fact, one can argue it surves one time usage.
Also note that in some implementations, ID tokens are being used as bearer tokens. That mean, ID token used like an access token for authentication and authorization.

Related

Need help setting up Postman Collection Authorization with API Token and Credentials

I am learning to connect to one of our 3rd party's API, and the first step in doing so is to first get an access token to use for additional requests.
To get that access token, I send a POST request that includes an API key in the header, along with the username and password in the body (as JSON). And that successfully returns a token.
But how do I set up that up in a collection? In postman I have options of API token, Basic Auth, Oath2, etc. But I do not see how you set up and include both the API key and user/password.
I've tried different scenario's of just the API Key and Oath2 with credentials, but unsure how you set it up to include both.

How to set up custom user authentication with Google Cloud Endpoints

I am trying to understand how to use Cloud Endpoints with custom authentication. From the docs I understand that it starts from the securityDefinitions:
securityDefinitions:
your_custom_auth_id:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
# The value below should be unique
x-google-issuer: "issuer of the token"
x-google-jwks_uri: "url to the public key"
# Optional. Replace YOUR-CLIENT-ID with your client ID
x-google-audiences: "YOUR-CLIENT-ID"
This is how I understand the flow:
API consumer sends a request with a JWT token in the header
ESP validates this token using the authorizationUrl
The request is forwarded or ESP returns an error.
My questions:
Is the flow above correct?
How should the authorizationUrl be implemented. How does the request look, what response should be return in case of success or failure
What about this values?
x-google-issuer: "issuer of the token"
x-google-jwks_uri: "url to the public key"
x-google-audiences: "YOUR-CLIENT-ID"
Configuring Custom Authentication for Endpoints
To configure custom authentication for Endpoints (and according to the OpenAPI v2 spec), you need two pieces:
Define your custom authentication scheme in the securityDefinitions section of the spec
Apply your custom authentication scheme (defined in #1) to the entire api or to specific operations using the security field.
The Google Cloud Endpoints docs describe this here.
OpenAPI Spec's SecurityDefinitions
Some fields in the SecurityDefinitions section of the OpenAPI spec are for the API producer, and some are for the API consumer.
The following fields are for the API producer and tell Endpoints how to validate the access tokens that accompany API requests:
type: "oauth2"
x-google-issuer: "issuer of the token"
x-google-jwks_uri: "url to the public key"
x-google-audiences: "YOUR-CLIENT-ID"
These fields are specified by the API producer and tell the consumer how to get a valid access token:
authorizationUrl
flow
Re:Your Questions
Correct. Here is documentation on how the consumer should send the access token with the request
ESP validates the access token using the public keys specified in the x-google-jwks_uri property of the spec and ensures that the issuer of the token matches the issuer specified in the securityDefinition's x-google-issuer field.
Correct.
Regarding your questions, the authorizationUrl should be set up by the OAuth2 provider you are using. That url should allow the consumer to execute the implicit OAuth2 flow to get an access token. All you need to do is specify this

Issue with jwt-bearer authorization grant in Azure AD

There are two ASP.NET Core Web APIs that use bearer token authentication. The services also serve static files which are used to consent the APIs into the directory of a consuming application. So both APIs have implicit flow enabled in Azure AD.
API2 is calling into API1 from the Web API controller using the jwt-bearer grant. API2 has permission to access API1.
A user from a third directory navigates to the SPA served by API2. The user is redirected to Azure AD, signs in and consents the API. The user is redirected back to the SPA application and an AJAX call is made to the API2 web API. From that controller, another call is made to API1. This call is authenticated using the jwt-bearer grant (urn:ietf:params:oauth:grant-type:jwt-bearer).
When the AcquireToken call is made with client credentials for API2 and the JWT token used to call into API2, Azure AD responds with an error:
Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException:
AADSTS50027: Invalid JWT token. AADSTS50027: Invalid JWT token. Token format not valid.
Trace ID: 4031717e-aa0c-4432-bbd1-b97a738d3e6f
Correlation ID: 61ae6cd6-6df6-49ee-9145-c16570c28f7b
Timestamp: 2017-02-13 22:44:01Z ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (BadRequest). ---> System.Exception: {"error":"invalid_request","error_description":"AADSTS50027: Invalid JWT token. AADSTS50027: Invalid JWT token. Token format not valid.\r\nTrace ID: 4031717e-aa0c-4432-bbd1-b97a738d3e6f\r\nCorrelation ID: 61ae6cd6-6df6-49ee-9145-c16570c28f7b\r\nTimestamp: 2017-02-13 22:44:01Z","error_codes":[50027,50027],"timestamp":"2017-02-13 22:44:01Z","trace_id":"4031717e-aa0c-4432-bbd1-b97a738d3e6f","correlation_id":"61ae6cd6-6df6-49ee-9145-c16570c28f7b"}
Can anyone tell me what this error means? The JWT token itself is correct, it must be one of the claims inside that Azure AD dislikes.
I have the sample apps and repro steps in this github repo.
EDIT
A diagram may clarify what I'm trying to do. It's the interaction #3 that is giving me the error. It uses a ClientCredential with ClientId of API2 and a ClientSecret (or key) and the orange JWT token issued by directory3 with an audience of API2.
The orange JWT token looks like:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Il9VZ3FYR190TUxkdVNKMVQ4Y2FIeFU3Y090YyIsImtpZCI6Il9VZ3FYR190TUxkdVNKMVQ4Y2FIeFU3Y090YyJ9.eyJhdWQiOiJmOTJjNGI5MS05NTY3LTRjYjgtOTI4MC0yYmFjNDUyYmZjZTEiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9iYWRiODcyNC1jODExLTRlYjEtOTcwZi04YmI4MzU0NTI0OTEvIiwiaWF0IjoxNDg3MDM1MDI5LCJuYmYiOjE0ODcwMzUwMjksImV4cCI6MTQ4NzAzODkyOSwiYW1yIjpbInB3ZCJdLCJmYW1pbHlfbmFtZSI6Im9uZSIsImdpdmVuX25hbWUiOiJ1c2VyIiwiaXBhZGRyIjoiNzMuMTU3LjExMC4xNjQiLCJuYW1lIjoidXNlciBvbmUiLCJub25jZSI6ImRjOTYwMjkzLWQ0MTItNDFmNy1iMGRhLWYzZWM2NTE1ZTM1YSIsIm9pZCI6IjUzMTE1OTY0LWQwOTMtNGM5NS05MDkzLTg0ZjliNzVmYzNlOSIsInBsYXRmIjoiMyIsInN1YiI6IlVjVFVleGJYd1BWYkZ4aGRDUW9MR25vTkdsZnVQWi1feGtaSndIdU9zM1EiLCJ0aWQiOiJiYWRiODcyNC1jODExLTRlYjEtOTcwZi04YmI4MzU0NTI0OTEiLCJ1bmlxdWVfbmFtZSI6InVzZXIxQHppZWtlbmh1aXNBLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6InVzZXIxQHppZWtlbmh1aXNBLm9ubWljcm9zb2Z0LmNvbSIsInZlciI6IjEuMCJ9.lhwEL3x3Cu66l-Dt-hWmH2DrmCCX2YORGhl4x4_13_lZuUVhMr1OFLUdJ4MZRWG5DJMc8F_SyC4XdDiStwFDaLSI_4L6noXNau3KF6Su3PnqD-FoXoQPtmPPmFrDRZ7nPEtSazEcd9HeSwgVvRZywJRBKQqQQtBGBpS7-Y9kxrO-moUhnBdJJ-gwhu_wxwdEZaOuLs68sZuFaONAunElMKO1iYlC9VHP5xrVzh3ErnRSIp3xmgJNmlbf-9AFUSrjN5UaFjfpGGGJIvoaKbL6rq-J1XNpvKZDFYvoC7RMkqS1KM-lu-EI7-QCksb3NKhTg6J_bz5uxmjYltjKanWbUg
First, to enable the API2 could onbehalfof the user to acquire the token for API1, we need to grant the API1 to API2 when we register the API2 in the Directory2 like below:
Then since the service principal of API1 is also not created in Directory3, we need to sign-in the API1 first to to create the service principal of API1 on Directory3 tenant.
When the users sign-in the SPA from Directory3 and send the request to the API2, in the code you were acquire the token from Directory2. We should acquire the token from the tenant of users(Directory3).
And in the code, you were acquiring the token using the clientId, in this secnario, we should use the ClientCredential like below:
var result = await adal.AcquireTokenAsync(resource, clientCred, userAssertion);
After changing, the code works well for me. Please let me know whether it helps.
In addition, the scenario you are developing is like below and you can refer the detail from this link.

OpenIDConnect Response Type Confusion

I've spend the last few days reading through all the specs with regards to OAuth2 and OpenIDConnect and implementing a test client using Thinktecture Identity Server. I've also followed several pluralsight courses and I think understand the main gist of it. However i'm still extremely confused about the Response Types.
OpenIDConnect spec specifies that the Hybrid flow response types are a combination of "code", "id_token" and "token". I understand the "id_token" allows us to get access to basic id information initially.
I also understand code" refers to the authorization code and "token" refers to an access token and combining "code" with one or both of the other two triggers the flow but my understanding was that you swap an authorization code for an access token in the Authorization flow, while the Implicit flow supplies the Access Code implicitly?
Could someone clear up my confusion?
The following statements that you made are correct:
code refers to the Authorization Code
token refers to an Access Token or (access_token)
in the Authorization Code flow one switches the code for an access_token
But part of your confusion may originate from terminology mixup:
the term Authorization flow is not entirely correct; its official name is Authorization Code flow
the term Access Code does not exist
the Implicit flow does not have an Authorization Code (nor Access code) in fact there's no credential (or grant) involved at all that allows the Client to get tokens from the Token endpoint, hence it's name
As #juanifioren pointed out, Hybrid flows combine things:
the code id_token flow would get a code and id_token in the Authentication Response directly but you'd use the code to get an access_token from the Token endpoint
the code token flow would get a code and access_token in the Authentication Response directly but you'd use the code to get an id_token and possibly another access_token in the backend from the Token endpoint
the code id_token token flow would get a code, access_token and an id_token in the Authentication Response directly and you could use the code in the backend to get another access_token from the Token endpoint
Getting an access_token from the Token endpoint differs from getting it from the Authorization endpoint because the confidential clients authenticate themselves to the Token endpoint (and not to the Authorization endpoint). Hence the access_token for the confidential part of the client might have more permissions and or a longer life.
See also a short thread on the spec mailing list on this topic: http://lists.openid.net/pipermail/openid-specs-ab/Week-of-Mon-20150209/005229.html
To understand the possible relationships between Response Types and Grant Types see IdentityServer4\Constants.cs
public static readonly Dictionary<string, string> ResponseTypeToGrantTypeMapping = new Dictionary<string, string>
{
{ OidcConstants.ResponseTypes.Code, GrantType.AuthorizationCode },
{ OidcConstants.ResponseTypes.Token, GrantType.Implicit },
{ OidcConstants.ResponseTypes.IdToken, GrantType.Implicit },
{ OidcConstants.ResponseTypes.IdTokenToken, GrantType.Implicit },
{ OidcConstants.ResponseTypes.CodeIdToken, GrantType.Hybrid },
{ OidcConstants.ResponseTypes.CodeToken, GrantType.Hybrid },
{ OidcConstants.ResponseTypes.CodeIdTokenToken, GrantType.Hybrid }
};
Your thoughts about Authorization Code Flow and Implicit Flow are right.
But I think you are over-complicating the hybrid flow. When using hybrid you just simply can get both code and id_token.
After that, either you can grab code and exchange it for access token or just use the id_token (or access token) directly. Both approaches have their own flaws, especially in terms of security.
https://medium.com/#darutk/diagrams-of-all-the-openid-connect-flows-6968e3990660#9401
6. response_type=code token
When the value of response_type is code token, an authorization code
and an access token are issued from the authorization endpoint, and an
access token is issued from the token endpoint. In addition, if openid
is included in the scope request parameter, an ID token is issued from
the token endpoint, too.
Both the authorization endpoint and the token endpoint issue an access
token, but the contents of the access tokens are not always the same.
Regarding this, “3.3.3.8. Access Token” in OpenID Connect Core 1.0
says as follows:
If an Access Token is returned from both the Authorization Endpoint
and from the Token Endpoint, which is the case for the response_type
values code token and code id_token token, their values MAY be the
same or they MAY be different. Note that different Access Tokens might
be returned be due to the different security characteristics of the
two endpoints and the lifetimes and the access to resources granted by
them might also be different.

{"error":"invalid_client","error_description":"The client credentials are invalid"} in fosoauth bundle

I tried to to use the FOSOAuthServerBundle for authenticating the users respective to their access token.
I did all the settings as per the link: http://blog.tankist.de/blog/2013/07/17/oauth2-explained-part-2-setting-up-oauth2-with-symfony2-using-fosoauthserverbundle/
As an output I receied the client id and the client secret key but I am confused about the grant_type..what values does it hold??
And while running this in browser: http://external.apostle.digibiz.com/web/app_dev.php/oauth/v2/token?client_id=1k1x8xpqbjnogs88cso0gwwk4848oocsscsgwcwowcck4840s8&client_secret=3ntf3p6h6c6c04g4o08ggkgcwc0co0sk804gwckow88g0ggck0&grant_type=client_credentials
the following is given as error:
{"error":"invalid_client","error_description":"The client credentials are invalid"}
How can I solve this error????
You can find list of supported grant types at oauth2 repo in class OAuth2. Here are they:
/**
* Grant types support by draft 20
*/
const GRANT_TYPE_AUTH_CODE = 'authorization_code';
const GRANT_TYPE_IMPLICIT = 'token';
const GRANT_TYPE_USER_CREDENTIALS = 'password';
const GRANT_TYPE_CLIENT_CREDENTIALS = 'client_credentials';
const GRANT_TYPE_REFRESH_TOKEN = 'refresh_token';
const GRANT_TYPE_EXTENSIONS = 'extensions';
Grant type specifies how client can be authenticated in application. Detailed explanation can be found in OAuth2 spec but it's spread around the document. Precise meaning of each grant type based on my knowledge of OAuth2 Server bundle:
authorization_code - client is identified and authenticated by code parameter obtained earlier from server
password - client is authenticated by user's credentials: user and password
client_credentials - client is authenticated by it's own credentials (the ones you've provided during client creation)
implicit - one step authentication. Not recommended unless you know what you're doing
refresh_token - client is authenticated by refresh token provided in original authentication. OAuth token issued earlier becomes invalid
extensions - ???
You can provide more than 1 grant_type per client. Also I recommend you to read great article OAuth2 Simplified

Resources