【问题标题】:.NET Framework MVC and Web Api Auth JWT.NET Framework MVC 和 Web Api Auth JWT
【发布时间】:2019-02-26 05:19:43
【问题描述】:

我在 MVC 中有一个使用 .NET Framework v4.7 的项目,上面有一些 WebApi。我需要知道的是如何使用中间件来为 HTTP 请求和 MVC Action 请求授权 JWT。

我到处寻找解决方案示例,但找不到任何东西。

如果有人可以提供帮助,我将不胜感激。

对不起英语。

【问题讨论】:

  • 您的 MVC 应用程序和 WebAPI 是否驻留在同一个解决方案上?如果是,除了 MVC 操作,您还有什么选择?
  • 是的,我的 MVC 和 WebAPI 在同一个解决方案中。我可以选择从框架更改为核心应用程序
  • 你找到解决办法了吗?

标签: .net asp.net-mvc jwt asp.net-web-api2 bearer-token


【解决方案1】:

从您的问题中了解我的理解您想为您的 WebApi 使用 JWT 令牌,为您的 MVC 使用正常流程,因为稍后从服务器生成的视图不依赖于 JWT 令牌。

我已经看到了这个问题。在我的一个应用程序中,我同时托管 MVC 视图和 webapi,而 MVC 视图依赖于基于 cookie 的身份验证和授权。和 WebApi 调用依赖于 JWT 令牌进行授权和身份验证。

抱歉,此解决方案来自 .net 核心。您需要像这样配置 Cookie 和 JWT 身份验证

services.AddCookie()
.AddJwtBearer()

这里默认是您的 cookie 身份验证。现在要为您的 webapi 启用 jwt 令牌,您需要使用以下属性装饰 webapi

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

希望这能回答你的问题。

【讨论】:

    【解决方案2】:

    如果我掌握了您的问题陈述,我认为 OWIN 可能是一个选择:您将应用程序与底层托管分离并获得一个可扩展的管道,您可以将中间件注入其中(非常像 .net 核心开箱即用)。

    更好 - 它提供开箱即用的 JWT 支持(嗯,您需要安装一些 nuget 包 - 见下文)。然后您只需在您的IAppBuilder 上启用它并使用标准[Authorize] 属性滚动。

    为了演示此设置,我整理了一个 working GitHub repo here 来说明 WebApi 中间件。

    除了 Microsoft.AspNet.WebApi.OwinMicrosoft.Owin.Host.SystemWebMicrosoft.Owin.Security.Jwt nuget 包之外,它几乎是一个标准的 asp.net WebApi 项目,更改了以下文件:

    /Startup.cs

    using System.Text;
    using System.Web.Http;
    using Microsoft.IdentityModel.Tokens;
    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.Jwt;
    using Owin;
    
    namespace OWIN.WebApi
    {
        public class Startup
        {
            public void Configuration(IAppBuilder appBuilder)
            {
                HttpConfiguration config = new HttpConfiguration();
                WebApiConfig.Register(config); // bootstrap your existing WebApi config 
    
                appBuilder.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
                {
                    AuthenticationMode = AuthenticationMode.Active,
                    TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateIssuerSigningKey = true, // I guess you don't even have to sign the token
                        ValidIssuer = "http://localhost",
                        ValidAudience = "http://localhost",
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("jwt_signing_secret_key"))
                    }
                });
                appBuilder.UseWebApi(config); // instruct OWIN to take over
            }
        }
    }
    

    /Controllers/ProtectedValuesController.cs

    using System.Collections.Generic;
    using System.Web.Http;
    
    namespace OWIN.WebApi.Controllers
    {
        [Authorize]
        public class ProtectedValuesController : ApiController
        {
            // GET api/values
            public IEnumerable<string> Get()
            {
                return new string[] { "value1", "value2" };
            }
        }
    }
    

    /Controllers/ObtainJwtController.cs

    using System;
    using System.Collections.Generic;
    using System.IdentityModel.Tokens.Jwt;
    using System.Text;
    using System.Web.Http;
    using Microsoft.IdentityModel.Tokens;
    using Claim = System.Security.Claims.Claim;
    
    namespace OWIN.WebApi.Controllers
    {
        // this class is literally just a test harness to help me generate a valid token for popping into Postman.
        public class ObtainJwtController: ApiController
        {
            private string CraftJwt()
            {
                string key = "jwt_signing_secret_key"; //Secret key which will be used later during validation    
                var issuer = "http://localhost";
    
                var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
                var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
    
                var permClaims = new List<Claim>
                {
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim("valid", "1"),
                    new Claim("userid", "1"),
                    new Claim("name", "test")
                };
    
                var token = new JwtSecurityToken(issuer,
                    issuer,
                    permClaims,
                    expires: DateTime.Now.AddDays(1),
                    signingCredentials: credentials);
                return new JwtSecurityTokenHandler().WriteToken(token);
            }
    
            public string Get()
            {
                return $"Bearer {CraftJwt()}";
            }
        }
    }
    

    这似乎也适用于 MVC

    我添加了一些额外的 nuget 包来处理 ASP.NET Identity,这似乎使我能够成功地保护以下控制器:

    /Controllers/Home.cs

    using System.Web.Mvc;
    
    namespace OWIN.WebApi.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                ViewBag.Title = "Home Page";
    
                return View();
            }
    
            [Authorize]
            public ActionResult Protected()
            {
                return View();
            }
        }
    }
    

    希望这能给你一些探索的选择

    【讨论】:

    • 请确保您指的是经典的 asp.net mvc,而不是 netcore 应用程序
    • @anatol 据我所知,它完全是一个完整的 .net 框架解决方案
    • 这不适用于 mvc 控制器中的 [Authorize] 属性
    • @anatol 好的,让我再看看
    • 似乎只能使用 cookie 身份验证
    猜你喜欢
    • 2012-08-07
    • 2019-10-25
    • 1970-01-01
    • 2018-07-13
    • 2019-11-03
    • 1970-01-01
    • 2013-02-27
    • 2019-05-28
    • 2016-04-18
    相关资源
    最近更新 更多