I can use to check if the User's -> Role -> OU has application permission? Something like User.Roles.OU.Any(x => x.AppPermission == this.Client_Id)
There is no such navigation property relationship, you need to get user roles's ou first.
you can refer to ABP code https://github.com/abpframework/abp/blob/dev/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs#L316
Ok, that makes sense :-)
You can see this https://abp.io/community/articles/how-to-add-a-custom-grant-type-in-openiddict.-6v0df94z
So I don't need to create a Custom Grant?
.
I just need to override the login page to verify the 6-digit code received by email via UserManager.GenerateUserTokenAsync(adminUser, "PasswordlessLoginProvider","passwordless-auth");
That should work, am I correct?
https://abp.io/docs/latest/framework/ui/mvc-razor-pages/customization-user-interface
Yes, it's easy to override the controller, thank you :-)
.
Should I use navigation One-2-Many OR should I use it as custom property similar to how ABP saves scopes in the ApplicationTable:["scp:roles","scp:profile","scp:phone","scp:email","scp:address"]
What is the correct approach from above? and is there any ABP trick I can use to check if the User's -> Role -> OU has application permission?
Something like User.Roles.OU.Any(x => x.AppPermission == this.Client_Id)
Hi,
Yes, you can override
TokenController.Password(password flow) and login model(code flow)
Thank you Liangshiwei,
While I am customising the entity, I am thinking of extending Organization Unit as it has User and Role both, the way I am thinking is to create for each loop in application to show as Application Name with checkboxes. Should I use navigation One-2-Many OR should I use it as custom property similar to how ABP saves scopes in the ApplicationTable:["scp:roles","scp:profile","scp:phone","scp:email","scp:address"]
. . however, How can I show it below next to Roles
. . Regarding Application permission I am confused as when a user tries to login into the application, doesn't AuthorizeController.cs kick in to check whether the user has access to the requested client_id?
So, do I need to inject code to check permission in each of the three below :
AuthorizeController.cs, TokenController.Password.cs TokenController.AuthorizationCode.cs
-- OR --
only AuthorizeController.cs is enough
Sorry, security is not my strongest, but trying to learn 🙈
Regards, Navneet
HI liangshiwei,
Do you mean to use the below to generate a token?
await UserManager.GenerateUserTokenAsync(adminUser, "PasswordlessLoginProvider","passwordless-auth");
In regards to the custom grant type, I have found the code below in Ticket no. 8041, this is two month old post and has claims and resources of the user.
Does this code look correct to you for my purpose, or do you think I should remove any unnecessary things as it does not have your suggested code: await SignInManager.SignInAsync(user, isPersistent: false);
public class EmpowermTokenExtensionGrant : ITokenExtensionGrant
{
public const string ExtensionGrantName = "PasswordlessLoginProvider";
public string Name => ExtensionGrantName;
public async Task<IActionResult> HandleAsync(ExtensionGrantContext context)
{
var userToken = context.Request.GetParameter("token").ToString();
if (string.IsNullOrEmpty(userToken))
{
return new ForbidResult(
new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme },
properties: new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidRequest
}!));
}
var userId = context.Request.GetParameter("userid").ToString();
if (string.IsNullOrEmpty(userId))
{
return new ForbidResult(
new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme },
properties: new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidRequest
}!));
}
var userManager = context.HttpContext.RequestServices.GetRequiredService<EmpowermIdentityUserManager>();
var user = await userManager.GetByIdAsync(userId);
if(!await UserManager.VerifyUserTokenAsync(user, "PasswordlessLoginProvider", "passwordless-auth", token))
{
return new ForbidResult(
new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme },
properties: new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidRequest
}!));
}
var userClaimsPrincipalFactory = context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<Volo.Abp.Identity.IdentityUser>>();
var claimsPrincipal = await userClaimsPrincipalFactory.CreateAsync(user);
claimsPrincipal.SetScopes(principal.GetScopes());
claimsPrincipal.SetResources(await GetResourcesAsync(context, principal.GetScopes()));
await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimsPrincipalManager>().HandleAsync(context.Request, claimsPrincipal);
return new Microsoft.AspNetCore.Mvc.SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, claimsPrincipal);
}
private async Task<IEnumerable<string>> GetResourcesAsync(ExtensionGrantContext context, ImmutableArray<string> scopes)
{
var resources = new List<string>();
if (!scopes.Any())
{
return resources;
}
await foreach (var resource in context.HttpContext.RequestServices.GetRequiredService<IOpenIddictScopeManager>().ListResourcesAsync(scopes))
{
resources.Add(resource);
}
return resources;
}
}
Thanks, Navneet
Thanks, Liangshiwei for sharing the link, it is a useful resource, but you need to go through it to understand.
Just trying to understand, if the custom grant is to validate the token, how can I generate it in the first place?
Also, how to make the login screen remove the password field if the user has opted for passwordless OTP, it needs to be dynamic to allow users with and without PasswordLess OTP
Thanks, Navneet
Hello Team,
I need to come up with a solution to limit access of users to the application, there are a few ways I can extend the entity via https://abp.io/docs/latest/framework/architecture/modularity/extending/module-entity-extensions of users and assign the Application or I can extend the Application and assign the application.
My question is where should I put debut to understand which point the user needs to be checked if that user has access to the application, I was trying to understand the code in: AuthorizeController.cs TokenController.Password.cs TokenController.XXXYY
and found that there is a code:
user = await UserManager.FindByNameAsync(request.Username);
Is this the correct place to intercept if any user is trying to use the Login Form or trying to generate Token by token endpoint?
Many thanks, Navneet
Hello Team,
I have a security requirement, is there any way can I assign IP addresses to OpenIddictApplicatin to allow and block based on IPs?
If something is not available out of the box, Any guide will be helpful like which place I can debug for incoming requests, it needs to be client-based not global access control.
Thanks, Navneet
Hi team,
I found a way to hook it up with UI by overriding the ApplicationAppService. However, I still need help to create "PasswordLess OTP" grant type
[Authorize(AbpOpenIddictProPermissions.Application.Default)]
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IApplicationAppService), typeof(ApplicationAppService), typeof(MyApplicationAppService))]
public class MyApplicationAppService : ApplicationAppService
{
public MyApplicationAppService(IOpenIddictApplicationManager applicationManager,
IOpenIddictApplicationRepository applicationRepository) : base(applicationManager, applicationRepository)
{
}
Hello Abp team,
Could you please guide me on how can I add a PasswordLess OTP grant type in the MVC application?
I have managed to create a checkbox "PasswordLess OTP" in OpenIddictApplication --> Create and Update UI by extending the entity, how to wire up the check box allow PasswordLess OTP grant type
Thanks, Navneet