在 MVC 中使用 OAuth 持有者令牌 (JWT)

Posted

技术标签:

【中文标题】在 MVC 中使用 OAuth 持有者令牌 (JWT)【英文标题】:Using An OAuth Bearer Token (JWT) With MVC 【发布时间】:2016-05-17 09:25:22 【问题描述】:

我创建了一个后端 WebApi 来创建 JWT 令牌,当我使用 PostMan 通过将令牌添加到标头来访问受限资源时,它们工作正常,例如[授权(Roles="SuperAdmin")]。

我想将此基础架构与我的 MVC 应用程序一起使用,但不太清楚如何将它结合在一起。

我猜当用户创建帐户并为他们生成 JWT(通过 WebApi)时,我需要将令牌粘贴到 cookie 中,但如何做到这一点并从 cookie 中提取 JWT未来的请求,以便它可以与我装饰 ActionResults 的普通 [Authorize] 属性一起使用?

我需要在 Owin 管道中添加一些内容吗? 还是我需要创建一个自定义的 [Authorize] 属性?

我的 Startup.cs 文件目前如下所示:

public void Configuration(IAppBuilder app)
    
        HttpConfiguration httpConfig = new HttpConfiguration();

        ConfigureOAuthTokenGeneration(app);

        ConfigureOAuthTokenConsumption(app);


        ConfigureWebApi(httpConfig);

        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        app.UseWebApi(httpConfig);

    

    private void ConfigureOAuthTokenGeneration(IAppBuilder app)
    
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        
            //TODO: enforce https in live
            //For Dev enviroment only (on production should be AllowInsecureHttp = false)
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/oauth/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new CustomOAuthProvider(),
            AccessTokenFormat = new CustomJwtFormat("https://localhost:443")
        ;

        // Plugin the OAuth bearer JSON Web Token tokens generation and Consumption will be here


        // OAuth 2.0 Bearer Access Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
    

    private void ConfigureOAuthTokenConsumption(IAppBuilder app)
    
        var issuer = "https://localhost:443";
        string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];
        byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["as:AudienceSecret"]);

        // Api controllers with an [Authorize] attribute will be validated with JWT
        app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            
                AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = new[]  audienceId ,
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
                
            );
    

    private void ConfigureWebApi(HttpConfiguration config)
    
        config.MapHttpAttributeRoutes();

        var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
        jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    

如果有帮助,我会按照本指南进行操作: http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/

【问题讨论】:

【参考方案1】:

您提到的基础架构实际上是为处理直接 Web API 调用而设计的。经典的基于重定向的 Web 应用程序会退回到更传统的模式,其中应用程序接收一个令牌,对其进行验证并使用它来启动经过身份验证的会话(通过将令牌验证的结果保存在某些会话工件中,如令牌)。尽管您可以从任何基于令牌的系统(包括您的自定义系统)开始实施此模式,但通常利用现有协议(如 OpenId Connect)和现有产品(如 Azure AD 或Identity Server)更方便(和安全)。有关基于 Azure AD 的简单示例,请参阅 this - 无论您选择哪种 OpenId Provider,中间件都保持不变。

【讨论】:

以上是关于在 MVC 中使用 OAuth 持有者令牌 (JWT)的主要内容,如果未能解决你的问题,请参考以下文章

未经资源所有者同意生成访问令牌的 OAuth 流程是啥?

处理 OAuth 2.0 身份验证 - 在 ASP.NET MVC 应用程序中获取令牌重定向令牌响应

OAuth 2.0

OAuth 2.0

OAuth 2.0

Oauth 刷新令牌授予类型