I have a requirement, where App1 does the authentication with Azure B2C, and passes "RefreshToken" to App2, App2 needs to acquire Access and Id tokens using only that refresh token. The purpose of App2 is to generate cookies that gets generated when using msal lib.
I see msal library has a method "acquireTokenSilent" but this method fetches refreshtoken behind the scenes (using cookies etc), but App2 doesn't have any information other than "RefreshToken" that is passed to it.
Is this possible to achieve, I called /token endpoint using postman and was able to acquire tokens by passing refresh_token. I am wondering if there's an equivalent method in msal library.
TIA
Related
I am trying to implement the BFF-Gateway pattern (no tokens in the browser) to be used with a React SPA. The BFF is using AddMicrosoftIdentityWebAppAuthentication to handle login and issue a cookie to the SPA. And it is using YARP to proxy api requests to a downstream api. I'm using Azure B2C. Everything works perfectly until the BFF id_token expires in 1 hour. At that point, fetching the downstream api access token via GetAccessTokenForUserAsync (which is called in a piece of middleware) fails:
var scope = _configuration["CallApi:ScopeForAccessToken"];
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { scope });
ctx.Request.Headers.Add("Authorization", "Bearer " + accessToken);
Exception:
IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user. See https://aka.ms/ms-id-web/ca_incremental-consent.
ResponseBody: {"error":"invalid_grant","error_description":"AADB2C90085: The service has encountered an internal error. Please reauthenticate and try again.\r\nCorrelation ID: 622d6bd6-d06e-4142-86f2-b30a7a17b3b5\r\nTimestamp: 2022-11-25 09:31:23Z\r\n"}
This is effectively the same as Call Downstream API Without The Helper Class example and this sample, except that I'm acquiring the access token in middleware, not a controller, so the downstream YARP requests contain the access token. BTW I get the same error if I do this inside a controller per this example. And I see no soluton to this in the sample.
There is a similar question here which references the sample referenced above, but for the B2C sample I see no solution to this problem.
I also found this sample and this explanation. But this uses Microsoft.Owin to configure auth, not AddMicrosoftIdentityWebAppAuthentication. This looks promising, but is a departure from most examples I see that use Microsoft.Identity.Web.
Can you please point to the correct soluton? I need call to be able to call _tokenAcquisition.GetAccessTokenForUserAsync after the id token expires without asking the user to reauthenticate and/or the SPA to having to reload.
At the moment I am handling this issue in the SPA by catching the exception from MSAL and redirecting back to the login endpoint in the BFF which initiates the challenge. This gets me a new id_token and cookie, but this is just a temp workaround as it's very disruptive to user to be redirected away from the SPA.
I have an api written in GO that, at the moment, serves an authorization token based on a username and password. (Without MSAL)
I am trying to implement MSAL logins with Microsoft accounts. I have setup my angular frontend to log a user in to an Azure AD app registration. Would it be possible to authenticate that they have successfully logged in to the Azure AD, and serve them one of my tokens (unrelated to msal) from my GO API?
The username that they use to login with MSAL also exists in my backend, the flow would be something like this;
User logs in with MSAL -> my frontend makes a request to golang backend with username -> golang verifies that this username has logged in with MSAL -> backend serves a token for this user
It appears golang integration with MSAL is limited, so not sure how possible this is.
Thanks.
What you can do is acquire an access token for your API in the front-end from Azure AD. For this you will either register the API in Azure AD or use the same app registration. Either way, you should add a scope in the Expose an API page in the registration. Your front-end can then use that scope's id to get the needed token.
Your API can then have an endpoint that validates the access token, and issues the local token. The access token will contain the user's username for example, if you want to map to that. A more robust way would be to map to the user's object id (also in the token) since it is immutable, unlike the user email.
For token validation, you should be able to use a generic JWT validation library. Also remember to check for that scope in the token that you defined to properly authorize the request.
I'm currently using Keycloak 9.0.0. When authenticating using the code flow and exchanging this code, I'm receiving an id token without the at_hash claim.
How do I configure Keycloak to include an at_hash claim in the id token?
Background:
I'm using a "classic" server side rendered (SSR) program, a confidential client.
I'm sending requests to my local http api. But I also have an Angular client. The SSR is a Go programm using github.com/coreos/go-oidc.
Rendered pages that require authentication redirect the visitor to keycloak and back via the redirect_uri.
Since the visitor is logged in its id token is present in the session and I also pass the access token. However the id token has no at_hash claim and thus access token validation fails.
I also have a mobile web version of this site, in Angular and it sends a bearer access token once logged in. This app uses the code flow + pcke.
Both should be able to send authenticated requests, but since I'm using pretty much the only oidc client library for Go available, it requires an at_hash claim being present in the id token to be able to verify access tokens. The package currently has no support for the introspection endpoint.
Both id token and access token are returned from the IDP. But neither has an at_hash claim.
According to OIDC at_hash is mandatory only when access token is issued.
Make sure you are using response_type=id_token token and not response_type=id_token.
I have three applications: REST API with Resource Server, Authorization Server and javascript client on VueJs that should use REST Api. Problem in using access token that I get after authorization. First I decided to use local storage or cookie for storing access token, but as I read It's not secure. It's recommended to use cookie with httpOnly, but I can't to access from js. Addition token in url params as well not right way. So what I should to do for using my Rest Api? I'm using Authorization Code grant flow.
When you have a Javascript client, the client itself should act as an OAuth2 client.
Meaning, the server is not what gets the token. The client, the javascript application in the browser, will fetch the token from the authorization server.
You achieve this by using a grant type called implicit.
In this grant type, there is no client_secret, but you must have a valid client_id. You will also not receive a refresh token. But you can receive access tokens and id_token (if you have an OIDC server).
Your question hints at you doing a server side grant (authorization_code,password,etc) and then sending that token to the javascript client. This would be incorrect.
For a great description of OAuth2, we have published this video: https://www.youtube.com/watch?v=u4BHKcZ2rxk
Your JavaScript application would do this:
Do I have a valid token? No
Start implicit grant
Receive token from authorization server
Store token in memory var token = ....
Use the token to invoke API endpoints on the server
Repeat step 5 until token is no longer valid
Go back to step 1
Next step for you is to watch the video and learn more about implicit grant type
As you already guessed, going down the road of getting a token on the server and then sending it to a non secure client exposes your applications in ways you probably do not want.
I am using the OAuth capability in Azure Bot service to access the Microsoft Graph.
I have the need to communicate with the SharePoint Online REST endpoint. Typically, I would request and cache a refresh token from AAD, then use that refresh token to acquire a second access token, specifying the sharepoint.com address as the resource.
When using the OAuth connections in the Azure Bot service, I can get an access token by calling the GetUserToken method of the dialog context. However, I cannot get the refresh token from the bot service.
Q: Is the refresh token exposed as part of the BotBuilder library, or in some other fashion?
You must include the offline_access scope on your OAuth Bot configuration and on bots API permission within your Azure bot registration (Go to AAD - Application Registration (Preview) - API Permission).
Otherwise the bot service will not be able to refresh the token when it expired after 60 minutes by default.
For more information's on scopes see here.
Further explanation:
Without the offline_access scope included in the token request, the refresh token is not submitted and only an access token is provided. With the scope included, a refresh token will be provided to the caller which (in this case the bot service) can use to acquire a fresh token at any point until the refresh token itself expires.