Open Closed

'Authorization failed! Given policy has not granted.' on [AllowAnonymous] #470


User avatar
0
ab created
  • ABP Framework version: v3.2.0
  • UI type: MVC
  • Tiered (MVC) or Identity Server Seperated (Angular): no
  • Exception message and stack trace:

Hello, I have following scenario: I have to build a custom registration page for a specific type of users. Anoynmous Users should register themselves. For this I implemented a method that checks if the user already exists and if yes it will invaldiate the object. I marked the Razor Page and the method with the AllowAnonymous attribute but I receive the error message below within the trace:

Volo.Abp.Authorization.AbpAuthorizationException HResult=0x80131500 Message=Authorization failed! Given policy has not granted. Source=Volo.Abp.Authorization StackTrace: at Microsoft.AspNetCore.Authorization.AbpAuthorizationServiceExtensions.d__15.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Authorization.MethodInvocationAuthorizationService.d__3.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Authorization.AuthorizationInterceptor.d__3.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Authorization.AuthorizationInterceptor.d__2.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.<InterceptAsync>d__31.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Castle.DynamicProxy.AsyncInterceptorBase.<ProceedAsynchronous>d__141.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.d__7.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Auditing.AuditingInterceptor.d__3.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.<InterceptAsync>d__31.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Castle.DynamicProxy.AsyncInterceptorBase.<ProceedAsynchronous>d__141.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.d__7.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Validation.ValidationInterceptor.d__2.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.<InterceptAsync>d__31.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Castle.DynamicProxy.AsyncInterceptorBase.<ProceedAsynchronous>d__141.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.d__7.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Uow.UnitOfWorkInterceptor.d__3.MoveNext()

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.<InterceptAsync>d__31.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at ImmoRecommend.AsyncHelpers.<>c__DisplayClass1_01.<b__0>d.MoveNext() in C:\Users\abier\source\repos\ImmoRecommend\src\ImmoRecommend.Domain.Shared\AsyncHelpers.cs:line 57

<br> This exception was originally thrown at this call stack: [External Code] ImmoRecommend.AsyncHelpers.RunSync.AnonymousMethod__0(object) in AsyncHelpers.cs

* Steps to reproduce the issue:

[AllowAnonymous]

public class RegisterModel : ImmoRecommendPageModel
{
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}

//Register
var recommender = await _recommenderAppManager.CreateAsync(RecommenderRegisterView);
return Page();
}
}

ModelState.IsValid will call the validation

public class RecommenderRegisterView : IValidatableObject
{
[Required]
[EmailAddress]

public string EMail { get; set; }

[Required]
public string FirstName { get; set; }
[Required]

public string LastName { get; set; }

[Required]
[DataType(DataType.Password)]
public string Password { get; set; }


[AllowAnonymous]

IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{

//check if user already exists
var identityUserAppService = validationContext.GetRequiredService<IIdentityUserAppService>();
var existingIdentityUserDto = AsyncHelpers.RunSync<IdentityUserDto>(() => identityUserAppService.FindByEmailAsync(EMail));



`if (existingIdentityUserDto != null)`
`{`
`yield return new ValidationResult(`
`"E-Mail Adresse bereits vergeben",`
`new[] { "EMail" }`
`);`
`}`
`}`
`}`


The reason seems to be clear. IIdentityUserAppService as a build in class requires authorization.

In order to make it work I build my own IdentutyUserAppService and inherited from the original IdentityUserAppService and set the method to anonymous

/// <summary>
/// Replaces the IdentutyUSerAppService
/// </summary>
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService), typeof(CustomIdentityUserAppService))]
public class CustomIdentityUserAppService : IdentityUserAppService
{
//...
//public CustomIdentityUserAppService(
//    IdentityUserManager userManager,
//    IIdentityUserRepository userRepository,
//    IGuidGenerator guidGenerator
//) : base(
//    userManager,
//    userRepository,
//    guidGenerator,
//{
//}
public CustomIdentityUserAppService(IdentityUserManager userManager, IIdentityUserRepository userRepository, IIdentityRoleRepository roleRepository, IOrganizationUnitRepository organizationUnitRepository,
IIdentityClaimTypeRepository identityClaimTypeRepository, IdentityTwoFactorManager identityTwoFactorManager) : base(userManager, userRepository, roleRepository, organizationUnitRepository, identityClaimTypeRepository, identityTwoFactorManager)
{
}
/// <summary>
/// Allow Anoynmous in the FindByEMailAsync method
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
[AllowAnonymous]
public override Task<IdentityUserDto> FindByEmailAsync(string email)
{
return base.FindByEmailAsync(email);
}}

This makes it work.

However, I don't like this kind of implementation, otherwise there is no reason to write a service of your own. Is there another way to set the access rights for IdentityUserAppService? I checked up the docs but cant find any proper solution here for me. Thanks in advance!

P.S: After years of absence I started developing in .NET again, Maybe I forgot some concepts behind


1 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    It is not good practice to use application services in ValidatableObject.Validate method.

    You can consider creating an anonymous application service and calling it in the Register page.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11