asp.net core webpi 结合jwt实现登录鉴权

1.安装jwt nuget包

    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.25" />
    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />

2.配置jwt信息

  builder.Services.AddDistributedMemoryCache();
            var key = Encoding.ASCII.GetBytes("your_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_here");

            builder.Services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = "JwtBearer";
                options.DefaultChallengeScheme = "JwtBearer";
            }).AddJwtBearer("JwtBearer", jwtBearerOptions =>
            {
                jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = true,
                    ClockSkew = System.TimeSpan.Zero
                };
            });
             app.UseAuthentication();
            app.UseAuthorization();

3.登录代码生成token

 /// 
        /// 生成token
        /// 
        /// 
        /// 
        /// 
        [HttpPost]
        public IActionResult tokensc(string username,string pwd)
        {
        //...需从数据库获取
        if(username=!admin&&pwd=="123"){
         return NotFound("用户名或密码不存在");
        }
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes("your_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_here");
            // 设置过期时间为当前时区的时间加上30分钟
            var expirationTime = DateTimeOffset.Now.AddMinutes(5);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Name, username)
                }),
                // 其他令牌信息...
                Expires = expirationTime.UtcDateTime,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);

            return Ok(new { Token = tokenString });
        }

4.写一个授权过滤器(解析token)

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Text;

namespace webapi
{
    public class customAuthorizeAttribute : Attribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            // 获取token
            string token = context.HttpContext.Request.Headers["token"];
            // 获取当前用户的角色
            //var user = context.HttpContext.User;
            // 获取当前的路由信息
            var routeData = context.RouteData;

            // 获取控制器和动作方法名称
            var controller = routeData.Values["controller"];
            var action = routeData.Values["action"];
            //通过角色-控制器-方法,可以开放权限
            //TODO
            // 尝试解析token
            if (!TryParseToken(token))
            {
                // 如果解析失败,返回 401 Unauthorized 状态码
                context.Result = new JsonResult("无权限访问"); /*new StatusCodeResult(401)*/;
                return;
            }
        }

        /// 
        /// 解析token
        /// 
        /// 
        public bool TryParseToken(string tokens)
        {
            try
            {
                // 这里应该验证用户名和密码

                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes("your_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_hereyour_secret_key_here"); // 与创建令牌时使用的密钥相同

                var tokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = true
                };

                var token = tokens; // 替换为要解析的JWT令牌

                SecurityToken validatedToken;
                var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out validatedToken);

                var jwtToken = (JwtSecurityToken)validatedToken;

                // 从令牌中获取声明
                var username = jwtToken.Claims.First(x => x.Type == "unique_name").Value;
                var expirationDate = jwtToken.ValidTo;

                if (expirationDate < DateTime.UtcNow)
                {
                    Console.WriteLine("Token has expired.");
                }
                else
                {
                    Console.WriteLine("Token is still valid.");
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}

5.在需要的控制器或方法上,使用过滤器(只有token解析成功,没有过期才可以访问接口)

[customAuthorizeAttribute ]
[HttpGet]
public IActionResult Get(){
return ok();
}

6.可以结合IdentityService4身份认证框架使用

你可能感兴趣的:(asp.net,jwt)