asp.net-mvcazuresignalrowin-middlewareazure-authentication

Is it possible to share AAD authentication cookie between two web applications on the same site


Question Is it possible for a back-end-web-app to accept and pick up the user identity from the AAD authentication cookie generated by signing in to a front-end-web-app?

Background I want to achieve an Azure Active Directory single sign on experience for a JavaScript SignalR client but my current solution requires the user to sign in twice. Once to access the web app hosting the js-client and then again so that the js-client-app can access the back-end.

Desired solution with SSO AAD Authentication

  1. Front-end (OWIN/MVC/JavaScript)
    • AAD authentication to identify the user - implemented
    • JS SignalR client includes the auth cookie in the server requests - works by default
  2. Back-end (OWIN/SignalR PersistentConnection)
    • Identify the user via the the encrypted .AspNetCookies cookie from the front-end authentication that is included in the SignalR requests.
    • the cookie is not accepted and the debug output from OWIN is Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware Warning: 0 : Unprotect ticket failed

Attempted Back-End Startup.cs

public void ConfigureAuth( IAppBuilder app )
   app.SetDefaultSignInAsAuthenticationType( CookieAuthenticationDefaults.AuthenticationType);
   app.UseCookieAuthentication(new CookieAuthenticationOptions());
   app.UseOpenIdConnectAuthentication(
       new OpenIdConnectAuthenticationOptions
           {
              ClientId = clientId,
              Authority = authority,
              RedirectUri = redirectUri,
              PostLogoutRedirectUri = redirectUri,
              TokenValidationParameters = new TokenValidationParameters
              {
                 RoleClaimType = "roles"
              }
            });
}

Current solution with undesirable dual sign in

  1. Front-end web app (OWIN/MVC/JavaScript)
    • Owin handles AAD authentication
    • MVC generates views based on the authenticated user
    • ADAL JS handles user authentication client-side and acquires an access token that is added as a cookie (my_access_token)
  2. Back-end web app (OWIN/SignalR PersistentConnection)
    • OWIN handles authentication by extracting the access token found in the my-_access_token cookie and adding it as a Bearer Authorization header
    • Authorization is handled by overriding the Authorize function in PersistentConnection based on the authenticated user

Current Front-End Startup.cs

public void ConfigureAuth( IAppBuilder app )
   GlobalFilters.Filters.Add( new AuthorizeAttribute() );
   app.SetDefaultSignInAsAuthenticationType( CookieAuthenticationDefaults.AuthenticationType);
   app.UseCookieAuthentication(new CookieAuthenticationOptions());
   app.UseOpenIdConnectAuthentication(
       new OpenIdConnectAuthenticationOptions
           {
              ClientId = clientId,
              Authority = authority,
              RedirectUri = redirectUri,
              PostLogoutRedirectUri = redirectUri,
              TokenValidationParameters = new TokenValidationParameters
              {
                 RoleClaimType = "roles"
              }
            });
}

Current Back-end Startup.cs

public void Configuration( IAppBuilder app ){
   app.Use( ( context, next ) =>
       {
          if (context.Request.Cookies.Any(c => c.Key.Equals("BearerToken")))
          {
            var cookie = context.Request.Cookies.First(c => c.Key.Equals("BearerToken"));
            context.Request.Headers.Add("Authorization", new[] { $"Bearer {cookie.Value}" });
          }

           return next.Invoke();
        });

    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
        new WindowsAzureActiveDirectoryBearerAuthenticationOptions
        {
           Tenant = tenant,
           TokenValidationParameters = new TokenValidationParameters
                                         {
                                             ValidAudience = audience,
                                             RoleClaimType = "roles"
                                          }
        };
     );
}

Solution

  • Yes, It's possible. You need to specify the shared key for cookie encryption & decryption. https://learn.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-3.1

    once your added AzureAd you just inject the shared cookie setting with the shared cookie name and the dataProtectionProvider from the same key in both apps.