Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to obtain “B2C JWT Access Token” from the signed in User? #11424

Closed
AndrePaulVigneault opened this issue Jun 20, 2019 · 9 comments
Closed
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer

Comments

@AndrePaulVigneault
Copy link

I'm working with a .Net Core Web API and a .Net Core Web MVC Application. They both use Azure AD B2C to authenticate users. But in order to get a response from a HttpRequest from the Web API I need to provide the JWT Access Token from B2C for the signed in user on my web MVC application. Is there a way to obtain this access token inside a controller using the authenticated "User".

I have tried accessing the claims of the signed in user but no luck there, I have also used jwt.ms to review that the B2C workflow works well and that the JWT token is being generated and it works as well. The MVC application is authenticating the user and the web API is working fine with a hardcoded token. I just need to obtain the access token from a signed in user rather than doing it hardcoded.

I expect to be able to get the B2C JWT access token so that I can later on pass it to the Web Api and be able to secure my requests.

@Eilon Eilon added the area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer label Jun 20, 2019
@blowdart
Copy link
Contributor

The token you get to login to the web application is limited to that function, logging into the web application (this is what the audience field is for). It's not supposed to be passed on anywhere else. You would use that token to ask for another token to access another service?

Is your web api within the same application, or is it another application?

@AndrePaulVigneault
Copy link
Author

Thank you for the fast response @blowdart , the api is a separate application that accepts two audiences(api itself, and this mvc app audience).

@blowdart
Copy link
Contributor

Oh you're really abusing audiences here, really the web site should ask for a token to access the api.

However, @Tratcher where did savetokens go?

@Tratcher
Copy link
Member

You need to get to the lower level options:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/azure-ad-b2c?view=aspnetcore-2.2#configure-the-underlying-openidconnectoptionsjwtbearercookie-options

@blowdart
Copy link
Contributor

Aha, so @AndrePaulVigneault in

services.Configure(
AzureAD[B2C]Defaults.OpenIdScheme, options =>
{
// Omitted for brevity
});

There should be a SaveTokens property, which will turn the access and refresh tokens into claims

@AndrePaulVigneault
Copy link
Author

That's definitely helpful, I'll try it out, thank you for the answer.

@ryancole
Copy link

ryancole commented Jun 21, 2019

@blowdart and @Tratcher Thanks so much for helping us out here. I'm working with @AndrePaulVigneault on this project. I believe he is trying out your recommended bit of code, etc, so thank you for that pointer.

I've coded the HTTP API server that he's trying to make requests to and I saw your remarks about audiences. I'm new to the B2C workflows and the concept of audiences, and such, in general, and so I did have an off-topic follow-up about audiences if you have the time to answer. It'd help to educate me on the proper integration of all of these parts.

Originally the API site that I'm coding only allowed one audience - the API site's B2C application ID. As I understand it, this was like saying the API site expects tokens only from folks who have gone through a B2C policy specifically for this API site.

Once Andre was at a point where his MVC web site was needing to make requests to my API web site, he already had authenticated against B2C for his use. So, our logic was that if he could locate his B2C JWT token, he could just use that in his requests to my API site. All I would have to do is add his MVC site's B2C application ID to the list of valid audiences.

I did this because it seemed to make sense considering the B2C policies can run against any application registered on B2C, and saying that his MVC site was a valid audience kind of make sense in the in the context of how it read in plain english anyway - "users of his MVC site are also acceptable users of the API". (very plain way of thinking haha)

But I see your remarks and now I understand that it does sort of seem like an abuse of the system. So I want to ask if you could validate what I now understand as being the correct workflow? Which is ...

I should add an endpoint to my API to allow folks to request a token. My site would need to create a valid B2C token for them. They could then use that token to access the rest of API site. Andre's MVC site does not have a user password, though - how would it provide a means of authentication to my API site?

or ...

Andre's MVC site needs to somehow ask B2C for a token to my API site? He would not need password, but can his application requests tokens for a different application?

Thanks!

@blowdart
Copy link
Contributor

This isn't a B2C issue, this is an oidc issue, and as such I'm not really the expert in this, so asking advice from the B2C folks or OIDC experts may be better.

But how I think I understand it is you register the token issued to the MVC app is meant for the MVC app, if the MVC uses it to authorize. When the MVC app wants to call the API it either

  1. Authenticates as service to service, and passes the identity information on in a header or parameter, and as you trust the service in the api, you trust the forwarded authentication

or

  1. The MVC app goes back to the OIDC server and says "Hey this login token I have, can I have one that gives me access to this service" (services being identified by scopes). You're doing "on behalf of".

@AndrePaulVigneault
Copy link
Author

@blowdart , @Tratcher thank you so much for the help, you were completely right with the pointer. I'll add a snippet of code here for future references.

Startup.cs:
services.Configure(AzureADB2CDefaults.OpenIdScheme, options => {
options.SaveTokens = true;
});

Controller:
string idToken = await HttpContext.GetTokenAsync("id_token");

@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer
Projects
None yet
Development

No branches or pull requests

5 participants