public async Task SetPasswordAsync(Utilizer utilizer, string membershipId, string resetToken, string usernameOrEmailAddress, string password) { if (string.IsNullOrEmpty(usernameOrEmailAddress)) { throw ErtisAuthException.ValidationError(new [] { "Username or email required!" }); } var membership = await this.membershipService.GetAsync(membershipId); if (membership == null) { throw ErtisAuthException.MembershipNotFound(membershipId); } var user = await this.GetUserWithPasswordAsync(usernameOrEmailAddress, usernameOrEmailAddress, membershipId); if (user == null) { throw ErtisAuthException.UserNotFound(usernameOrEmailAddress, "username or email_address"); } if (utilizer.Role == Rbac.ReservedRoles.Administrator || utilizer.Id == user.Id) { if (this.jwtService.TryDecodeToken(resetToken, out var securityToken)) { var expireTime = securityToken.ValidTo.ToLocalTime(); if (DateTime.Now > expireTime) { // Token was expired! throw ErtisAuthException.TokenWasExpired(); } await this.ChangePasswordAsync(utilizer, membershipId, user.Id, password); } else { // Reset token could not decoded! throw ErtisAuthException.InvalidToken(); } } else { throw ErtisAuthException.AccessDenied("Unauthorized access"); } }
private void VerifyRolePermissions(Role role, string subjectId, HttpContext httpContext) { var endpoint = httpContext.GetEndpoint(); // Subject var rbacSubjectSegment = new RbacSegment(subjectId); // Resource var rbacResourceSegment = RbacSegment.All; var resourceMetadata = endpoint?.Metadata?.FirstOrDefault(x => x.GetType() == typeof(RbacResourceAttribute)); if (resourceMetadata is RbacResourceAttribute rbacResourceAttribute) { rbacResourceSegment = rbacResourceAttribute.ResourceSegment; } // Action var rbacActionSegment = RbacSegment.All; var actionMetadata = endpoint?.Metadata?.FirstOrDefault(x => x.GetType() == typeof(RbacActionAttribute)); if (actionMetadata is RbacActionAttribute rbacActionAttribute) { rbacActionSegment = rbacActionAttribute.ActionSegment; } // Object var rbacObjectSegment = RbacSegment.All; var objectMetadata = endpoint?.Metadata?.FirstOrDefault(x => x.GetType() == typeof(RbacObjectAttribute)); var routeData = httpContext.GetRouteData(); if (routeData?.Values != null && objectMetadata is RbacObjectAttribute rbacObjectAttribute) { if (routeData.Values.ContainsKey(rbacObjectAttribute.RouteParameterName)) { var rbacObject = routeData.Values[rbacObjectAttribute.RouteParameterName]; rbacObjectSegment = new RbacSegment(rbacObject.ToString()); } } var rbac = new Rbac(rbacSubjectSegment, rbacResourceSegment, rbacActionSegment, rbacObjectSegment); if (!role.HasPermission(rbac)) { throw ErtisAuthException.AccessDenied("Your authorization role is unauthorized for this action"); } }
public async Task <ResetPasswordToken> ResetPasswordAsync(Utilizer utilizer, string membershipId, string usernameOrEmailAddress) { if (string.IsNullOrEmpty(usernameOrEmailAddress)) { throw ErtisAuthException.ValidationError(new [] { "Username or email required!" }); } var membership = await this.membershipService.GetAsync(membershipId); if (membership == null) { throw ErtisAuthException.MembershipNotFound(membershipId); } var user = await this.GetUserWithPasswordAsync(usernameOrEmailAddress, usernameOrEmailAddress, membershipId); if (user == null) { throw ErtisAuthException.UserNotFound(usernameOrEmailAddress, "username or email_address"); } if (utilizer.Role == Rbac.ReservedRoles.Administrator || utilizer.Id == user.Id) { var tokenClaims = new TokenClaims(Guid.NewGuid().ToString(), user, membership); tokenClaims.AddClaim("token_type", "reset_token"); var resetToken = this.jwtService.GenerateToken(tokenClaims, HashAlgorithms.SHA2_256, Encoding.UTF8); var resetPasswordToken = new ResetPasswordToken(resetToken, TimeSpan.FromHours(1)); await this.eventService.FireEventAsync(this, new ErtisAuthEvent { EventType = ErtisAuthEventType.UserPasswordReset, UtilizerId = user.Id, Document = resetPasswordToken, MembershipId = membershipId }); return(resetPasswordToken); } else { throw ErtisAuthException.AccessDenied("Unauthorized access"); } }
private async Task <Utilizer> CheckAuthorizationAsync() { var token = this.Request.GetTokenFromHeader(out var tokenType); if (string.IsNullOrEmpty(token)) { throw ErtisAuthException.AuthorizationHeaderMissing(); } if (string.IsNullOrEmpty(tokenType)) { throw ErtisAuthException.UnsupportedTokenType(); } TokenTypeExtensions.TryParseTokenType(tokenType, out var _tokenType); switch (_tokenType) { case SupportedTokenTypes.None: throw ErtisAuthException.UnsupportedTokenType(); case SupportedTokenTypes.Basic: var basicToken = new BasicToken(token); var applicationId = token.Split(':')[0]; var getApplicationResponse = await this.applicationService.GetApplicationAsync(applicationId, basicToken); if (getApplicationResponse.IsSuccess) { var rbacDefinition = this.Context.GetRbacDefinition(getApplicationResponse.Data.Id); var rbac = $"{rbacDefinition.Resource}.{rbacDefinition.Action}"; var isPermittedForAction = await this.roleService.CheckPermissionAsync(rbac, basicToken); if (!isPermittedForAction) { throw ErtisAuthException.AccessDenied($"Token owner role is not permitted for this resource/action ({rbac})"); } return(new Utilizer { Id = getApplicationResponse.Data.Id, Username = getApplicationResponse.Data.Name, Type = tokenType == "Basic" ? Utilizer.UtilizerType.Application : Utilizer.UtilizerType.User, Role = getApplicationResponse.Data.Role, Token = token, TokenType = _tokenType }); } else { var errorMessage = getApplicationResponse.Message; if (ResponseHelper.TryParseError(getApplicationResponse.Message, out var error)) { errorMessage = error.Message; } throw ErtisAuthException.Unauthorized(errorMessage); } case SupportedTokenTypes.Bearer: var bearerToken = BearerToken.CreateTemp(token); var meResponse = await this.authenticationService.WhoAmIAsync(bearerToken); if (meResponse.IsSuccess) { var rbacDefinition = this.Context.GetRbacDefinition(meResponse.Data.Id); var rbac = $"{rbacDefinition.Resource}.{rbacDefinition.Action}"; var isPermittedForAction = await this.roleService.CheckPermissionAsync(rbac, bearerToken); if (!isPermittedForAction) { throw ErtisAuthException.AccessDenied($"Token owner role is not permitted for this resource/action ({rbac})"); } return(new Utilizer { Id = meResponse.Data.Id, Username = meResponse.Data.Username, Type = tokenType == "Basic" ? Utilizer.UtilizerType.Application : Utilizer.UtilizerType.User, Role = meResponse.Data.Role, Token = token, TokenType = _tokenType }); } else { var errorMessage = meResponse.Message; if (ResponseHelper.TryParseError(meResponse.Message, out var error)) { errorMessage = error.Message; } throw ErtisAuthException.Unauthorized(errorMessage); } default: throw ErtisAuthException.UnsupportedTokenType(); } }
private async Task <Utilizer> CheckAuthorizationAsync() { var token = this.Context.Request.GetTokenFromHeader(out var tokenType); if (string.IsNullOrEmpty(token)) { throw ErtisAuthException.AuthorizationHeaderMissing(); } if (string.IsNullOrEmpty(tokenType)) { throw ErtisAuthException.UnsupportedTokenType(); } TokenTypeExtensions.TryParseTokenType(tokenType, out var _tokenType); switch (_tokenType) { case SupportedTokenTypes.None: throw ErtisAuthException.UnsupportedTokenType(); case SupportedTokenTypes.Basic: var validationResult = await this.tokenService.VerifyBasicTokenAsync(token, false); if (!validationResult.IsValidated) { throw ErtisAuthException.InvalidToken(); } var application = validationResult.Application; Utilizer applicationUtilizer = application; if (!string.IsNullOrEmpty(application.Role)) { var role = await this.roleService.GetByNameAsync(application.Role, application.MembershipId); if (role != null) { var rbac = this.Context.GetRbacDefinition(application.Id); if (!this.accessControlService.HasPermission(role, rbac, applicationUtilizer)) { throw ErtisAuthException.AccessDenied("Your authorization role is unauthorized for this action"); } } } applicationUtilizer.Token = token; applicationUtilizer.TokenType = _tokenType; return(applicationUtilizer); case SupportedTokenTypes.Bearer: var verifyTokenResult = await this.tokenService.VerifyBearerTokenAsync(token, false); if (!verifyTokenResult.IsValidated) { throw ErtisAuthException.InvalidToken(); } var user = verifyTokenResult.User; Utilizer userUtilizer = user; if (!string.IsNullOrEmpty(user.Role)) { var role = await this.roleService.GetByNameAsync(user.Role, user.MembershipId); if (role != null) { var rbac = this.Context.GetRbacDefinition(user.Id); if (!this.accessControlService.HasPermission(role, rbac, userUtilizer)) { throw ErtisAuthException.AccessDenied("Your authorization role is unauthorized for this action"); } } } userUtilizer.Token = token; userUtilizer.TokenType = _tokenType; return(userUtilizer); default: throw ErtisAuthException.UnsupportedTokenType(); } }