init
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DouyinApi.Extensions.Authorizations.Behaviors
|
||||
{
|
||||
public interface IUserBehaviorService
|
||||
{
|
||||
|
||||
Task<bool> CreateOrUpdateUserAccessByUid();
|
||||
|
||||
Task<bool> RemoveAllUserAccessByUid();
|
||||
|
||||
Task<bool> CheckUserIsNormal();
|
||||
|
||||
Task<bool> CheckTokenIsNormal();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using DouyinApi.Common.HttpContextUser;
|
||||
using DouyinApi.IServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DouyinApi.Extensions.Authorizations.Behaviors
|
||||
{
|
||||
public class UserBehaviorService : IUserBehaviorService
|
||||
{
|
||||
private readonly IUser _user;
|
||||
private readonly ISysUserInfoServices _sysUserInfoServices;
|
||||
private readonly ILogger<UserBehaviorService> _logger;
|
||||
private readonly string _uid;
|
||||
private readonly string _token;
|
||||
|
||||
public UserBehaviorService(IUser user
|
||||
, ISysUserInfoServices sysUserInfoServices
|
||||
, ILogger<UserBehaviorService> logger)
|
||||
{
|
||||
_user = user;
|
||||
_sysUserInfoServices = sysUserInfoServices;
|
||||
_logger = logger;
|
||||
_uid = _user.ID.ObjToString();
|
||||
_token = _user.GetToken();
|
||||
}
|
||||
|
||||
|
||||
public Task<bool> CheckTokenIsNormal()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<bool> CheckUserIsNormal()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<bool> CreateOrUpdateUserAccessByUid()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<bool> RemoveAllUserAccessByUid()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
132
DouyinApi.Extensions/Authorizations/Helpers/JwtHelper.cs
Normal file
132
DouyinApi.Extensions/Authorizations/Helpers/JwtHelper.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using DouyinApi.Common;
|
||||
using DouyinApi.Common.AppConfig;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace DouyinApi.AuthHelper.OverWrite
|
||||
{
|
||||
public class JwtHelper
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 颁发JWT字符串
|
||||
/// </summary>
|
||||
/// <param name="tokenModel"></param>
|
||||
/// <returns></returns>
|
||||
public static string IssueJwt(TokenModelJwt tokenModel)
|
||||
{
|
||||
string iss = AppSettings.app(new string[] { "Audience", "Issuer" });
|
||||
string aud = AppSettings.app(new string[] { "Audience", "Audience" });
|
||||
string secret = AppSecretConfig.Audience_Secret_String;
|
||||
|
||||
//var claims = new Claim[] //old
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
/*
|
||||
* 特别重要:
|
||||
1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了!
|
||||
2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。
|
||||
*/
|
||||
|
||||
|
||||
|
||||
new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Iat, $"{DateTime.Now.DateToTimeStamp()}"),
|
||||
new Claim(JwtRegisteredClaimNames.Nbf,$"{DateTime.Now.DateToTimeStamp()}") ,
|
||||
//这个就是过期时间,目前是过期1000秒,可自定义,注意JWT有自己的缓冲过期时间
|
||||
new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds()}"),
|
||||
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(1000).ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Iss,iss),
|
||||
new Claim(JwtRegisteredClaimNames.Aud,aud),
|
||||
|
||||
//new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法
|
||||
};
|
||||
|
||||
// 可以将一个用户的多个角色全部赋予;
|
||||
// 作者:DX 提供技术支持;
|
||||
claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
|
||||
|
||||
|
||||
|
||||
//秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常)
|
||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
|
||||
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||
|
||||
var jwt = new JwtSecurityToken(
|
||||
issuer: iss,
|
||||
claims: claims,
|
||||
signingCredentials: creds);
|
||||
|
||||
var jwtHandler = new JwtSecurityTokenHandler();
|
||||
var encodedJwt = jwtHandler.WriteToken(jwt);
|
||||
|
||||
return encodedJwt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析
|
||||
/// </summary>
|
||||
/// <param name="jwtStr"></param>
|
||||
/// <returns></returns>
|
||||
public static TokenModelJwt SerializeJwt(string jwtStr)
|
||||
{
|
||||
var jwtHandler = new JwtSecurityTokenHandler();
|
||||
TokenModelJwt tokenModelJwt = new TokenModelJwt();
|
||||
|
||||
// token校验
|
||||
if (jwtStr.IsNotEmptyOrNull() && jwtHandler.CanReadToken(jwtStr))
|
||||
{
|
||||
|
||||
JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
|
||||
|
||||
object role;
|
||||
|
||||
jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
|
||||
|
||||
tokenModelJwt = new TokenModelJwt
|
||||
{
|
||||
Uid = (jwtToken.Id).ObjToLong(),
|
||||
Role = role != null ? role.ObjToString() : "",
|
||||
};
|
||||
}
|
||||
return tokenModelJwt;
|
||||
}
|
||||
|
||||
public static bool customSafeVerify(string token)
|
||||
{
|
||||
var jwtHandler = new JwtSecurityTokenHandler();
|
||||
var symmetricKeyAsBase64 = AppSecretConfig.Audience_Secret_String;
|
||||
var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
|
||||
var signingKey = new SymmetricSecurityKey(keyByteArray);
|
||||
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
|
||||
|
||||
var jwt = jwtHandler.ReadJwtToken(token);
|
||||
return jwt.RawSignature == Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(jwt.RawHeader + "." + jwt.RawPayload, signingCredentials);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 令牌
|
||||
/// </summary>
|
||||
public class TokenModelJwt
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public long Uid { get; set; }
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
public string Role { get; set; }
|
||||
/// <summary>
|
||||
/// 职能
|
||||
/// </summary>
|
||||
public string Work { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using DouyinApi.Model;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using DouyinApi.Common.HttpContextUser;
|
||||
|
||||
namespace DouyinApi.AuthHelper
|
||||
{
|
||||
public class ApiResponseHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
private readonly IUser _user;
|
||||
|
||||
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IUser user) : base(options, logger, encoder, clock)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
|
||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
|
||||
{
|
||||
Response.ContentType = "application/json";
|
||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject((new ApiResponse(StatusCode.CODE401)).MessageModel));
|
||||
}
|
||||
|
||||
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
|
||||
{
|
||||
Response.ContentType = "application/json";
|
||||
if (_user.MessageModel != null)
|
||||
{
|
||||
Response.StatusCode = _user.MessageModel.status;
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject(_user.MessageModel));
|
||||
}
|
||||
else
|
||||
{
|
||||
Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject((new ApiResponse(StatusCode.CODE403)).MessageModel));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
DouyinApi.Extensions/Authorizations/Policys/JwtToken.cs
Normal file
45
DouyinApi.Extensions/Authorizations/Policys/JwtToken.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using DouyinApi.Model.ViewModels;
|
||||
using System;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace DouyinApi.AuthHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// JWTToken生成类
|
||||
/// </summary>
|
||||
public class JwtToken
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取基于JWT的Token
|
||||
/// </summary>
|
||||
/// <param name="claims">需要在登录的时候配置</param>
|
||||
/// <param name="permissionRequirement">在startup中定义的参数</param>
|
||||
/// <returns></returns>
|
||||
public static TokenInfoViewModel BuildJwtToken(Claim[] claims, PermissionRequirement permissionRequirement)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
// 实例化JwtSecurityToken
|
||||
var jwt = new JwtSecurityToken(
|
||||
issuer: permissionRequirement.Issuer,
|
||||
audience: permissionRequirement.Audience,
|
||||
claims: claims,
|
||||
notBefore: now,
|
||||
expires: now.Add(permissionRequirement.Expiration),
|
||||
signingCredentials: permissionRequirement.SigningCredentials
|
||||
);
|
||||
// 生成 Token
|
||||
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
|
||||
|
||||
//打包返回前台
|
||||
var responseJson = new TokenInfoViewModel
|
||||
{
|
||||
success = true,
|
||||
token = encodedJwt,
|
||||
expires_in = permissionRequirement.Expiration.TotalSeconds,
|
||||
token_type = "Bearer"
|
||||
};
|
||||
return responseJson;
|
||||
}
|
||||
}
|
||||
}
|
||||
269
DouyinApi.Extensions/Authorizations/Policys/PermissionHandler.cs
Normal file
269
DouyinApi.Extensions/Authorizations/Policys/PermissionHandler.cs
Normal file
@@ -0,0 +1,269 @@
|
||||
using DouyinApi.Common;
|
||||
using DouyinApi.Common.Helper;
|
||||
using DouyinApi.Common.HttpContextUser;
|
||||
using DouyinApi.IServices;
|
||||
using DouyinApi.Model;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using DouyinApi.Common.Swagger;
|
||||
using DouyinApi.Model.Models;
|
||||
|
||||
namespace DouyinApi.AuthHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 权限授权处理器
|
||||
/// </summary>
|
||||
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证方案提供对象
|
||||
/// </summary>
|
||||
public IAuthenticationSchemeProvider Schemes { get; set; }
|
||||
|
||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
private readonly ISysUserInfoServices _userServices;
|
||||
private readonly IUser _user;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数注入
|
||||
/// </summary>
|
||||
/// <param name="schemes"></param>
|
||||
/// <param name="roleModulePermissionServices"></param>
|
||||
/// <param name="accessor"></param>
|
||||
/// <param name="userServices"></param>
|
||||
/// <param name="user"></param>
|
||||
public PermissionHandler(IAuthenticationSchemeProvider schemes,
|
||||
IRoleModulePermissionServices roleModulePermissionServices, IHttpContextAccessor accessor,
|
||||
ISysUserInfoServices userServices, IUser user)
|
||||
{
|
||||
_accessor = accessor;
|
||||
_userServices = userServices;
|
||||
_user = user;
|
||||
Schemes = schemes;
|
||||
_roleModulePermissionServices = roleModulePermissionServices;
|
||||
}
|
||||
|
||||
// 重写异步处理程序
|
||||
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 || httpContext.IsSuccessSwagger())
|
||||
{
|
||||
if (!isTestCurrent) httpContext.User = result.Principal;
|
||||
|
||||
//应该要先校验用户的信息 再校验菜单权限相关的
|
||||
// JWT模式下校验当前用户状态
|
||||
// IDS4也可以校验,可以通过服务或者接口形式
|
||||
SysUserInfo user = new();
|
||||
if (!Permissions.IsUseIds4)
|
||||
{
|
||||
//校验用户
|
||||
user = await _userServices.QueryById(_user.ID, true);
|
||||
if (user == null)
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户不存在或已被删除").MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.IsDeleted)
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户已被删除,禁止登录!").MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.Enable)
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "用户已被禁用!禁止登录!").MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 判断token是否过期,过期则重新登录
|
||||
var isExp = false;
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
isExp = (httpContext.User.Claims.FirstOrDefault(s => s.Type == "exp")?.Value) != null &&
|
||||
DateHelper.StampToDateTime(httpContext.User.Claims
|
||||
.FirstOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
// jwt
|
||||
isExp =
|
||||
(httpContext.User.Claims.FirstOrDefault(s => s.Type == ClaimTypes.Expiration)
|
||||
?.Value) != null &&
|
||||
DateTime.Parse(httpContext.User.Claims
|
||||
.FirstOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now;
|
||||
}
|
||||
|
||||
if (!isExp)
|
||||
{
|
||||
context.Fail(new AuthorizationFailureReason(this, "授权已过期,请重新授权"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//校验签发时间
|
||||
if (!Permissions.IsUseIds4)
|
||||
{
|
||||
var value = httpContext.User.Claims
|
||||
.FirstOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
||||
if (value != null)
|
||||
{
|
||||
if (user.CriticalModifyTime > value.ObjToDate())
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "很抱歉,授权已失效,请重新授权")
|
||||
.MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户的角色信息
|
||||
var currentUserRoles = new List<string>();
|
||||
currentUserRoles = (from item in httpContext.User.Claims
|
||||
where item.Type == ClaimTypes.Role
|
||||
select item.Value).ToList();
|
||||
if (!currentUserRoles.Any())
|
||||
{
|
||||
currentUserRoles = (from item in httpContext.User.Claims
|
||||
where item.Type == "role"
|
||||
select item.Value).ToList();
|
||||
}
|
||||
|
||||
//超级管理员 默认拥有所有权限
|
||||
if (currentUserRoles.All(s => s != "SuperAdmin"))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
context.Succeed(requirement);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
namespace DouyinApi.AuthHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户或角色或其他凭据实体,就像是订单详情一样
|
||||
/// 之前的名字是 Permission
|
||||
/// </summary>
|
||||
public class PermissionItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户或角色或其他凭据名称
|
||||
/// </summary>
|
||||
public virtual string Role { get; set; }
|
||||
/// <summary>
|
||||
/// 请求Url
|
||||
/// </summary>
|
||||
public virtual string Url { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DouyinApi.AuthHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 必要参数类,类似一个订单信息
|
||||
/// 继承 IAuthorizationRequirement,用于设计自定义权限处理器PermissionHandler
|
||||
/// 因为AuthorizationHandler 中的泛型参数 TRequirement 必须继承 IAuthorizationRequirement
|
||||
/// </summary>
|
||||
public class PermissionRequirement : IAuthorizationRequirement
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户权限集合,一个订单包含了很多详情,
|
||||
/// 同理,一个网站的认证发行中,也有很多权限详情(这里是Role和URL的关系)
|
||||
/// </summary>
|
||||
public List<PermissionItem> Permissions { get; set; }
|
||||
/// <summary>
|
||||
/// 无权限action
|
||||
/// </summary>
|
||||
public string DeniedAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 认证授权类型
|
||||
/// </summary>
|
||||
public string ClaimType { internal get; set; }
|
||||
/// <summary>
|
||||
/// 请求路径
|
||||
/// </summary>
|
||||
public string LoginPath { get; set; } = "/Api/Login";
|
||||
/// <summary>
|
||||
/// 发行人
|
||||
/// </summary>
|
||||
public string Issuer { get; set; }
|
||||
/// <summary>
|
||||
/// 订阅人
|
||||
/// </summary>
|
||||
public string Audience { get; set; }
|
||||
/// <summary>
|
||||
/// 过期时间
|
||||
/// </summary>
|
||||
public TimeSpan Expiration { get; set; }
|
||||
/// <summary>
|
||||
/// 签名验证
|
||||
/// </summary>
|
||||
public SigningCredentials SigningCredentials { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 构造
|
||||
/// </summary>
|
||||
/// <param name="deniedAction">拒约请求的url</param>
|
||||
/// <param name="permissions">权限集合</param>
|
||||
/// <param name="claimType">声明类型</param>
|
||||
/// <param name="issuer">发行人</param>
|
||||
/// <param name="audience">订阅人</param>
|
||||
/// <param name="signingCredentials">签名验证实体</param>
|
||||
/// <param name="expiration">过期时间</param>
|
||||
public PermissionRequirement(string deniedAction, List<PermissionItem> permissions, string claimType, string issuer, string audience, SigningCredentials signingCredentials, TimeSpan expiration)
|
||||
{
|
||||
ClaimType = claimType;
|
||||
DeniedAction = deniedAction;
|
||||
Permissions = permissions;
|
||||
Issuer = issuer;
|
||||
Audience = audience;
|
||||
Expiration = expiration;
|
||||
SigningCredentials = signingCredentials;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user