AzureAD / microsoft-authentication-library-for-js

Microsoft Authentication Library (MSAL) for JS
http://aka.ms/aadv2
MIT License
3.65k stars 2.65k forks source link

Question: How to leverage SSO capabilities of MSAL.js when not signed in through MSAL #340

Closed jhossy closed 6 years ago

jhossy commented 6 years ago

Hi

I have digged through the issues here and also on Stackoverflow, but there is an issue that remains unanswered to me.

Is it possible, for users to sign in using for example a Web App that integrates with Azure B2C AD and afterwards be signed into a SPA that uses the MSAL.js library?

When I attempt that and perform the loginRedirect() in my SPA, I am always redirected to the login page (which might be related to this issue: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/275).

This is my code that acquires a token, however it seems to always add the prompt parameter (even if the user is already signed in), which kinda defeats the SSO experience:

clientApplication = new Msal.UserAgentApplication(
    tenantConfig.clientID, 
    this.authority, 
    function(errorDesc: any, token: any, error: any, tokenType: any) {
        console.log('calling acquireTokenSilent with scopes: ' + tenantConfig.b2cScopes);
        console.log('idtoken: ' + token)
        if (token) {
            this.acquireTokenSilent(tenantConfig.b2cScopes).then(function (accessToken) {
                console.log('acquireTokenSilent');
                sessionStorage.setItem("b2c.api.access.token", accessToken);
            }, function (error) {
                console.log(error);
                this.acquireTokenPopup(tenantConfig.b2cScopes).then(function (accessToken) {
                    console.log('acquireTokenPopup');
                    sessionStorage.setItem("b2c.api.access.token", accessToken);
                }, function (error) {
                    console.log(error);
                });
            });
        }
        else if (errorDesc || error) {
            console.log(error + ':' + errorDesc);
        }
    },
    { 
        logger: this.logger,
    });
jhossy commented 6 years ago

Maybe my setup is unclear, so let me try to explain it again:

a) 1 Web application written in .NET 4.5.1 or later that utilizes the Microsoft.Owin and Microsoft.Owin.Security.OpenIdConnect NuGet packages (see code below)

b) 1 Single Page Application that uses MSAL.js to communicate with Azure B2C AD

When I signin, in the web application, a), and open a new tab with the SPA, I need to also be signed in to the SPA.

Currently, it seems to work when I first signin to the SPA and the visit the web application, but not the other way around.

And here is the code from the Startup.Auth.cs:

public void ConfigureAuth(IAppBuilder app)
        {
            app.Map(SsoAuthenticationRootPath, ConfigureSsoAuthentication);
        }

        private void ConfigureSsoAuthentication(IAppBuilder app)
        {
            // After successful sign-in in SSO, the redirect back to this web site will use the cookie authentication middleware to contain the obtained id_token.
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions()
                {
                    CookieName = SsoCookie.CookieName,
                    CookiePath = SsoAuthenticationRootPath, // Scope cookies to the authentication root path in order to avoid having the cookie included in every normal request.
                    TicketDataFormat = new TicketDataFormat(new MachineKeyProtector()) // In order to be able to decrypt the authentication ticket stored in the cookie later on, we use protection based on the machine key.
                },
                PipelineStage.PostAuthenticate
            );

            string policy = B2cConfiguration.Settings.PolicyName;
            app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(policy));
            log.Info(string.Format("Adding client={0}, policy={1}, RedirectAfterLoginUri={2}", B2cConfiguration.Settings.ClientId, B2cConfiguration.Settings.PolicyName, B2cConfiguration.Settings.RedirectUri));
        }

        private OpenIdConnectAuthenticationOptions CreateOptionsFromPolicy(string policy)
        {
            OpenIdConnectAuthenticationOptions options = new OpenIdConnectAuthenticationOptions();

            // For each policy, give OWIN the policy-specific metadata address, and
            // set the authentication type to the id of the policy
            options.MetadataAddress = string.Format(AadInstance, Tenant, policy);

            options.AuthenticationType = policy;

            options.RedirectUri = B2cConfiguration.Settings.ReplyUri;
            options.PostLogoutRedirectUri = B2cConfiguration.Settings.RedirectUri;

            options.Notifications = new OpenIdConnectAuthenticationNotifications()
            {
                AuthenticationFailed = AuthenticationFailed,
                SecurityTokenValidated = SecurityTokenValidated
            };

            // These are standard OpenID Connect parameters, with values pulled from web.config
            options.ClientId = B2cConfiguration.Settings.ClientId;
            //http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
            options.Scope = "openid";
            //http://openid.net/specs/openid-connect-core-1_0.html#Authentication
            options.ResponseType = "id_token";

            return options;
        }
davidkempers commented 6 years ago

This is what I'm after too.

There is a comment by @rohitnarula7176 where he says there is the intention of this but not implemented yet.

@rohitnarula7176 any update on this? Will you accept a PR?

nehaagrawal commented 6 years ago

@davidkempers @jhossy We have implemented SSO in MSA.js and PR is out. We are hoping to release it by next week.

nehaagrawal commented 6 years ago

Fixed and released in msal 0.2.3. Please check our sample here https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-core/samples/VanillaJSTestApp/index_single_sign_on.html

navyasric commented 6 years ago

Please check the SSO wiki page now to see the pattern for this scenario: https://github.com/AzureAD/microsoft-authentication-library-for-js/wiki/Sso