AWS cognito: "Access token does not contain openid scope" - oauth-2.0

I got this issue while trying to fetch user attributes from AWS Cognito.
I can't tell how it can be an "Invalid Token" because I have copied and pasted it, also I have make sure that it's the accessToken not idToken or anything else.
There are some other similar questions on this site but they don't address my issue:
"Access token does not contain openid scope" in AWS Cognito
Access token does not have the openid scope
Update: here my app client config

OK, I got you detail.
Short answer: You must use oauth2 Cognito authentication instead of using default Cognito authentication API in SDK.
Let me explain why you meet error: You're using Cognito authentication, then Cognito return to you an "access token" that not contains "openid" scope, you can paste the Token here to check: https://jwt.io/#encoded-jwt.
You have to use oauth2 authentication to get the "access token" that contains "openid". In order to do it, you have to use Hosted UI or AUTHORIZATION Endpoint to get the "access token".
You can try Hosted UI by access link (pls edit your domain + response_type + client_id + redirect_uri): https://tsunami.auth.us-east-2.amazoncognito.com/login?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_SIGNIN_URL
You can use AUTHORIZATION Endpoint: https://tsunami.auth.us-east-2.amazoncognito.com/oauth2/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_SIGNIN_URL&identity_provider=COGNITO and it will redirect to Hosted UI

Getting user info is an open id connect feature and requires the openid scope in the token.
I suspect the problem originates from not specifying this scope when you authenticated and got the token.
Usually you configure scopes such as these when authenticating:
openid profile email
You also provide these in the OAuth Client trust entry configured in Cognito
The profile scope enables you to get the user name from the user info endpoint
The email scope enables you to get the email from the user info endpoint
See step 9 of my write up for an example

Related

Google open id connect

I'm trying to secure my endpoint using open Id connect. Currently there is only a mobile app client. With Google as the Identity provider, I have Id_token and access_token.
My question is can I use this access token returned as a part of authentication to authorize user to access my endpoint?
If yes, Is there a way to validate the access token within my server?
Or Should I create an access token for the user and store the same, so that when the user requests, I will check in the DB/Redis ?
OpenID connect is an Authentication layer on top of the "Authorization" framework OAuth 2.0. So the Access Token is the "Authorization" for the OAuth Client to access the resource.
Perhaps this post may help.
As #jwilleke mentioned, OAuth2.0 doesn't specify a way in which an access token can be validated with Authorization server.
Hence the approach that I took was to verify the JWT Id token by checking the signature of it and storing the access token returned along with it.

Can i use AWS cognito to provide a open id connect endpoint?

I want to use AWS cognito as a OpenId connect provider.My AWS cognito IDP will intern call my another OpenId provider to authenticate the user. It will then create its new token and hand over to callers as its own.
The OpenID provider used internally by AWS cognito pool is transparent to user. User only configures AWS cognito as its IDP provider.
User case
User authenticates with My AWS IDP provider
My IDP provider authenticates the user agains Googles IDP provider
My IDP decodes the token returned by Google IDP.
My IDP Creates new token and add additional claims.
My IDP hands over my JWT to user.
Question
Is this possible in AWS cognito?
Does AWS user pool expose OpenID connect endpoint?
Cognito does provide an OpenId connect endpoint, as detailed in this blog post by #Badri
The formula for the authority is:
https://cognito-idp.{region}.amazonaws.com/{userPoolId}
And you can verify by checking the metadata URL that something is there
https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/openid-configuration
Then during client pool setup, you can federate with other OIDC providers, and also enable the OIDC provider in the app client settings. Which should enable your scenario which sounds very similar to what I would like to do. However, the blog post misses one crucial piece of configuration, which is setting a domain name for the app integration. This StackOverflow question shows the error you will receive if you do not configure this domain and links to the solution in an answer. Once I set the domain, Badri's code worked for me.
To give a more detailed answer on Cognito's OpenID Connect support.
Discovery Endpoint
Cognito exposes an OpenID Connect Discovery endpoint as described at https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest at the following location:
https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/openid-configuration
Response Types
The above endpoint returns the following three response_types:
"response_types_supported":["code","token","token id_token"]
code: defined in https://www.rfc-editor.org/rfc/rfc6749#section-11.3.2 - this worked for us, but only when a domain was specified as below.
token: this value is forbidden by OpenID Connect at https://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest - "NOTE: While OAuth 2.0 also defines the token Response Type value for the Implicit Flow, OpenID Connect does not use this Response Type, since no ID Token would be returned." - OpenID Connect libraries will ignore this response.
token id_token: this value triggers a redirect to an error page with the code "invalid_request". There is no indication given as to what is invalid with the request. AWS technical support claim that only "code" and "token" are supported by authorize endpoint, it is however not clear why this response_type is advertised if not supported.
Domain
Cognito gives the option to specify a domain that will prefix the hostname of the Cognito endpoint.
Without a domain being specified, Cognito will advertise generic URLs at the OpenID Connect discovery endpoint such as https://cognito-idp.eu-west-2.amazonaws.com/{userPoolId}/authorize, but all attempts to log in at these URLs return the error message:
{"code":"BadRequest","message":"The server did not understand the operation that was requested.","type":"client"}
The error message does not indicate what is bad about the request, so this appears to be a bug in Cognito.
With a domain specified, Cognito will advertise URLs that include the domain prefix, and the response_type "code" returns a login page as expected.
Logout
OpenID Connect Session Management at https://openid.net/specs/openid-connect-session-1_0.html#RPLogout describes how an OpenID Connect logout must be initiated, and requires as per https://openid.net/specs/openid-connect-session-1_0.html#OPMetadata that the end_session_endpoint parameter be included in the discovery metadata.
In the case of Cognito end_session_endpoint is omitted from the metadata.
RP-Initiated Logout at https://openid.net/specs/openid-connect-session-1_0.html#RPLogout describes how the logout endpoint works. If an attempt is made to pass the logout endpoint manually to the OpenID Connect client implementation, logout fails as follows:
{"code":"BadRequest","message":"The server did not understand the operation that was requested.","type":"client"}
Again, the error message gives no indication of the error, however the description of the logout endpoint at https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html shows no compatibility with OpenID Connect.
While you can log into Cognito using OpenID Connect, there is no option to log out.
Cloudformation
Cognito Cloudformation support is incomplete, and affects OpenID Connect as follows:
There is no way to specify a domain using Cloudformation, and the domain is required for OpenID Connect to work.
The callback URL is required by OpenID Connect, but cannot be set using Cloudformation.
Summary
To access Cognito using OpenID Connect, ensure that a domain is specified, and use the response_type "code" only. OpenID Connect logout is not possible. Other options violate the OpenID Connect specification, or were released broken.
I'm having a little trouble following your use case, but I'll explain some points that might help.
You can use Cognito User Pools to authenticate users through Google, and then issue JWT tokens from the Cognito User Pool. See the Developer Guide.
Cognito User Pools is not currently a full OpenID identity provider, but that is on our roadmap. User Pools do support OAuth2.0 flows, and they do provide OpenID standard JWT tokens.

