简体   繁体   中英

Replacing Cookie by Token based authentication in ASP.NET OWIN OpenIdConnect code authorization flow

We have a web application written in ASP.NET that uses MVC for serving our Single Page Applications and Web API for ajax calls.

The authentication uses Microsoft.Owin and OpenIdConnect with Azure AD for Authority. The OAUTH flow is server side code authorization. Then in Startup.Auth.cs we have

    public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        var cookieAuthenticationOptions = new CookieAuthenticationOptions()
        {
            CookieName = CookieName,
            ExpireTimeSpan = TimeSpan.FromDays(30),
            AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
            SlidingExpiration = true,
        };
        app.UseCookieAuthentication(cookieAuthenticationOptions);
        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                   AuthorizationCodeReceived = (context) =>
                    {
                        /*exchange authorization code for a token 
                        stored on database to access API registered on AzureAD (using ADAL.NET) */
                    },

                    RedirectToIdentityProvider = (RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) =>
                    {
                        /* Set the redirects URI here*/
                    },
            });
    }

When clicking on signin we navigate to an url whose routes map to the methods of the following MVC controller

public class AccountController : Controller
{
    public void SignIn(string signalrRef)
    {
        var authenticationProperties = /* Proper auth properties, redirect etc.*/
        HttpContext.GetOwinContext()
            .Authentication.Challenge(authenticationProperties, OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
    }

    public void SignOut(string signalrRef)
    {
       var authenticationProperties = /* Proper auth properties, redirect etc.*/
       HttpContext.GetOwinContext().Authentication.SignOut(authenticationProperties,
            OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
    }

Then the end-user connected to our application is authenticated between our client apps and the ASP.net server using an ASP.NET cookie. We would like to use Token Based approach instead . If you are interested this is the reason .

I tried to replace the Nuget package Microsoft.Owin.Security.Cookies by Microsoft.Owin.Security.OAuth and in Startup.cs replacing

app.UseCookieAuthentication(cookieAuthenticationOptions); by app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

and in my AccountController we changed the challenge from HttpContext.GetOwinContext().Authentication.SignOut(authenticationProperties, OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType); to HttpContext.GetOwinContext().Authentication.SignOut(authenticationProperties, OpenIdConnectAuthenticationDefaults.AuthenticationType, OAuthDefaults.AuthenticationType);

The problem is that with Cookie the set-cookie was automatically sent in web request respond when the flow completes while redirecting to the url we specified. Where can I find the Bearer generated by OWIN with UseOAuthBearerAuthentication (if there is any) **, **Where and When should I send it back to my client SPAs

Note: an open source sample of what we are trying to do can be found in this github repository .

I think there are two approaches for you to consider.

  1. Use javascript libraries to perform sign-in & token acquisition within your single page app. Then your backend is purely an web API, and can just use OAuth bearer middleware to authenticate requests. The backend doesn't know anything about signing the user in. We have a good sample that takes this approach here . If your backend needs to make API calls as well, you could consider the OnBehalfOf flow as well. I usually recommend this approach.
  2. Use the OpenIDConnect middleware in your server to perform user sign-in and token acquisition. You might even be able to omit the usage of the CookieAuthenticationMiddleware entirely (although I'm not 100% sure). You can capture the token in the AuthorizationCodeReceived notification as you mention, and you could redirect back to your SPA with the token in the fragment of the URL. You could also have some route which delivers the tokens (which are cached on your server) down to your javascript. In either case, you'll need to ensure that an outside caller can't get access to your tokens.

The thing to keep in mind will be how you refresh tokens when they expire. If you use #1, most of it will be handled for you by libraries. If you use #2, you'll have to manage it more yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM