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

[Feature Request] HYBRID SPA Integration with IdWeb #1528

Closed
gladjohn opened this issue Nov 11, 2021 · 16 comments
Closed

[Feature Request] HYBRID SPA Integration with IdWeb #1528

gladjohn opened this issue Nov 11, 2021 · 16 comments
Labels
enhancement New feature or request Spec'd web app
Milestone

Comments

@gladjohn
Copy link
Contributor

Feature is described here: https://identitydivision.visualstudio.com/DevEx/_git/AuthLibrariesApiReview/pullrequest/3922?_a=files&iteration=17&base=16

Feature has already been implemented in MSAL.Net. Work to be done for ID WEB

  • Add Hybrid SPA feature
  • Add Unit tests
  • Add Integration tests

This is a tracking item for adding feature to ID WEB

MSAL ,Net PR : AzureAD/microsoft-authentication-library-for-dotnet#2981

@gladjohn gladjohn self-assigned this Nov 11, 2021
@gladjohn gladjohn changed the title Integration with IdWeb HYBRID SPA Integration with IdWeb Nov 11, 2021
@jmprieur
Copy link
Collaborator

Thanks @gladjohn
Before we start on this, let's make sure we have the OWIN sample.

@gladjohn
Copy link
Contributor Author

Sure @jmprieur tracking item for sample AzureAD/microsoft-authentication-library-for-dotnet#3006

@bgavrilMS bgavrilMS changed the title HYBRID SPA Integration with IdWeb [Feature Request] HYBRID SPA Integration with IdWeb Nov 12, 2021
@bgavrilMS bgavrilMS transferred this issue from AzureAD/microsoft-authentication-library-for-dotnet Nov 12, 2021
@jmprieur jmprieur added the enhancement New feature or request label Nov 13, 2021
@jmprieur
Copy link
Collaborator

jmprieur commented Dec 1, 2021

Proposed design:

  • Add a boolean requestSpaAuthCode in MicrosoftIdentityOptions
  • in TokenAcquisition.cs, add a call to WithSpaAuthCode to AcquireTokenByAuthorizationCode if requestSpaAuthCode is present, and when receiving the auth code from the AuthenticationResult, and store it in the session (for instance as SpaAuthCode): HttpContext.Session["SpaAuthCode"] = spaAuthCode;

In the controller the applications could retrieve the auth code from the HttpContext.Session["SpaAuthCode"], and pass it to the HTML page. and remove it from the session.

@jmprieur jmprieur added the Spec'd label Dec 1, 2021
@Grovespaz
Copy link

Grovespaz commented Feb 4, 2022

Hi, I was wondering if this issue is still on your roadmap?
I'm also wondering if there is a way we can accomplish this today already when using IdWeb, perhaps with a less ideal workaround?

@jmprieur
Copy link
Collaborator

jmprieur commented Feb 5, 2022

@Grovespaz. It's still on the roadmap.
How urgent is it for you?
cc: @jennyf19

@Grovespaz
Copy link

@jmprieur we could use it very much starting today already.

Our use case is a privileged SPA whose source can not be accessible to the public, only to authenticated users. But once loaded, the SPA does all the heavy lifting itself and thus uses MSAL.js.

So it would be ideal for us if we could have the backend use IdWeb to authenticate and authorize and then pass the authorization to MSAL.js to prevent a second redirect to AAD whenever possible.

Thanks for your time.

@jennyf19
Copy link
Collaborator

jennyf19 commented Feb 9, 2022

@Grovespaz
Can you try this branch which has the support for hybrid spa?

You need to add the following in your Startup.cs:

services.AddSession(options =>
 {
            options.Cookie.IsEssential = true;  // if this is not included, the session is not maintained
});

In Configure:

...
app.UseSession();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
...

In the Controller, get the spa auth code:

var code = HttpContext.Session.GetString(Constants.SpaAuthCode);

@Grovespaz
Copy link

@jennyf19 Thanks for getting back to me so soon with this!
I tried out the branch. Configuring it was easy (had to remember to do options.WithSpaAuthCode = true; too), it works great at first try.

One thing I did notice was that when I stopped the project (to make a change) and restarted it again, I would remain logged in to the backend but the session would no longer contain the spa code, leading to (what feels like a) spurious login redirect through MSAL.js in the frontend.

Additionally if I did have a code, when I refreshed the page it would try to use the same code from the session to acquire a token in MSAL.js but the request would fail with AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token, which was not what I expected but makes sense in a way. Is it possible for the backend to re-acquire this token as needed or is it the responsibility of the frontend to redeem the code when first seen and store the resulting token itself? Should a developer clear the code from the session after first use?

I'll continue working with this to make sure it covers everything we need, but I thought I'd give you my preliminary feedback already as you were so quick and helpful in responding to me too.

@jmprieur
Copy link
Collaborator

@Grovespaz the spa code should be removed from the session anyway once you have redeemed it. It's only usable once.
hence the error you get (AADSTS54005),
Your question is more for the JavaScript team: @EmLauber @pkanher617 ?

@EmLauber
Copy link

Adding @jasonnutter who might have thoughts. You are welcome to open this issue on MSAL.js library so we can track there:
https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/new/choose

@jasonnutter
Copy link

Is it possible for the backend to re-acquire this token as needed or is it the responsibility of the frontend to redeem the code when first seen and store the resulting token itself? Should a developer clear the code from the session after first use?

@Grovespaz It is the responsibility of the backend (MSAL.net / MS Identity Web) to acquire the spa authorization code and provide it to the frontend (MSAL.js), and then MSAL.js will redeem that for its own set of tokens (including an RT which can be used to get more tokens). Once the spa has loaded, it doesn't need another spa authorization code from the backend, as it can get its own authorization code (i.e. once the RT has expired). MSAL.js will not cache/store the spa authorization code once it has been used.

And if the user has already logged in (i.e. have already redeemed the spa auth code), they do not need to go through the hybrid spa flow a second time.

@Grovespaz
Copy link

Perfect, thank you all.

That just leaves me to (dare) ask when you expect this to land in an official release. 😊 If anything meaningful can be said about that already, of course.

@jennyf19
Copy link
Collaborator

@Grovespaz I can aim to get it out Monday (2/14)

@jennyf19
Copy link
Collaborator

Just catching up on the thread :/

@jennyf19
Copy link
Collaborator

@Grovespaz 1.23.0 with Hybrid Spa support is available on Nuget. https://www.nuget.org/packages/Microsoft.Identity.Web/1.23.0

@jennyf19 jennyf19 added this to the 1.23 milestone Feb 15, 2022
@VictorioBerra
Copy link

Why would the backend for front end pattern not suffice for this use-case?

IE: The confident client authenticates the user, YARP could then be configured to proxy the requests, after appending the bearer token to the request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Spec'd web app
Projects
None yet
Development

No branches or pull requests

7 participants