public async Task <object> GetJwtToken3(string name = "", string pass = "") { string jwtStr = string.Empty; if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass)) { return(new JsonResult(new { Status = false, message = "用户名或密码不能为空" })); } pass = MD5Helper.MD5Encrypt32(pass); var user = await _sysUserInfoServices.Query(d => d.uLoginName == name && d.uLoginPWD == pass); if (user.Count > 0) { var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass); //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 var claims = new List <Claim> { new Claim(ClaimTypes.Name, name), new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().uID.ToString()), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) }; claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); var data = await _roleModulePermissionServices.RoleModuleMaps(); var list = (from item in data where item.IsDeleted == false orderby item.Id select new PermissionItem { Url = item.Module?.LinkUrl, Role = item.Role?.Name, }).ToList(); _requirement.Permissions = list; //用户标识 var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); identity.AddClaims(claims); var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); return(new JsonResult(token)); } else { return(new JsonResult(new { success = false, message = "认证失败" })); } }
public async Task <MessageModel <TokenInfoViewModel> > GetJwtToken3(string name = "", string pass = "") { string jwtStr = string.Empty; if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass)) { return(Failed <TokenInfoViewModel>("用户名或密码不能为空")); } pass = MD5Helper.MD5Encrypt32(pass); var user = await _sysUserInfoServices.Query(d => d.uLoginName == name && d.uLoginPWD == pass && d.tdIsDelete == false); if (user.Count > 0) { var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass); //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 var claims = new List <Claim> { new Claim(ClaimTypes.Name, name), new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().uID.ToString()), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) }; claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); // ids4和jwt切换 // jwt if (!Permissions.IsUseIds4) { var data = await _roleModulePermissionServices.RoleModuleMaps(); var list = (from item in data where item.IsDeleted == false orderby item.Id select new PermissionItem { Url = item.Module?.LinkUrl, Role = item.Role?.Name.ObjToString(), }).ToList(); _requirement.Permissions = list; } var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement); return(Success(token, "获取成功")); } else { return(Failed <TokenInfoViewModel>("认证失败")); } }
public async Task <ApiResponseModel <JwtTokenDto> > GetJwtStr(string name, string pass) { string jwtStr = string.Empty; LogServer.WriteLog("用户登录:" + name); if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass)) { return(ApiResponse.Error <JwtTokenDto>("用户名或密码不能为空")); } pass = MD5Helper.MD5Encrypt32(pass); var userInfo = await _sysUserInfoServices.GetUserByLogin(name, pass); if (userInfo == null) { return(ApiResponse.Error <JwtTokenDto>("用户名不存在")); } var roleList = await _sysUserInfoServices.GetUserRoleByUserId(userInfo.uID); var claims = new List <Claim> { new Claim(ClaimTypes.Name, name), new Claim(JwtRegisteredClaimNames.Jti, userInfo.uID.ObjToString()), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) }; claims.AddRange(roleList.Select(s => new Claim(ClaimTypes.Role, s.Name))); var data = await _roleModulePermissionServices.RoleModuleMaps(); var list = data.OrderBy(m => m.Id).Select(m => new PermissionItem { Url = m.Module?.LinkUrl, Role = m.Role?.Name, }).ToList(); _requirement.Permissions = list; //用户标识 var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); identity.AddClaims(claims); var token = JwtHelper.BuildJwtToken(claims, _requirement); return(ApiResponse.Success(token)); }
// 重写异步处理程序 protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { var httpContext = _accessor.HttpContext; if (!requirement.Permissions.Any()) { var data = await _roleModulePermissionServices.RoleModuleMaps(); var list = new List <PermissionItem>(); // ids4和jwt切换 // ids4 if (Permissions.IsUseIds4) { list = (from item in data where item.IsDeleted == false orderby item.Id select new PermissionItem { Url = item.Module?.LinkUrl, Role = item.Role?.Id.ObjToString(), }).ToList(); } // jwt else { list = (from item in data where item.IsDeleted == false orderby item.Id select new PermissionItem { Url = item.Module?.LinkUrl, Role = item.Role?.Name.ObjToString(), }).ToList(); } requirement.Permissions = list; } //请求Url if (httpContext != null) { var questUrl = httpContext.Request.Path.Value.ToLower(); //判断请求是否停止 var handlers = httpContext.RequestServices.GetRequiredService <IAuthenticationHandlerProvider>(); foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync()) { if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync()) { context.Fail(); return; } } //判断请求是否拥有凭据,即有没有登录 var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync(); if (defaultAuthenticate != null) { var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name); //result?.Principal不为空即登录成功 if (result?.Principal != null) { // 将最新的角色和接口列表更新 // 这里暂时把代码移动到了Login获取token的api里,这样就不用每次都请求数据库,造成压力. // 但是这样有个问题,就是如果修改了某一个角色的菜单权限,不会立刻更新, // 需要让用户退出重新登录,如果你想实时更新,请把下边的注释打开即可. //var data = await _roleModulePermissionServices.RoleModuleMaps(); //var list = (from item in data // where item.IsDeleted == false // orderby item.Id // select new PermissionItem // { // Url = item.Module?.LinkUrl, // Role = item.Role?.Name, // }).ToList(); //requirement.Permissions = list; httpContext.User = result.Principal; //权限中是否存在请求的url //if (requirement.Permissions.GroupBy(g => g.Url).Where(w => w.Key?.ToLower() == questUrl).Count() > 0) //if (isMatchUrl) if (true) { // 获取当前用户的角色信息 var currentUserRoles = new List <string>(); // ids4和jwt切换 // ids4 if (Permissions.IsUseIds4) { currentUserRoles = (from item in httpContext.User.Claims where item.Type == "role" select item.Value).ToList(); } else { // jwt currentUserRoles = (from item in httpContext.User.Claims where item.Type == requirement.ClaimType select item.Value).ToList(); } var isMatchRole = false; var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role)); foreach (var item in permisssionRoles) { try { if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl) { isMatchRole = true; break; } } catch (Exception) { // ignored } } //验证权限 //if (currentUserRoles.Count <= 0 || requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role) && w.Url.ToLower() == questUrl).Count() <= 0) if (currentUserRoles.Count <= 0 || !isMatchRole) { context.Fail(); return; } } var isExp = false; // ids4和jwt切换 // ids4 if (Permissions.IsUseIds4) { isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) != null && DateHelper.StampToDateTime(httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now; } else { // jwt isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now; } if (isExp) { context.Succeed(requirement); } else { context.Fail(); return; } return; } } //判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败 if (!(questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType))) { context.Fail(); return; } } //context.Succeed(requirement); }
// 重写异步处理程序 protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { var httpContext = _accessor.HttpContext; // 获取系统中所有的角色和菜单的关系集合 if (!requirement.Permissions.Any()) { var data = await _roleModulePermissionServices.RoleModuleMaps(); var list = new List <PermissionItem>(); // ids4和jwt切换 // ids4 if (Permissions.IsUseIds4) { list = (from item in data where item.IsDeleted == false orderby item.Id select new PermissionItem { Url = item.Module?.LinkUrl, Role = item.Role?.Id.ObjToString(), }).ToList(); } // jwt else { list = (from item in data where item.IsDeleted == false orderby item.Id select new PermissionItem { Url = item.Module?.LinkUrl, Role = item.Role?.Name.ObjToString(), }).ToList(); } requirement.Permissions = list; } if (httpContext != null) { var questUrl = httpContext.Request.Path.Value.ToLower(); // 整体结构类似认证中间件UseAuthentication的逻辑,具体查看开源地址 // https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authentication/Core/src/AuthenticationMiddleware.cs httpContext.Features.Set <IAuthenticationFeature>(new AuthenticationFeature { OriginalPath = httpContext.Request.Path, OriginalPathBase = httpContext.Request.PathBase }); // Give any IAuthenticationRequestHandler schemes a chance to handle the request // 主要作用是: 判断当前是否需要进行远程验证,如果是就进行远程验证 var handlers = httpContext.RequestServices.GetRequiredService <IAuthenticationHandlerProvider>(); foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync()) { if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync()) { context.Fail(); return; } } //判断请求是否拥有凭据,即有没有登录 var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync(); if (defaultAuthenticate != null) { var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name); // 是否开启测试环境 var isTestCurrent = Appsettings.app(new string[] { "AppSettings", "UseLoadTest" }).ObjToBool(); //result?.Principal不为空即登录成功 if (result?.Principal != null || isTestCurrent) { if (!isTestCurrent) { httpContext.User = result.Principal; } // 获取当前用户的角色信息 var currentUserRoles = new List <string>(); // ids4和jwt切换 // ids4 if (Permissions.IsUseIds4) { currentUserRoles = (from item in httpContext.User.Claims where item.Type == "role" select item.Value).ToList(); } else { // jwt currentUserRoles = (from item in httpContext.User.Claims where item.Type == requirement.ClaimType select item.Value).ToList(); } var isMatchRole = false; var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role)); foreach (var item in permisssionRoles) { try { if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl) { isMatchRole = true; break; } } catch (Exception) { // ignored } } //验证权限 if (currentUserRoles.Count <= 0 || !isMatchRole) { context.Fail(); return; } var isExp = false; // ids4和jwt切换 // ids4 if (Permissions.IsUseIds4) { isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) != null && DateHelper.StampToDateTime(httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now; } else { // jwt isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now; } if (isExp) { context.Succeed(requirement); } else { context.Fail(); return; } return; } } //判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败 if (!(questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType))) { context.Fail(); return; } } //context.Succeed(requirement); }
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { var httpContext = _accessor.HttpContext; var permissionsList = requirement.Permissions; if (!permissionsList.Any()) { var data = await _roleModulePermissionServices.RoleModuleMaps(); var list = data.Select(m => new PermissionItem { Role = m.Role?.Id.ObjToString(), Url = m.Module?.LinkUrl }).ToList(); requirement.Permissions = list; } if (httpContext != null) { var requestUrl = httpContext.Request.Path.Value.ToLower(); //判断请求是否停止 TODO没懂 var handlers = httpContext.RequestServices.GetRequiredService <IAuthenticationHandlerProvider>(); foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync()) { if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync()) { context.Fail(); return; } } //“登录用户名”,“email”,“用户Id”就是ClaimType。 //“身份证号码:xxx”是一个claim,“姓名:xxx”是另一个claim。 //一组claims构成了一个identity,具有这些claims的identity就是 ClaimsIdentity ,驾照就是一种ClaimsIdentity,可以把ClaimsIdentity理解为“证件”,驾照是一种证件,护照也是一种证件。 //ClaimsIdentity的持有者就是 ClaimsPrincipal ,一个ClaimsPrincipal可以持有多个ClaimsIdentity,就比如一个人既持有驾照,又持有护照。 var defaultAuthticate = await Schemes.GetDefaultAuthenticateSchemeAsync(); if (defaultAuthticate == null) { context.Fail(); return; } var result = await httpContext.AuthenticateAsync(); if (result?.Principal == null) { context.Fail(); return; } // 获取当前用户的角色信息 var currentUserRoles = httpContext.User.Claims.Where(m => m.Type == requirement.ClaimType).Select(m => m.Value).ToList(); if (currentUserRoles.Count <= 0) { context.Fail(); return; } var isMatchRole = false; var currentUrls = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role)).Select(m => m.Url).ToList(); foreach (var item in currentUrls) { if (Regex.Match(requestUrl, item.ToLower())?.Value == requestUrl) { isMatchRole = true; break; } } //验证权限 //if (currentUserRoles.Count <= 0 || requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role) && w.Url.ToLower() == questUrl).Count() <= 0) if (!isMatchRole) { context.Fail(); return; } //判断过期时间(这里仅仅是最坏验证原则,你可以不要这个if else的判断,因为我们使用的官方验证,Token过期后上边的result?.Principal 就为 null 了,进不到这里了,因此这里其实可以不用验证过期时间,只是做最后严谨判断) if ((httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now) { context.Succeed(requirement); } else { context.Fail(); return; } //判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败 //if (!requestUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType)) //{ // context.Fail(); // return; //} } context.Succeed(requirement); }
/// <summary> /// 重写异步处理程序 /// </summary> /// <param name="context"></param> /// <param name="requirement"></param> /// <returns></returns> protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { var httpContext = _accessor.HttpContext; if (!requirement.Permissions.Any()) { var data = await _roleModulePermissionServices.RoleModuleMaps(); var list = (from item in data where item.IsDeleted == false orderby item.Id select new PermissionItem { Url = item.Module?.LinkUrl, Role = item.Role?.Id.ObjToString(), } ).ToList(); requirement.Permissions = list; } if (httpContext != null) { var questUrl = httpContext.Request.Path.Value.ToLower(); // 判断请求是否停止 var handlers = httpContext.RequestServices.GetRequiredService <IAuthenticationHandlerProvider>(); // 在AuthenticateAsync代码中,先查询Scheme,然后根据SchemeName查询Handle,再调用handle的同名方法。 foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync()) { if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync()) { context.Fail(); return; } } // 判断请求是否拥有凭据,即有没有登录 var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync(); if (defaultAuthenticate != null) { var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name); if (result?.Principal != null) { httpContext.User = result.Principal; if (true) { // 获取当前用户的角色信息 var currentUserRoles = (from item in httpContext.User.Claims where item.Type == requirement.ClaimType select item.Value).ToList(); var isMatchRole = false; var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role)); foreach (var item in permisssionRoles) { try { if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl) { isMatchRole = true; break; } } catch (Exception) { } } if (currentUserRoles.Count <= 0 || !isMatchRole) { context.Fail(); return; } } //判断过期时间(这里仅仅是最坏验证原则,你可以不要这个if else的判断,因为我们使用的官方验证,Token过期后上边的result?.Principal 就为 null 了,进不到这里了,因此这里其实可以不用验证过期时间,只是做最后严谨判断) if ((httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now) { context.Succeed(requirement); } else { context.Fail(); return; } return; } } // 判断没有登录时,是否访问登录的url,并且是post请求,并且是form表单提交类型,否则为失败 if (!questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType)) { context.Fail(); return; } } context.Succeed(requirement); }