4

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

身份验证使用Microsoft.OwinOpenIdConnect以及 Azure AD 进行授权。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*/
                    },
            });
    }

单击登录时,我们导航到一个 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 服务器之间进行身份验证。我们想改用基于令牌的方法。如果你有兴趣,这就是原因

我试图 用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 请求响应中自动发送,同时重定向到我们指定的 url。 我在哪里可以找到 OWIN 使用 UseOAuthBearerAuthentication 生成的承载(如果有)**、**我应该在何时何地将其发送回我的客户端 SPA

注意:可以在这个 github 存储库中找到我们正在尝试做的开源示例。

4

1 回答 1

4

我认为有两种方法供您考虑。

  1. 使用 javascript 库在您的单页应用程序中执行登录和令牌获取。那么你的后端就是一个纯粹的 Web API,可以只使用 OAuth 承载中间件来验证请求。后端对用户登录一无所知。我们有一个很好的示例在这里采用这种方法。如果您的后端也需要进行 API 调用,您也可以考虑 OnBehalfOf 流程。我通常推荐这种方法。
  2. 使用服务器中的 OpenIDConnect 中间件来执行用户登录和令牌获取。您甚至可以CookieAuthenticationMiddleware完全省略使用 (尽管我不是 100% 确定)。您可以在您提到的通知中捕获令牌AuthorizationCodeReceived,并且您可以使用 URL 片段中的令牌重定向回您的 SPA。您还可以有一些路由将令牌(缓存在您的服务器上)传递到您的 javascript。无论哪种情况,您都需要确保外部调用者无法访问您的令牌。

要记住的是在令牌过期时如何刷新令牌。如果您使用 #1,则大部分内容将由库为您处理。如果您使用#2,您将不得不自己管理它。

于 2016-10-18T17:24:38.447 回答