Exemplo n.º 1
0
        /// <summary>
        /// 获取基于JWT的Token
        /// </summary>
        /// <param name="claims">需要在登陆的时候配置</param>
        /// <param name="requirement">在startup中定义的参数</param>
        /// <returns></returns>
        public static string IssueToken(Claim[] claims, AdmPolicyRequirement requirement)
        {
            var now = DateTime.Now;
            // 实例化JwtSecurityToken
            var jwt = new JwtSecurityToken(
                issuer: requirement.Issuer,
                audience: requirement.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(requirement.Expiration),
                signingCredentials: requirement.SigningCredentials
                );

            // 生成 Token
            return(new JwtSecurityTokenHandler().WriteToken(jwt));;
        }
Exemplo n.º 2
0
        public static AuthenticateInfo Get(LoginUserInfo user, AdmPolicyRequirement requirement, IDistributedCache cache = null)
        {
            var expirationSeconds = requirement.Expiration.TotalSeconds;
            var subjectId         = user.Id.ToString();
            var claims            = new List <Claim> {
                new Claim(JwtRegisteredClaimNames.Sub, subjectId),
                new Claim(ClaimTypes.NameIdentifier, subjectId),
                new Claim(JwtRegisteredClaimNames.AuthTime, DateTime.Now.ToString()),    //DateTime.UtcNow.ToString("o")
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(expirationSeconds).ToString())
            };

            if (!string.IsNullOrWhiteSpace(user.Name))
            {
                claims.Add(new Claim(JwtClaimTypes.Name, user.Name));
            }
            claims.AddRange(user.Roles.Select(s => new Claim(ClaimTypes.Role, s.Id.ToString())));

            var token = JwtToken.IssueToken(claims.ToArray(), requirement);

            if (cache != null)
            {
                //token白名单  一个用户只有一个token有效
                //需要启用AuthorizationSetup中代码
                //30天清理失效得key
                cache.SetString(subjectId, token, new DistributedCacheEntryOptions {
                    SlidingExpiration = TimeSpan.FromDays(30)
                });
            }
            return(new AuthenticateInfo()
            {
                AccessToken = token,
                TokenType = "Bearer",
                ExpireInSeconds = expirationSeconds,
                UserName = user.UserName,
                IsMaster = user.IsMaster,
                Name = user.Name,
                UserId = user.Id,
                Roles = user.Roles
            });
        }
Exemplo n.º 3
0
        public static void AddAuthorizationSetup(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            var secretKey    = AdmBootsApp.Configuration["Authentication:JwtBearer:SecurityKey"];
            var keyByteArray = Encoding.ASCII.GetBytes(secretKey);
            var signingKey   = new SymmetricSecurityKey(keyByteArray);
            var issuer       = AdmBootsApp.Configuration["Authentication:JwtBearer:Issuer"];
            var audience     = AdmBootsApp.Configuration["Authentication:JwtBearer:Audience"];

            var admPolicyRequirement = new AdmPolicyRequirement(
                ClaimTypes.Role,                                                   //基于角色的授权
                issuer,                                                            //发行人
                audience,                                                          //订阅人
                new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256), //签名凭据
                expiration: TimeSpan.FromDays(1)                                   //接口的过期时间 总的Token有效时间 = 接口的过期时间 + ClockSkew
                );

            //复杂的策略授权
            services.AddAuthorization(options => {
                options.AddPolicy(AdmConsts.POLICY,
                                  policy => policy.Requirements.Add(admPolicyRequirement));
            });

            //官方JWT认证
            //开启Bearer认证
            services.AddAuthentication(o => {
                o.DefaultScheme          = JwtBearerDefaults.AuthenticationScheme;
                o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                o.DefaultForbidScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            // 添加JwtBearer服务
            .AddJwtBearer(o => {
                //令牌验证参数
                o.TokenValidationParameters = new TokenValidationParameters {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = signingKey,
                    ValidateIssuer           = true,
                    ValidIssuer           = issuer,   //发行人
                    ValidateAudience      = true,
                    ValidAudience         = audience, //订阅人
                    ValidateLifetime      = true,
                    ClockSkew             = TimeSpan.Zero,
                    RequireExpirationTime = true,
                };
                o.Events = new JwtBearerEvents {
                    OnAuthenticationFailed = context => {
                        // 如果过期,则把<是否过期>添加到,返回头信息中
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("Token-Expired", "true");
                        }
                        return(Task.CompletedTask);
                    },
                    ////token白名单  一个用户只有一个token有效
                    //OnTokenValidated = context => {
                    //    var token = ((JwtSecurityToken)context.SecurityToken).RawData;
                    //    var uid = JwtToken.ReadJwtToken<int>(token);
                    //    var cache = context.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();
                    //    if (cache.GetString(uid.ToString()) != token) {
                    //        context.Fail("token不在白名单中");//返回401
                    //    }
                    //    return Task.CompletedTask;
                    //},
                    //对连接到集线器的用户进行身份验证 SignalR
                    //https://docs.microsoft.com/zh-cn/aspnet/core/signalr/authn-and-authz?view=aspnetcore-3.1
                    OnMessageReceived = context => {
                        if (!context.HttpContext.Request.Path.HasValue)
                        {
                            return(Task.CompletedTask);
                        }
                        var accessToken = context.Request.Query["access_token"];
                        //判断是Signalr的路径
                        var path = context.HttpContext.Request.Path;
                        if (!string.IsNullOrEmpty(accessToken) &&
                            (path.StartsWithSegments("/api/chatHub")))
                        {
                            context.Token = accessToken;
                        }
                        return(Task.CompletedTask);
                    }
                };
            });
            // 注入权限处理器
            services.AddScoped <IAuthorizationHandler, AdmAuthorizationHandler>();
            services.AddSingleton(admPolicyRequirement);
        }
Exemplo n.º 4
0
 public LoginController(IUserService userService, AdmPolicyRequirement requirement, IDistributedCache cache)
 {
     _userService = userService;
     _requirement = requirement;
     _cache       = cache;
 }