.NET6使用jwt进行权限验证

在当今的软件开发中,安全性是至关重要的。为了确保应用程序的资源受到保护,并只对经过身份验证和授权的用户开放,我们经常使用JSON Web Token (JWT)来进行权限验证。在.NET 6中,实现这样的系统变得更加简单和直接。

一、JWT简介

JWT是一种开放标准,它定义了一种紧凑的、自包含的方式来在各方之间传递信息。它经常被用于身份验证和授权,因为它提供了一种在不需要中心化身份验证系统的情况下,在客户端和服务器之间安全地传输用户信息的方法。

二、在.NET 6中实现JWT验证

在.NET 6项目中实现基于JWT的权限验证通常涉及以下步骤:

  1. 创建JWT认证服务:这个服务将负责生成和验证JWT。它需要一个密钥,该密钥用于签名令牌,以便之后可以验证它。
  2. 用户管理:创建一个服务来处理用户管理任务,例如创建、查询和验证用户凭据。这通常是与数据库交互的代码。
  3. 配置依赖注入:如果使用如ASP.NET Core的依赖注入框架,需要将认证服务和其他相关组件注册到容器中,以便在整个应用程序中重用它们。
  4. 使用权限验证服务:在控制器或动作方法上使用[Authorize]属性来要求JWT验证。如果令牌无效或过期,用户将被拒绝访问受保护的资源。

三、注意事项

  • 密钥管理:确保密钥的安全存储和更新。如果密钥泄露,任何人都可以生成有效的JWT,可能导致安全风险。
  • 令牌过期时间:合理设置令牌的过期时间,以平衡用户便利性和安全性。
  • 错误处理:当验证失败时,提供适当的错误响应,帮助客户端理解发生了什么。
  • 测试和调试:确保对整个流程进行彻底的测试,以确保没有安全漏洞或问题。

四、结论

使用JWT进行权限验证是保护.NET 6应用程序的一种有效方法。通过遵循最佳实践和密切关注安全更新,可以确保应用程序的安全性。

正好在最近需要写一个使用jwt鉴权的功能,下面是代码。

先新建一个配置类,用于接收和传递jwt对象:

public class JwtOpt
{
    public string Audience { get; set; } = string.Empty;

    public string Issuer { get; set; } = string.Empty;

    public string SecurityKey { get; set; } = string.Empty;
}

在appsettings.json文件存储相关信息:

"JwtOpt": {
  "Audience": "***",
  "Issuer": "***",
  "SecurityKey": "************************************"
}

写一个JwtMiddleware作为中间件:

public class JwtMiddleware
{
    private readonly RequestDelegate _next;
    private readonly JwtOpt _authOptions;

    public JwtMiddleware(RequestDelegate next, IConfiguration configuration)
    {
        _next = next;
        _authOptions = configuration.GetSection("JwtOpt").Get<JwtOpt>();
    }

    public async Task Invoke(HttpContext context)
    {
        var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last()
                    ?? context.Request.Headers["token"].FirstOrDefault()
                    ?? context.Request.Query["Token"].FirstOrDefault()
                    ?? context.Request.Cookies["Token"];
        if (token != null)
            AttachUserToContext(context, token);
        await _next(context);
    }

    private void AttachUserToContext(HttpContext context, string token)
    {
        try
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            byte[]? key = Encoding.ASCII.GetBytes(_authOptions.SecurityKey);
            tokenHandler.ValidateToken(token, new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidIssuer = _authOptions.Issuer,
                ValidAudience = _authOptions.Audience,
                ClockSkew = TimeSpan.Zero
            }, out SecurityToken validatedToken);
            var jwtToken = (JwtSecurityToken)validatedToken;
            var user = jwtToken.Claims.First(x => x.Type == "User").Value;
            var claimsIdentity = new ClaimsIdentity(new Claim[] { new Claim("User", jwtToken.Claims.First(x => x.Type == "User").Value) });
            Thread.CurrentPrincipal = new ClaimsPrincipal(claimsIdentity);
            context.Items["User"] = user;
        }
        catch
        {

        }
    }
}

写一个ApiAuthorizeAttribute用于验证:

public class ApiAuthorizeAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.Items["User"];
        if (HasAllowAnonymous(context) == false && user == null)
        {
            context.Result = new JsonResult(new { msg = "你无权做这些", code = 401 })
                { StatusCode = StatusCodes.Status401Unauthorized };
        }
    }

    private static bool HasAllowAnonymous(AuthorizationFilterContext context)
    {
        var filters = context.Filters;
        if (filters.OfType<IAllowAnonymousFilter>().Any())
        {
            return true;
        }
        var endpoint = context.HttpContext.GetEndpoint();
        return endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null;
    }
}

在Program.cs中加入代码:

builder.Services.AddControllers()
    .AddInject().AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
    }).AddMvcOptions((opt) => { opt.Filters.Add<ApiAuthorizeAttribute>(); });

 app.UseMiddleware<JwtMiddleware>();

在登录认证成功后生成token并返回:


 IConfiguration _configuration;
 private AutoDingContext _ctx;

 public TestController( IConfiguration configuration)
 {
     _configuration = configuration;
 } 
//以上是依赖注入



var jwtOpt = _configuration.GetSection("JwtOpt").Get<JwtOpt>(); //获取配置文件里JwtOpt的信息

var claims = new[]
 {
     new Claim(ClaimTypes.Name, username),
     new Claim("User",username)
 };

 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOpt.SecurityKey));
 var signMethod = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
 var tokenOpt = new JwtSecurityToken(
     issuer: jwtOpt.Issuer,
     audience: jwtOpt.Audience,
     claims: claims,
     expires: DateTime.Now.AddDays(7),
     signingCredentials: signMethod
 );

 var tokenStr = new JwtSecurityTokenHandler().WriteToken(tokenOpt); //生成的token

这样功能就完成了,下面是测试返回的结果:

未进行token认证时:

登录获取token:

在请求时加上token:

测试完美通过。使用JWT进行权限验证是保护.NET 6应用程序的一种有效方法。通过遵循最佳实践和密切关注安全更新,可以确保应用程序的安全性。

最后向大家介绍一下在开发中我使用的后端框架----Fruion,让 .NET 开发更简单,更通用,更流行。官网地址如下:

让 .NET 开发更简单,更通用,更流行。 Furion | Furion

是一个非常不错的框架,上手快速,对新手也很友好,官方文档也很详细,使.net开发更加方便快捷。可惜有一部分文档需要收费了,大家可以支持一下开源作者。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值