在ASP.NET OWIN OpenIdConnect代码授权流程中通过基于令牌的身份验证替换Cookie

时间:2016-10-18 13:22:09

标签: asp.net owin openid-connect azure-active-directory owin-middleware

我们有一个用ASP.NET编写的Web应用程序,它使用MVC为我们的单页应用程序和Web API提供ajax调用。

身份验证使用 Microsoft.Owin OpenIdConnect 与Azure AD for Authority。 OAUTH流程是服务器端代码授权。 然后在 Startup.Auth.cs 中我们有

    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*/
                    },
            });
    }

当点击signin时,我们导航到一个url,其路由映射到以下MVC控制器的方法

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);
    }

然后,连接到我们应用程序的最终用户使用ASP.NET cookie在我们的客户端应用程序和ASP.net服务器之间进行身份验证。 我们希望使用基于令牌的方法。如果您对this is the reason感兴趣。

我试图替换 Microsoft.Owin.Security.OAuth 和Startup.cs中的Nuget包 Microsoft.Owin.Security.Cookies 替换

app.UseCookieAuthentication(cookieAuthenticationOptions);

app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

在我的 AccountController 中,我们将挑战从HttpContext.GetOwinContext().Authentication.SignOut(authenticationProperties, OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);更改为HttpContext.GetOwinContext().Authentication.SignOut(authenticationProperties, OpenIdConnectAuthenticationDefaults.AuthenticationType, OAuthDefaults.AuthenticationType);

问题在于,使用Cookie时,当流程完成时, set-cookie 会在Web请求中自动发送,同时重定向到我们指定的网址。 我在哪里可以找到OWIN使用UseOAuthBearerAuthentication生成的承载(如果有)**,**我应该何时何地将其发送回客户端SPA

注意:我们尝试做的开源示例可以在this github repository中找到。

1 个答案:

答案 0 :(得分:2)

我认为有两种方法可以考虑。

  1. 使用javascript库执行登录&amp;单页应用中的令牌获取。然后你的后端纯粹是一个Web API,可以使用OAuth承载中间件来验证请求。后端对用户签名没有任何了解。我们有一个很好的样本采用这种方法here。如果您的后端也需要进行API调用,您也可以考虑使用OnBehalfOf流程。我通常推荐这种方法。
  2. 使用服务器中的OpenIDConnect中间件执行用户登录和令牌获取。您甚至可以完全省略CookieAuthenticationMiddleware的使用(尽管我并非100%确定)。您可以在提及的AuthorizationCodeReceived通知中捕获令牌,然后您可以使用URL片段中的令牌重定向回SPA。您还可以使用一些路由将令牌(缓存在您的服务器上)下载到您的javascript。在任何一种情况下,您都需要确保外部来电者无法访问您的令牌。
  3. 要记住的是在令牌到期时刷新令牌的方式。如果您使用#1,大部分将由图书馆为您处理。如果你使用#2,你必须自己管理它。