From e4c4a284571d51dcda373a0a1c047e634b17882d Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 12 Nov 2020 21:38:43 +0800 Subject: ... --- BackEnd/Timeline/Auth/Attribute.cs | 21 ------------- BackEnd/Timeline/Auth/MyAuthenticationHandler.cs | 9 +++--- .../Timeline/Auth/PermissionAuthorizeAttribute.cs | 30 +++++++++++++++++++ BackEnd/Timeline/Auth/PermissionPolicyProvider.cs | 35 ++++++++++++++++++++++ BackEnd/Timeline/Auth/PrincipalExtensions.cs | 10 ++++--- 5 files changed, 76 insertions(+), 29 deletions(-) delete mode 100644 BackEnd/Timeline/Auth/Attribute.cs create mode 100644 BackEnd/Timeline/Auth/PermissionAuthorizeAttribute.cs create mode 100644 BackEnd/Timeline/Auth/PermissionPolicyProvider.cs (limited to 'BackEnd/Timeline/Auth') diff --git a/BackEnd/Timeline/Auth/Attribute.cs b/BackEnd/Timeline/Auth/Attribute.cs deleted file mode 100644 index 86d0109b..00000000 --- a/BackEnd/Timeline/Auth/Attribute.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Timeline.Entities; - -namespace Timeline.Auth -{ - public class AdminAuthorizeAttribute : AuthorizeAttribute - { - public AdminAuthorizeAttribute() - { - Roles = UserRoles.Admin; - } - } - - public class UserAuthorizeAttribute : AuthorizeAttribute - { - public UserAuthorizeAttribute() - { - Roles = UserRoles.User; - } - } -} diff --git a/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs b/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs index 3c97c329..b5e22a14 100644 --- a/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs +++ b/BackEnd/Timeline/Auth/MyAuthenticationHandler.cs @@ -17,6 +17,7 @@ namespace Timeline.Auth { public const string Scheme = "Bearer"; public const string DisplayName = "My Jwt Auth Scheme"; + public const string PermissionClaimName = "Permission"; } public class MyAuthenticationOptions : AuthenticationSchemeOptions @@ -78,12 +79,12 @@ namespace Timeline.Auth try { - var userInfo = await _userTokenManager.VerifyToken(token); + var user = await _userTokenManager.VerifyToken(token); var identity = new ClaimsIdentity(AuthenticationConstants.Scheme); - identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userInfo.Id!.Value.ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Integer64)); - identity.AddClaim(new Claim(identity.NameClaimType, userInfo.Username, ClaimValueTypes.String)); - identity.AddClaims(UserRoleConvert.ToArray(userInfo.Administrator!.Value).Select(role => new Claim(identity.RoleClaimType, role, ClaimValueTypes.String))); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Integer64)); + identity.AddClaim(new Claim(identity.NameClaimType, user.Username, ClaimValueTypes.String)); + identity.AddClaims(user.Permissions.Select(permission => new Claim(AuthenticationConstants.PermissionClaimName, permission.ToString(), ClaimValueTypes.String))); var principal = new ClaimsPrincipal(); principal.AddIdentity(identity); diff --git a/BackEnd/Timeline/Auth/PermissionAuthorizeAttribute.cs b/BackEnd/Timeline/Auth/PermissionAuthorizeAttribute.cs new file mode 100644 index 00000000..3df8dee5 --- /dev/null +++ b/BackEnd/Timeline/Auth/PermissionAuthorizeAttribute.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Authorization; +using System; +using System.Linq; +using Timeline.Services; + +namespace Timeline.Auth +{ + public class PermissionAuthorizeAttribute : AuthorizeAttribute + { + public PermissionAuthorizeAttribute() + { + + } + + public PermissionAuthorizeAttribute(params UserPermission[] permissions) + { + Permissions = permissions; + } + + public UserPermission[] Permissions + { + get => Policy == null ? Array.Empty() : Policy[PermissionPolicyProvider.PolicyPrefix.Length..].Split(',') + .Select(s => Enum.Parse(s)).ToArray(); + set + { + Policy = $"{PermissionPolicyProvider.PolicyPrefix}{string.Join(',', value)}"; + } + } + } +} diff --git a/BackEnd/Timeline/Auth/PermissionPolicyProvider.cs b/BackEnd/Timeline/Auth/PermissionPolicyProvider.cs new file mode 100644 index 00000000..12a4fcd5 --- /dev/null +++ b/BackEnd/Timeline/Auth/PermissionPolicyProvider.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization.Infrastructure; +using System; +using System.Threading.Tasks; + +namespace Timeline.Auth +{ + public class PermissionPolicyProvider : IAuthorizationPolicyProvider + { + public const string PolicyPrefix = "Permission-"; + + public Task GetDefaultPolicyAsync() + { + return Task.FromResult(new AuthorizationPolicyBuilder(AuthenticationConstants.Scheme).RequireAuthenticatedUser().Build()); + } + + public Task GetFallbackPolicyAsync() + { + return Task.FromResult(null); + } + + public Task GetPolicyAsync(string policyName) + { + if (policyName.StartsWith(PolicyPrefix, StringComparison.OrdinalIgnoreCase)) + { + var permissions = policyName[PolicyPrefix.Length..].Split(','); + + var policy = new AuthorizationPolicyBuilder(AuthenticationConstants.Scheme); + policy.AddRequirements(new ClaimsAuthorizationRequirement(AuthenticationConstants.PermissionClaimName, permissions)); + return Task.FromResult(policy.Build()); + } + return Task.FromResult(null); + } + } +} diff --git a/BackEnd/Timeline/Auth/PrincipalExtensions.cs b/BackEnd/Timeline/Auth/PrincipalExtensions.cs index ad7a887f..9f86e8ac 100644 --- a/BackEnd/Timeline/Auth/PrincipalExtensions.cs +++ b/BackEnd/Timeline/Auth/PrincipalExtensions.cs @@ -1,13 +1,15 @@ -using System.Security.Principal; -using Timeline.Entities; +using System; +using System.Security.Claims; +using Timeline.Services; namespace Timeline.Auth { internal static class PrincipalExtensions { - internal static bool IsAdministrator(this IPrincipal principal) + internal static bool HasPermission(this ClaimsPrincipal principal, UserPermission permission) { - return principal.IsInRole(UserRoles.Admin); + return principal.HasClaim( + claim => claim.Type == AuthenticationConstants.PermissionClaimName && string.Equals(claim.Value, permission.ToString(), StringComparison.InvariantCultureIgnoreCase)); } } } -- cgit v1.2.3