OAuth Authorization without login

I've been requested by a client to incorporate OAuth authentication within a REST service. The setup I am working with is client/user accessing a service directly. The service is not connecting to another service. I was asked to have OAuth implemented so that users/clients are authenticated by supplying the username and password in the authorization request and not have them log in via a web page. My client has read information from other sites like paypal (https://developer.paypal.com/docs/integration/direct/paypal-oauth2/) which lead him to believe this was possible. So my underlying question is how do I configure an Authoirzation Server to allow for authorization when supplied a password and username directly?
Peter
The flow is called "Resource Owner Password Credentials Grant" and described in 4.3. Resource Owner Password Credentials Grant of RFC 6749 (OAuth 2.0).
In this flow, a client accesses the token endpoint without accessing the authorization endpoint. So, check the configuration of the token endpoint of your authorization server.

DocuSign OAuth Flow

I am implementing DocuSign's OAuth flow by following OAuth2 Authentication Support in DocuSign REST API
According to the documentation, in order to carry out the OAuth Token Request the client application should show a UI to prompt the user for email/password and is responsible to keep the information confidential and not store it locally.
I would like to know if DocuSign supports OAuth in the manner where the client application does not take hold of the user's email and password and is just concerned with the authentication token of the user.
The DocuSign Developer Center has some info on the OAuth process on their SOBO (Send-On-Behalf-Of) feature page. Check out Explore -> Features -> SOBO.
It's pretty easy to request an access token, just make the following call:
URL
https://{server}/restapi/{apiVersion}/oauth2/token
METHOD
POST
BODY
grant_type=password&client_id={IntegratorKey}&username={email}&password={password}&scope=api
For the body make sure you replace IntegratorKey, email, and password with your credentials.
A successful call will generate the following response:
{
"access_token": "<access token for user>",
"scope": "api",
"token_type": "bearer"
}
And finally, you can then use that access token in subsequent api calls using the Authorization: bearer header like so:
Authorization: bearer <access_token>
One important thing to remember is that you are only allowed 10 OAuth tokens in your account (which can be seen on the Preferences -> Connected Apps screen in the DocuSign Console). If you have 10 and request a new token the call will fail, you'll need to revoke an existing one in that case if you want to create a new one.
According to the DocuSign documentation, it supports two grants: (1) the Resource Owner Password Credentials Grant and (1) the SAML2 Grant, which is an extension to the base OAuth2 spec. Neither of these grants issue an authentication token. In the first grant, the resource owner must share his credentials with the client application. In the second grant, the resource owner approves access by the client application in advance. The client app generates a SAML assertion which is validated by the authorization server and (if the assertion is valid) is issued an access token.
The authentication token is used only by the Authentication Code Grant which, according to the DocuSign documentation, is not supported.

Google Federated Login (OpenID + OAuth 2)

I'm trying to get OpenID working with OAuth 2 for using Google's API. I only want the user to have to "grant access" once when they login for the first time. Here is the flow I have so far:
User clicks "Login with Google"
My server signs in the User with OpenID. With federated login I receive an OAuth Request Token.
From https://developers.google.com/accounts/docs/OpenID#oauth it says the next step is to exchange the request token for an access token. However, I see a couple problems with this:
It is an OAuth 1 API call.
It requires a verifier. Don't I need the user to "grant access" to receive the verifier? How is this federated?
Thanks for any help!
You should use OAuth 2.0 based authentication:
https://developers.google.com/accounts/docs/OAuth2Login
This is also referred to as OpenID Connect.
This will redirect to your site with an authorization code. You then exchange that for an access token. You can validate the access token by calling the TokenInfo endpoint with a simple REST request. This will give you a simple userid identifier.
After, you make a call to get the detailed profile information, such as name + email, etc.
You can see more about how it works with this great demo:
http://oauthssodemo.appspot.com/

Resources