ASP.NET WebApi 基于JWT实现Token签名认证(发布版)
时间: 2023-06-20 18:07:42 浏览: 79
首先,我们需要安装 `Microsoft.AspNet.WebApi` 和 `Microsoft.Owin.Security.Jwt` NuGet 包。
接下来,我们需要在 `WebApiConfig.cs` 文件中配置 Web API 路由:
```csharp
public static void Register(HttpConfiguration config)
{
// 配置路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// 配置 JWT 认证
ConfigureJwtAuth(config);
}
```
然后,我们需要在 `Web.config` 文件中配置 JWT 令牌的密钥和有效期:
```xml
<appSettings>
<add key="jwtSecret" value="my_secret_key" />
<add key="jwtExpireDays" value="7" />
</appSettings>
```
接下来,我们需要创建一个 `JwtAuthManager` 类来管理 JWT 认证:
```csharp
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
public class JwtAuthManager : IJwtAuthManager
{
private readonly string _jwtSecret;
private readonly double _jwtExpireDays;
public JwtAuthManager(string jwtSecret, double jwtExpireDays)
{
_jwtSecret = jwtSecret;
_jwtExpireDays = jwtExpireDays;
}
public string GenerateToken(IEnumerable<Claim> claims)
{
var key = Encoding.ASCII.GetBytes(_jwtSecret);
var jwtToken = new JwtSecurityToken(
claims: claims,
expires: DateTime.Now.AddDays(_jwtExpireDays),
signingCredentials: new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature)
);
var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
return token;
}
}
```
然后,我们需要创建一个 `JwtAuthAttribute` 特性,用于在控制器或操作方法上应用 JWT 认证:
```csharp
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class JwtAuthAttribute : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
try
{
var token = actionContext.Request.Headers.Authorization.Parameter;
var jwtAuthManager = actionContext.ControllerContext.Configuration
.DependencyResolver.GetService(typeof(IJwtAuthManager)) as IJwtAuthManager;
var principal = jwtAuthManager.ValidateToken(token);
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
}
catch (Exception)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
return;
}
base.OnAuthorization(actionContext);
}
}
```
最后,我们需要在 `ConfigureJwtAuth` 方法中注册依赖项并配置 JWT 认证:
```csharp
private static void ConfigureJwtAuth(HttpConfiguration config)
{
var jwtSecret = ConfigurationManager.AppSettings["jwtSecret"];
var jwtExpireDays = double.Parse(ConfigurationManager.AppSettings["jwtExpireDays"]);
var container = new UnityContainer();
container.RegisterType<IJwtAuthManager, JwtAuthManager>(
new InjectionConstructor(jwtSecret, jwtExpireDays));
config.DependencyResolver = new UnityResolver(container);
config.Filters.Add(new JwtAuthAttribute());
}
```
现在,我们可以在控制器或操作方法上应用 `JwtAuth` 特性来启用 JWT 认证:
```csharp
[RoutePrefix("api/products")]
public class ProductsController : ApiController
{
[HttpGet]
[Route("")]
[JwtAuth]
public IHttpActionResult Get()
{
// ...
}
[HttpGet]
[Route("{id}")]
[JwtAuth]
public IHttpActionResult Get(int id)
{
// ...
}
[HttpPost]
[Route("")]
[JwtAuth]
public IHttpActionResult Post([FromBody] Product product)
{
// ...
}
// ...
}
```
这样,我们就成功地基于 JWT 实现了 Token 签名认证。