【C#/.NET 日常开发技巧】JWT+ActionFilter 简便控制器代码

 JWT+ActionFilter 简便控制器代码

这是微软关于过滤器的介绍:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.0

今天的日常开发技巧是介绍下如何通过Authorization 和 Action Filter 来自动将登录用户的ID添加到控制器中去,这样就可以简化我们代码量了。

首先我们新建一个ApiController类继承ControllerBase  

    [ApiController]
    [Route("api/[controller]")]
    [Authorize]   // 开启授权 登录成功后才能访问
    [ActionFilter] // 自定义的一个属性 核心功能下文实现 用来实现自动将登录用户的ID添加到控制器中去
    public abstract class ApiController:ControllerBase
    {
        public string UserId { get; set; }
    }

上述代码我们创建一个抽象的基类控制器,这样就可以将[ActionFilter]应用到所有继承ApiController这个基类的控制器上,这样我们就可以规避很多重复的代码,与此同时我们定义一个UserId属性,便于每个派生类访问。

[Authorize]用来判断是否有权限调用控制器或者动作方法,常见的身份认证方案有JWT,下文代码也是基于此。
下面我们实现ActionFilter 属性

 public class ActionFilter : Attribute, IActionFilter
     {
         // 动作方法执行结束调用
         public void OnActionExecuted(ActionExecutedContext context)
         {
             // throw new NotImplementedException();
         }
         // 动作方法执行前执行
         public void OnActionExecuting(ActionExecutingContext context)
         {
            // throw new NotImplementedException();
            var c = context.Controller as ApiController;
            c.UserId = c.User.FindFirstValue(ClaimTypes.NameIdentifier);
        }
    }

在这个类中,我们继承了Attribute ,这样就可以将ActionFilter当做属性来用,同时继承了IActionFilter接口,这就要求我们实现两个方法:OnActionExecuted 、 OnActionExecuting 两个方法的执行顺序分别是控制器(动作方法)被执行后和执行前。因为我们需要在所有的控制器里面使用UserId, 所以我们在OnActionExecuting 执行相应的逻辑操作。
ActionExecutedContext 作为一个OnActionExecuting方法的参数,可以得到控制器本身,我们将控制器转化为 ApiController  也就是上文定义的那个抽象类,这样就可以操作里面定义的UserId 了。因为我用的JWT验证,所以第二行的逻辑可以获取到登录用的UserId。对于ClaimTypes.NameIdentifier 这个属性 可以在生成Toke的时候用登录用户的UserId赋值,这样就可以作为有效信息存到Token中去便于解析。

 public static string CreateToken(JwtTokenModel tokenModel)
 {
             var claims= new []{
                 new Claim("Id",tokenModel.Id.ToString()),
                 new Claim("CustomerNo",tokenModel.CustomerNo),
                 new Claim("CustomerName",tokenModel.CustomerName),
                 new Claim(ClaimTypes.NameIdentifier,tokenModel.CustomerNo) // ClaimTypes.NameIdentifier类型值为用户Id
             };
             // 生成密钥
             var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenModel.Security));
            var creds = new SigningCredentials(key,SecurityAlgorithms.HmacSha256); 

            var token =new JwtSecurityToken(
                issuer:tokenModel.Issuer,
                audience:tokenModel.Audience,
                expires:DateTime.Now.AddDays(tokenModel.Expires),
                signingCredentials:creds,
                claims:claims
            );

            //生成token
            var accessToken =new JwtSecurityTokenHandler().WriteToken(token);
            return accessToken;
}

示例展示

     /// <summary>
     /// 测试控制器  继承自定义的ApiController
     /// </summary>
     public class TestController : ApiController
     {
         [HttpGet]
         public void GetUserId()
         {
             // 直接获取到用户访问的用户Id 
             // 后续需要UserId传参调用服务的时候就不需要重新获取了用户Id了
             System.Console.WriteLine("用户Id:"+UserId); // 控制台可以打印出 访问登录用户的UserId
         }
     }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用.NET 6 Web API实现JWT认证的示例代码: 1. 首先,安装所需的NuGet包: ``` dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer dotnet add package System.IdentityModel.Tokens.Jwt ``` 2. 在Program.cs文件中进行配置: ```csharp using Microsoft.IdentityModel.Tokens; var builder = WebApplication.CreateBuilder(args); // 添加JWT认证服务 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "your_issuer", // 发行者 ValidAudience = "your_audience", // 受众 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")) // 密钥 }; }); builder.Services.AddControllers(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); ``` 3. 创建一个控制器来处理认证请求: ```csharp using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.IdentityModel.Tokens; [Authorize] [ApiController] [Route("api/[controller]")] public class AuthController : ControllerBase { [AllowAnonymous] [HttpPost("login")] public IActionResult Login(string username, string password) { // 假设这里是验证用户名和密码的逻辑 // 如果验证通过,创建一个JWT token并返回给客户端 var token = GenerateToken(username); return Ok(new { token }); } [HttpGet("protected")] public IActionResult Protected() { // 受保护的路由,只有经过认证的用户才能访问 return Ok("You have accessed the protected route."); } private string GenerateToken(string username) { var claims = new[] { new Claim(ClaimTypes.Name, username), // 可以添加其他自定义的claims }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: "your_issuer", audience: "your_audience", claims: claims, expires: DateTime.Now.AddMinutes(30), // token过期时间 signingCredentials: creds); return new JwtSecurityTokenHandler().WriteToken(token); } } ``` 以上示例代码演示了如何使用.NET 6 Web API和JWT来实现身份认证。请注意替换示例中的"your_issuer"、"your_audience"和"your_secret_key"为适合你的实际情况的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值