Cognito Authorization with Azure AD SAML integration returns id_token and access_token but no refresh token - azure-active-directory

I have a cognito User Pool with 1 client that is configured with 2 identity providers, Cognito User Pool and a SAML provider that links an Azure AD instance. The Allowed OAuth Flows is set Implicit grant only. Login via the Cognito User Pool provider is done using the InitiateAuthCommand in the #aws-sdk/client-cognito-identity-provider library. From this an id_token, access_token and refresh token are all returned.
Login via the SAML provider is done by using the template link provided in the cognito developer docs (https://your_Amazon_Cognito_userpool_domain/authorize?
response_type=code&identity_provider=your-SAML-IdP-name&client_id=your-
client-id&redirect_uri=https://your_application_redirect_url). This login works, however only an id_token and access_token are returned (no refresh token).
How can I get cognito to issue a refresh token for users logged in via the SAML provider

Cognito should not return a refresh token for Implicit grant flow. That is the intended behaviour according to the specification:
The authorization server MUST NOT issue a refresh token.
Also using the implicit flow is highly discouraged due to vulnerabilities.
Please consider using Authorization code grant flow along with PKCE. With that you can get the refresh token.
The reason you get the refresh token along with the aws-sdk is, because it should be using a different Auth flow (example: USER_PASSWORD_AUTH) as mentioned in the document.

Related

ReactJs FE and Django Rest Services with Azure AD for authentication & Authorization

I'm having a Frontend application built in Reactjs connecting to Azure AD using msal for authentication. After authentication, the user needs to click a button which calls a Django rest API which is also authenticated using Azure AD.
React FE and Django connects to two separate App registrations in Azure AD. Even thought 1) FE is added to Django's App registration as known client 2) Django is exposing the API and the scope is given consent.
When the authenticated FE sends requests to the Django Rest service with Bearer token,
it fails to authenticate the request saying 'invalid token'.
I'm able to authenticate FE and Django rest service separately but authenticated FE is not able to connect to the Django Rest service. Please share your thoughts on what else needs to be checked or any solutions.
Please check if any of these configurations can be worked around
Check if you have given your react app’s URL in the redirect URL in portal and code , so that once the Azure AD validates the user and it’ll return back to your react app with ID Token.Also, enable Access Token and ID Token.
Check if you have created a scope for your web api (in Azure Portal > Your API > Expose an API). Then configure it on your client app on the API Permissions menu tab. Then add it on your scopes collection in code settings.Also, add grant admin consent for that API permission.
Check the manifest of your azure ad app: Below value is probably null or one, should be two: If you are using v2.0 endpoint,
"accessTokenAcceptedVersion": 2,
If you are using v2.0 endpoint, the scope should be api://{server_client_id}/.default.
In the code setting.py for your application, you'll need to provide the authority to which your web app delegates sign-in. (ex: authority: 'https://login.microsoftonline.com/(your tenant id>',)
auth: {
clientId: '232a1406-b27b-4667-b8c2-3a865c42b79c',
authority: 'https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb',
//
}
When we perform a token validation, Check your jwt token in http://jwt.io
Audience: The token is targeted for the web API.
"aud" value that is being generated for JWT token by azure is also controlled by "accessTokenAcceptedVersion" property in AD application manifest.(see if issuer or iss has v2 to confirm as v2 endpoint )
If you have set the access token accepted version to 2, then the client id and audience needs to be same (i.e. no need to write api:// in audience)
Note that Implicit flow is the only flow supported for SPA. Authorization code flow is intended for webapps, mobile and desktop apps but not for SPA.Please refer this document
References:
See how to configure Azure AD and how to determine the settings for
django-auth-adfs.
You can check this and find your use case scenario.
Check v2-supported-account-types for authentication-flows
Check OAuth2.0 On-Behalf-Of flow

InvalidRequesMessage error when trying Azure AD IDP initiated SSO - Keycloak

I am using Keycloak 12.0.1 as an identity broker and Azure AD as an identity provider using SAML2.0. I get below error when trying to do IDP initiated SSO -
SP initiated sign-on works fine. The error message is not descriptive enough to find the root cause. I've not setup any client in Keycloak, I want this to work just like SP initiated sign-on in which after successful login, Keycloak profile page is displayed.
Below are links to the metadata -
Service Provider Metadata
SAML Response by Azure AD
Update:
I forgot to mention that Keycloak expects relay-state in IDP initiated sso response (without which Keycloak shows NullPointerException on the server console) but I'm not sure what value I should provide for relay-state here because I've not setup any custom clients. I want Azure AD to redirect to the default client that Keycloak provides (i.e account-console).
I grabbed relay-state from SP initiated sign-on and used the same value for IDP initiated one and the NullPointerException goes away but I get 'InvalidRequesMessage'. So I'm suspecting it has to do with the relay-state value I'm using.

Refresh token flow in Azure Active Directory with a federated Google user

I have set up an Azure Active Directory tenant with direct federation to Google. Next to that I have a .NET core web application using the OIDC code flow for getting both id_tokens and access and refresh tokens. The access token is used to call my API which is working fine.
Now the problem is whenever I use my refresh_token to get a new access_token I receive a new access_token, but no refresh_token. So I can only refresh once.
I only have this issue when authenticating with my Google account using direct federation. When I authenticate using a tenant native account I can refresh unlimited.
We have two multitenant Azure AD app registrations as described here. One for our single page application and one for our API. In our single page application backend we use the OpenIdConnect middleware to authenticate against Azure AD. Note that we are not using the common endpoint, but the tenant specific endpoint because otherwise direct federation does not work. We can reproduce this issue by intercepting the refresh token in the OnTokenResponseReceived event of the OIDC middleware and initiating the refresh flow as stated here (by using Postman for instance). The response is successful, but does only contain an access token, no refresh token.
Is this behavior by design?

Identity Server 4 (with external Azure AD auth) token is not valid in Graph API

I am switching my application from Azure Active Directory authentication to authentication with Identity Server (using Azure AD as external auth). The authentication and authorization part is implemented and my web API successfully validates token and give me what I'm asking.
Our application also uses external APIs, such as Graph API and SharePoint Online which require Azure AD token. E.g. when I go to https://graph.microsoft.com/v1.0/me from my JS application with token that I get back from Identity Server, Graph API response is
401
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token validation failure.",
"innerError": {
"request-id": "ce7651bb-5dc4-49e9-90ff-02df440ed4ad",
"date": "2017-08-11T08:53:12"
}
}
}
I expected that because Identity Server is giving me his token, and not passing the existing token that is provided by Azure AD. I copied all the claims from Azure AD token into identity server token, but no changes.
What would be the right approach to enable my application to continue using APIs which require Azure AD token?
EDIT:
What I'm hoping for is this.
Click login button on Js (or any other client app)
Redirect to Identity Server login screen
Click on Azure AD external auth
Redirect to Microsoft login page and enter your credentials there
Redirect to Identity server app
a. I started Fiddler and see that "Microsoft" redirect to {IdentityServerAppUrl}/signin-aad (I suppose this is because I configured CallbackPath property on OpenID Connect options). This request carry a cookie idsrv.external. I'm not sure but I think inside is access token from Azure AD. I don't know how to decode this. I tried with base64, but it is not working.
b. When this request is finished redirect is made to {IdentityServerAppUrl}/account/ExternalLoginCallback. In this action method I check with debugger all fields and data in request but I can't find token from AAD. I'm hoping to get token and put it in additional calims.
Identity Server app redirect to JS client app with its own token and additional claim that contains Azure AD token that is valid on graph API and SharePoint.
First I would like to locate Action method or middleware that handle {IdentityServerAppUrl}/signin-aad?
Second, is there any way to get token from Azure AD or any other external provider inside {IdentityServerAppUrl}/account/ExternalLoginCallback Action method?
Be aware that I'm new to this kind of stuff and maybe I'm totally wrong with this thinking.
I manage to do Azure AD authentication without Identity Server, but know we have request to have multiple external providers and I'm hoping to handle all authentication in one app. If one day I get request to have additional external provider I need to add to just in one place.
You need to retrieve an access token from AAD for the Graph API - how that exactly works, check the Microsoft documentation.
Once you have that access token, you can return it as a claim in either the IdentityServer identity or access token (depending if you want to make it available to your front or back-end).
You can also try that first in a simple MVC app to remove the moving partsy - and once you have the AD part working, move your code to the app using the identityserver middleware.
I am also looking for an answer to this question. However, I think it should work a bit differently. IdentityServer gives you a JWT that you can use to authorize to the recources that make up your app. E.g.: yourAPI-1 and yourAPI-2. With the JWT you can pass on the identity. Microsoft Graph is an external resource. Therefore we would need the access token form the Graph API as a claim or external resource, same way as you'd receive an access token for an internal resource.
I would guess that there should be a way of forwarding whatever information you get from the identity provider (Azure AD) to IdentityServer for your client (JS app) to pick up. I am facing the same problem here.
There is another thread about this topic that caught my attention which I will look into. It requires to build your IdentityServer from the source with a few modifications: ASP.NET Identity (with IdentityServer4) get external resource oauth access token
I will let you know what the outcome is and push it to a git repo that you can use if it works:

SAML indendity propagation

In my scenario I have the following architecture elements:
- SAML secured Portal (Domain A)
- User
- SAML secured API( Domain B, so different domain than the portal)
- an IdP
The user will login first to the portal, when not authenticated, the portal will redirect him to the identity provider to login. Once logged in to the IdP and hence to the Portal, the Portal will possess a SAML token identifying the user.
Now this portal will need to automatically call the API (present on another domain), and pass to it a SAML token identifying the user. Problem is that the portal only posses the token that has been provided to him, and hence my question:
How can I propagate the identity of the user through the invocation chain?
For instance, is it possible to share same token between different relying parties? If yes, what are the constraints that the issued token should respect to make sure it can be "shared" by different entities?
Many thanks in advance!
One way could be that the portal rather than calling the API directly, instead should redirect the user to the API.
This way the API will find the user doesn't have a valid session, will redirect to the IdP where the user is already authenticated. The IdP will then redirect back to the API with the SAML response for the API.
This will all be transparent to the user, who will just see the result from the API.

Resources