• .net core jwt 实现简易授权


    jwt授权拓展类AddAuth:

    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.IdentityModel.Tokens;
    using Siia.MobileApi.Extensions.Jwt;
    using System;
    using System.Text;
    
    namespace Siia.MobileApi.Extensions
    {
        public static class AuthenticationExt
        {
            public static void AddAuth(this IServiceCollection services, IConfiguration configuration)
            {
                if (services == null) throw new ArgumentNullException(nameof(services));
    
                JwtSettings jwtSettings = new JwtSettings();
                services.Configure<JwtSettings>(configuration.GetSection("JwtSettings"));
                configuration.GetSection("JwtSettings").Bind(jwtSettings);
    
                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(o =>
                    {
                        o.TokenValidationParameters = new TokenValidationParameters()
                        {
                            ValidateIssuerSigningKey = true,
                            ValidateIssuer = true,//是否验证Issuer
                            ValidateAudience = true,//是否验证Audience
                            ValidateLifetime = true,//是否验证失效时间
                            ValidIssuer = jwtSettings.Issuer,
                            ValidAudience = jwtSettings.Audience,
                            //用于签名验证
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtSettings.SecretKey)),
                            //注意这是缓冲过期时间,总的有效时间等于这个时间加上jwt的过期时间,如果不配置,默认是5分钟
                            //ClockSkew = TimeSpan.FromSeconds(4)
                        };
                    });
                services.AddTransient<IPassport, Passport>(PassportFactory);
            }
            private static Passport PassportFactory(IServiceProvider provider)
            {
                var httpAccessor = provider.GetService<IHttpContextAccessor>();
                if (httpAccessor == null)
                {
                    return null;
                }
                return new Passport(httpAccessor.HttpContext?.User);
            }
        }
    }
    View Code

    ConfigureServices中注入AddAuth: services.AddAuth(Configuration);

     public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
    
                services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
                services.AddSwagger();
                services.AddAuth(Configuration);
                services.AddScoped<IJwt, Jwt>(); // Jwt注入
    
                //json 序列化问题
                services.AddControllers().AddNewtonsoftJson(options =>
                {
                    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //指定时间的序列化格式
                    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //忽略循环引用
                });
    
                //解决中文被编码
                services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));
    
                services.AddHttpClient("Siia.MobileApi");
                //防止回收
                services.AddQuartzHostedService()
                    .AddQuartzJob<WeatherMonitoring>()
                   .AddQuartzJob<HealthCheckJob>();
    
                //services.AddSingleton<MessageQueueFunc>();
            }
    View Code

    Configure中:

    app.UseAuthentication();
    app.UseAuthorization();

    jwt,生成授权token:

    using Microsoft.Extensions.Configuration;
    using Microsoft.IdentityModel.Tokens;
    using System;
    using System.Collections.Generic;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Claims;
    using System.Text;
    
    namespace Siia.MobileApi.Extensions.Jwt
    {
        public class Jwt : IJwt
        {
            private JwtSettings _jwSetting = new JwtSettings();
            public Jwt(IConfiguration configration)
            {
                configration.GetSection("JwtSettings").Bind(_jwSetting);
            }
            /// <summary>
            /// 生成Token
            /// </summary>
            /// <param name="Claims"></param>
            /// <returns></returns>
            public (string token, int expires) GetToken(Dictionary<string, string> Claims)
            {
                List<Claim> claims = new List<Claim>();
                foreach (var item in Claims)
                {
                    claims.Add(new Claim(item.Key, item.Value));
                }
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this._jwSetting.SecretKey));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                var expires = DateTime.Now.AddMinutes(_jwSetting.Lifetime);
                var securityToken = new JwtSecurityToken(
                    issuer: this._jwSetting.Issuer,
                    audience: this._jwSetting.Audience,
                    claims: claims,
                    expires: expires,
                    signingCredentials: creds
                    );
                var token = new JwtSecurityTokenHandler().WriteToken(securityToken);
                return (token, _jwSetting.Lifetime * 60);
            }
    
        }
    }
    View Code

    IJwt:

    public interface IJwt
        {
            (string token, int expires) GetToken(Dictionary<string, string> Claims);
        }
    View Code

    配置文件model:

    internal class JwtSettings
        {
            public string Issuer { get; set; }
            public string Audience { get; set; }
            /// <summary>
            /// 加密key
            /// </summary>
            public string SecretKey { get; set; }
            /// <summary>
            /// 生命周期
            /// </summary>
            public int Lifetime { get; set; }
        }
    View Code

    appsettings.json:

    "JwtSettings": {
        "Issuer": "issuer", //随意定义
        "Audience": "Audience", //随意定义
        "SecretKey": "dnX51glQ09THNpjFFntQiHqIk1HcuYxJ", //随意定义
        "Lifetime": 60 //单位分钟
      }
    View Code

    登录信息Passport:

    using System.Collections.Generic;
    using System.Security.Claims;
    using System.Text.Json;
    
    namespace Siia.MobileApi.Extensions
    {
        public class Passport : IPassport
        {
            public bool IsAuthenticated { get; set; }
    
            /// <summary>
            /// 用户Id
            /// </summary>
            public int UserId { get; set; }
    
            /// <summary>
            /// 用户名
            /// </summary>
            public string UserName { get; set; }
    
            /// <summary>
            /// 拥有的角色Id
            /// </summary>
            public List<int> RoleIds { get; set; }
    
            /// <summary>
            /// 手机号
            /// </summary>
            public string PhoneNumber { get; set; }
            /// <summary>
            /// 组织Id
            /// </summary>
            public int OrganizationId { get; set; }
    
            public Passport(ClaimsPrincipal user)
            {
                if (user != null && user.Identity.IsAuthenticated)
                {
                    this.IsAuthenticated = true;
                    this.UserId = this.GetValue(user, "userId", -1);
                    this.UserName = user.FindFirst("userName")?.Value;
                    this.PhoneNumber = user.FindFirst("phoneNumber")?.Value;
                    this.RoleIds = this.GetValue(user, "roleIds");
                    this.OrganizationId= this.GetValue(user, "organizationId", -1);
                }
                else
                {
                    this.IsAuthenticated = false;
                    this.UserId = -1;
                }
            }
    
            private int GetValue(ClaimsPrincipal user, string type, int defaultValue)
            {
                if (user.FindFirst(type) == null) return defaultValue;
                return int.Parse(user.FindFirst(type).Value);
            }
            private List<int> GetValue(ClaimsPrincipal user, string type)
            {
                if (user.FindFirst(type) == null) return null;
                return JsonSerializer.Deserialize<List<int>>(user.FindFirst(type).Value);
            }
        }
    }
    View Code

    IPassport:

    public interface IPassport
        {
            bool IsAuthenticated { get; }
            /// <summary>
            /// 用户Id
            /// </summary>
            int UserId { get; }
            /// <summary>
            /// 用户名
            /// </summary>
            string UserName { get; }
            /// <summary>
            /// 拥有的角色Id
            /// </summary>
            List<int> RoleIds { get; }
            /// <summary>
            /// 手机号
            /// </summary>
            public string PhoneNumber { get; set; }
            /// <summary>
            /// 组织Id
            /// </summary>
            public int OrganizationId { get; set; }
        }
    View Code

    获取授权token :

    /// <summary>
            /// 账号密码用户登录接口 获取授权token
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            [AllowAnonymous]
            [HttpPost("[action]")]
            public async Task<IActionResult> UserLogin([FromBody] AccountsLogin request)
            {
                //这里应该是需要去连接数据库做数据校验
                var _result = await _accountsService.UserLogin(request.UserName, request.Password);
    
                if (_result == null || !(_result.Status ?? false))
                {
                    return Ok(ActionResponse.Fail(-1, _result.Message ?? "账号密码不正确"));
                }
                var clims = new Dictionary<string, string>();
                clims.Add("userId", _result.Data.Id.ToString());
                clims.Add("userName", _result.Data.UserName);
                clims.Add("organizationId", _result.Data.OrganizationId.ToString());
                clims.Add("roleIds", JsonConvert.SerializeObject(_result.Data.RoleIdList));
                var token = this._jwt.GetToken(clims);
                return Ok(ActionResponse.Succeed(new { token.token, token.expires, roleIds = _result.Data.RoleIdList }));
            }
    View Code
  • 相关阅读:
    ionic app打包和签名
    js时间戳与日期格式的相互转换
    js获取选中日期的当周的周一和周日
    Error occurred during initialization of VM Could not reserve enough space for 2097152KB object heap
    CSS媒体查询 @media
    [ng:areq] Argument 'XXXXCtrl' is not a function, got undefined
    plsql如何导出查询结果
    angularjs的$http请求方式
    JQuery请求数据的方式
    后台返回xml格式转json
  • 原文地址:https://www.cnblogs.com/SmilePastaLi/p/15702931.html
Copyright © 2020-2023  润新知