auth improvements related to multi-tenancy
This commit is contained in:
		| @ -1,25 +1,23 @@ | ||||
| using Microsoft.AspNetCore.Identity; | ||||
| using Microsoft.AspNetCore.Identity; | ||||
| using Microsoft.Extensions.Options; | ||||
| using System.Security.Claims; | ||||
| using System.Threading.Tasks; | ||||
| using Oqtane.Models; | ||||
| using Oqtane.Shared; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Oqtane.Repository; | ||||
| using Oqtane.Infrastructure; | ||||
|  | ||||
| namespace Oqtane.Security | ||||
| { | ||||
|     public class ClaimsPrincipalFactory<TUser> : UserClaimsPrincipalFactory<TUser> where TUser : IdentityUser | ||||
|     { | ||||
|         private readonly IdentityOptions _options; | ||||
|         private readonly ITenantResolver _tenants; | ||||
|         private readonly ITenantManager _tenants; | ||||
|         private readonly IUserRepository _users; | ||||
|         private readonly IUserRoleRepository _userRoles; | ||||
|  | ||||
|         public ClaimsPrincipalFactory(UserManager<TUser> userManager, IOptions<IdentityOptions> optionsAccessor, ITenantResolver tenants, IUserRepository users, IUserRoleRepository userroles) : base(userManager, optionsAccessor) | ||||
|         public ClaimsPrincipalFactory(UserManager<TUser> userManager, IOptions<IdentityOptions> optionsAccessor, ITenantManager tenants, IUserRepository users, IUserRoleRepository userroles) : base(userManager, optionsAccessor) | ||||
|         { | ||||
|             _options = optionsAccessor.Value; | ||||
|             _tenants = tenants; | ||||
|             _users = users;  | ||||
|             _userRoles = userroles; | ||||
| @ -27,33 +25,20 @@ namespace Oqtane.Security | ||||
|  | ||||
|         protected override async Task<ClaimsIdentity> GenerateClaimsAsync(TUser identityuser) | ||||
|         { | ||||
|             var id = await base.GenerateClaimsAsync(identityuser); | ||||
|             var identity = await base.GenerateClaimsAsync(identityuser); | ||||
|  | ||||
|             User user = _users.GetUser(identityuser.UserName); | ||||
|             if (user != null) | ||||
|             { | ||||
|                 id.AddClaim(new Claim(ClaimTypes.PrimarySid, user.UserId.ToString())); | ||||
|                 Alias alias = _tenants.GetAlias(); | ||||
|                 List<UserRole> userroles = _userRoles.GetUserRoles(user.UserId, alias.SiteId).ToList(); | ||||
|                 foreach (UserRole userrole in userroles) | ||||
|                 if (alias != null) | ||||
|                 { | ||||
|                     id.AddClaim(new Claim(_options.ClaimsIdentity.RoleClaimType, userrole.Role.Name)); | ||||
|                     // host users are members of every site | ||||
|                     if (userrole.Role.Name == RoleNames.Host) | ||||
|                     { | ||||
|                         if (userroles.Where(item => item.Role.Name == RoleNames.Registered).FirstOrDefault() == null) | ||||
|                         { | ||||
|                             id.AddClaim(new Claim(_options.ClaimsIdentity.RoleClaimType, RoleNames.Registered)); | ||||
|                         } | ||||
|                         if (userroles.Where(item => item.Role.Name == RoleNames.Admin).FirstOrDefault() == null) | ||||
|                         { | ||||
|                             id.AddClaim(new Claim(_options.ClaimsIdentity.RoleClaimType, RoleNames.Admin)); | ||||
|                         } | ||||
|                     } | ||||
|                     List<UserRole> userroles = _userRoles.GetUserRoles(user.UserId, alias.SiteId).ToList(); | ||||
|                     identity = UserSecurity.CreateClaimsIdentity(alias, user, userroles); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return id; | ||||
|             return identity; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
							
								
								
									
										64
									
								
								Oqtane.Server/Security/PrincipalValidator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Oqtane.Server/Security/PrincipalValidator.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| using System.Linq; | ||||
| using System.Security.Claims; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Authentication.Cookies; | ||||
| using Oqtane.Infrastructure; | ||||
| using Oqtane.Repository; | ||||
| using Oqtane.Models; | ||||
| using System.Collections.Generic; | ||||
| using Microsoft.Extensions.Configuration; | ||||
|  | ||||
| namespace Oqtane.Security | ||||
| { | ||||
|     public static class PrincipalValidator | ||||
|     { | ||||
|         public static Task ValidateAsync(CookieValidatePrincipalContext context) | ||||
|         { | ||||
|             if (context != null && context.Principal.Identity.IsAuthenticated) | ||||
|             { | ||||
|                 // check if framework is installed | ||||
|                 var config = context.HttpContext.RequestServices.GetService(typeof(IConfiguration)) as IConfiguration; | ||||
|                 if (!string.IsNullOrEmpty(config.GetConnectionString("DefaultConnection"))) | ||||
|                 { | ||||
|                     var tenantManager = context.HttpContext.RequestServices.GetService(typeof(ITenantManager)) as ITenantManager; | ||||
|                     var alias = tenantManager.GetAlias(); | ||||
|                     if (alias != null) | ||||
|                     { | ||||
|                         // verify principal was authenticated for current tenant | ||||
|                         if (context.Principal.Claims.First(item => item.Type == ClaimTypes.GroupSid)?.Value != alias.AliasId.ToString()) | ||||
|                         { | ||||
|                             // tenant agnostic requests must be ignored  | ||||
|                             string path = context.Request.Path.ToString().ToLower(); | ||||
|                             if (path.StartsWith("/_blazor") || path.StartsWith("/api/installation/") || path.StartsWith("/api/alias/name/")) | ||||
|                             { | ||||
|                                 return Task.CompletedTask; | ||||
|                             } | ||||
|  | ||||
|                             // refresh principal | ||||
|                             var userRepository = context.HttpContext.RequestServices.GetService(typeof(IUserRepository)) as IUserRepository; | ||||
|                             var userRoleRepository = context.HttpContext.RequestServices.GetService(typeof(IUserRoleRepository)) as IUserRoleRepository; | ||||
|  | ||||
|                             User user = userRepository.GetUser(context.Principal.Identity.Name); | ||||
|                             if (user != null) | ||||
|                             { | ||||
|                                 List<UserRole> userroles = userRoleRepository.GetUserRoles(user.UserId, alias.SiteId).ToList(); | ||||
|                                 var identity = UserSecurity.CreateClaimsIdentity(alias, user, userroles); | ||||
|                                 context.ReplacePrincipal(new ClaimsPrincipal(identity)); | ||||
|                                 context.ShouldRenew = true; | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 context.RejectPrincipal(); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         context.RejectPrincipal(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Oqtane.Models; | ||||
| using System.Linq; | ||||
| using System.Security.Claims; | ||||
| @ -17,40 +17,41 @@ namespace Oqtane.Security | ||||
|             _accessor = accessor; | ||||
|         } | ||||
|  | ||||
|         public bool IsAuthorized(ClaimsPrincipal user, string entityName, int entityId, string permissionName) | ||||
|         public bool IsAuthorized(ClaimsPrincipal principal, string entityName, int entityId, string permissionName) | ||||
|         { | ||||
|             return IsAuthorized(user, permissionName, _permissions.GetPermissionString(entityName, entityId, permissionName)); | ||||
|             return IsAuthorized(principal, permissionName, _permissions.GetPermissionString(entityName, entityId, permissionName)); | ||||
|         } | ||||
|  | ||||
|         public bool IsAuthorized(ClaimsPrincipal user, string permissionName, string permissions) | ||||
|         public bool IsAuthorized(ClaimsPrincipal principal, string permissionName, string permissions) | ||||
|         { | ||||
|             return UserSecurity.IsAuthorized(GetUser(user), permissionName, permissions); | ||||
|             return UserSecurity.IsAuthorized(GetUser(principal), permissionName, permissions); | ||||
|         } | ||||
|  | ||||
|         public User GetUser(ClaimsPrincipal user) | ||||
|         public User GetUser(ClaimsPrincipal principal) | ||||
|         { | ||||
|             User resultUser = new User(); | ||||
|             resultUser.Username = ""; | ||||
|             resultUser.IsAuthenticated = false; | ||||
|             resultUser.UserId = -1; | ||||
|             resultUser.Roles = ""; | ||||
|             User user = new User(); | ||||
|             user.IsAuthenticated = false; | ||||
|             user.Username = ""; | ||||
|             user.UserId = -1; | ||||
|             user.Roles = ""; | ||||
|  | ||||
|             if (user == null) return resultUser; | ||||
|             if (principal == null) return user; | ||||
|  | ||||
|             resultUser.Username = user.Identity.Name; | ||||
|             resultUser.IsAuthenticated = user.Identity.IsAuthenticated; | ||||
|             var idclaim = user.Claims.FirstOrDefault(item => item.Type == ClaimTypes.PrimarySid); | ||||
|             if (idclaim != null) | ||||
|             user.IsAuthenticated = principal.Identity.IsAuthenticated; | ||||
|             if (user.IsAuthenticated) | ||||
|             { | ||||
|                 resultUser.UserId = int.Parse(idclaim.Value); | ||||
|                 foreach (var claim in user.Claims.Where(item => item.Type == ClaimTypes.Role)) | ||||
|                 user.Username = principal.Identity.Name; | ||||
|                 if (principal.Claims.Any(item => item.Type == ClaimTypes.PrimarySid)) | ||||
|                 { | ||||
|                     resultUser.Roles += claim.Value + ";"; | ||||
|                     user.UserId = int.Parse(principal.Claims.First(item => item.Type == ClaimTypes.PrimarySid).Value); | ||||
|                 } | ||||
|  | ||||
|                 if (resultUser.Roles != "") resultUser.Roles = ";" + resultUser.Roles; | ||||
|                 foreach (var claim in principal.Claims.Where(item => item.Type == ClaimTypes.Role)) | ||||
|                 { | ||||
|                     user.Roles += claim.Value + ";"; | ||||
|                 } | ||||
|                 if (user.Roles != "") user.Roles = ";" + user.Roles; | ||||
|             } | ||||
|             return resultUser; | ||||
|             return user; | ||||
|         } | ||||
|  | ||||
|         public User GetUser() | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Shaun Walker
					Shaun Walker