- ABP Framework version: v8.2.1
- UI Type: Angular / MVC / Blazor Server
- Database System: EF Core (MySQL)
- Tiered (for MVC) or Auth Server Separated (for Angular): Auth server separated angular
- Exception message and full stack trace: NA
- Steps to reproduce the issue: NA
We have use case where we want to configure authentication scheme based on the user type. if a user is not a backend user/company user but a consumer than we want to configure mobile OTP based authentication and for company/tenant backend user , we want to use user name password authentication. Please suggest how to achieve this.
39 Answer(s)
-
0
-
0
if (!await userManager.VerifyUserTokenAsync(user, "PasswordlessLoginProvider", "passwordless-auth", userToken))
This if condition, it's going inside this if block, which it should not.
-
0
hi
You can check why the code is invalid.
VerifyUserTokenAsync
this is nothing to do with yourgrant extension
var token = await UserManager.GenerateUserTokenAsync(user, "PasswordlessLoginProvider", "passwordless-auth"); await userManager.VerifyUserTokenAsync(user, "PasswordlessLoginProvider", "passwordless-auth", token)
-
0
Yes, I got the point. But problem what I am dealing with is, earlier I was verifying the code here in this endpoint
public async Task<VerifyOTPAndSignInResponseDto> VerifyOTPAndSignIn(VerifyOTPAndSignInInput input) { using (CurrentTenant.Change(input.TenantId)) { using (var unitOfWork = UnitOfWorkManager.Begin()) { try { VerifyOTPResponseDto otpVerification = await VerifyOTP( new VerifyOTPInput() { CountryCode = input.CountryCode, MobileNumber = input.MobileNumber, OTP = input.OTP, }); if (otpVerification.type == "success") { var existingUser = await UserManager.FindByNameAsync(input.CountryCode + input.MobileNumber); var user = new Volo.Abp.Identity.IdentityUser(GuidGenerator.Create(), input.CountryCode + input.MobileNumber, input.CountryCode + input.MobileNumber + "@example.com", null); user.SetPhoneNumber(input.CountryCode + "-" + input.MobileNumber, true); if (existingUser == null) { (await UserManager.CreateAsync(user)).CheckErrors(); using (CurrentTenant.Change(null)) { (await UserManager.AddToRoleAsync(user, "Patient")).CheckErrors(); } await UsersAppService.PasswordlessUserRegistration(new PasswordlessUserRegistration(input.CountryCode, input.MobileNumber, user.Id)); } else { user = existingUser; } var token = await UserManager.GenerateUserTokenAsync(user, "PasswordlessLoginProvider", "passwordless-auth"); // Here I was validating the code //var isValid = await UserManager.VerifyUserTokenAsync(user, "PasswordlessLoginProvider", "passwordless-auth", token); //if (!isValid) //{ // throw new UnauthorizedAccessException("The token " + token + " is not valid for the user " + user.Id); //} await UserManager.UpdateSecurityStampAsync(user); await unitOfWork.CompleteAsync(); await SignInManager.SignInAsync(user, isPersistent: true); return new VerifyOTPAndSignInResponseDto() { message = otpVerification.message, type = otpVerification.type, token = token }; } else { return new VerifyOTPAndSignInResponseDto() { message = otpVerification.message, type = otpVerification.type }; } } catch (Exception e) { await unitOfWork.RollbackAsync(); unitOfWork.Dispose(); throw; } } } }
There it was successfully validating it, but when I moved that to the grant extension class, there it does not validate it.
-
0
In short, this line of code
await UserManager.VerifyUserTokenAsync(user, "PasswordlessLoginProvider", "passwordless-auth", token)
returns true in the controller endpoint, but returns false in the grant extension class, that's the issue.
-
0
hi
Can you prepare a minimal project to reproduce the problem and share it?
liming.ma@volosoft.com
Thanks.
-
0
Hi, I have given you the access to the git repository : https://github.com/perquantum/passwordless-authentication
Here I have put the sample project. Here's what you need to do.
Run the AuthServer project (or the whole solution) In postman, hit this api endpoint,
In response, you will get { "token": "6 digit token", "userId": "User Id of the user" }
You need to take these, token and userid values and hit one more API as follows :
In response, the user should be validated. This is the thing we want to achieve.
-
0
Also, we are using the MySQL as database, so I have updated the changes in the project accordingly. You can pull the latest changes and try.
-
0
ok, I will check it today.
Thanks.
-
0
hi
Can you try to remove the
await UserManager.UpdateSecurityStampAsync(user);
and try again?
Also, we are using the MySQL as database
The connection strings are still SQL server.
-
0
Hi, that worked. I was able to the access_token. But using that access_token, if I try to get the details of the application configuration, I should get the details of the currentUser right? But I am not getting the details there.
I also parsed the token on https://jwt.io/ the details are coming in as correctly there. But when tried to call the application-configuration api, it doesn't fetch the currentUser details.
And this is the error we are getting from logs :
Failed to validate the token. Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10206: Unable to validate audience. The 'audiences' parameter is empty. at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenPayloadAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateJWSAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration) [08:06:39 INF] Bearer was not authenticated. Failure message: IDX10206: Unable to validate audience. The 'audiences' parameter is empty. [08:06:39 INF] Executing endpoint 'Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.AbpApplicationConfigurationController.GetAsync (Volo.Abp.AspNetCore.Mvc)'
Can you help.
-
0
-
0
Hi, we have added all the required scope for the client, and after adding the scope, when we hit the connect/token API, we got this result :
Response :
{ "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjQwMzkyQUM4QzU2MzZGQTRDQTEzN0Y3NUE0MTI0OUU1MjZBNzU4RjgiLCJ4NXQiOiJRRGtxeU1WamI2VEtFMzkxcEJKSjVTYW5XUGciLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2Rldi5kb2N0cnouaW46NDQzMjIvIiwiZXhwIjoxNzMxNDA4OTc5LCJpYXQiOjE3MzE0MDUzNzksInNjb3BlIjoib3BlbmlkIiwianRpIjoiODQ2NTgzZjMtYjY5ZC00MmMwLTkzNzQtYjU3ZjgyMjk3YWE1Iiwic3ViIjoiM2ExNjFkZTYtMzk2NC1hNzg3LTRkNmEtOTg3MGRlZjcxNjE5IiwicHJlZmVycmVkX3VzZXJuYW1lIjoiKzkxOTYzODgyODUzMCIsImVtYWlsIjoiKzkxOTYzODgyODUzMEBleGFtcGxlLmNvbSIsInJvbGUiOiJQYXRpZW50IiwicGhvbmVfbnVtYmVyIjoiKzkxLTk2Mzg4Mjg1MzAiLCJwaG9uZV9udW1iZXJfdmVyaWZpZWQiOiJUcnVlIiwiZW1haWxfdmVyaWZpZWQiOiJGYWxzZSIsInNlc3Npb25faWQiOiI3MWY1NWM3Yy1mZTc5LTQ5NmYtODUxMS05MTNlYTg1NTc4MzIiLCJ1bmlxdWVfbmFtZSI6Iis5MTk2Mzg4Mjg1MzAiLCJvaV9wcnN0IjoicmVhY3RuYXR2ZUFwcF9Nb2JpbGUiLCJjbGllbnRfaWQiOiJyZWFjdG5hdHZlQXBwX01vYmlsZSIsIm9pX3Rrbl9pZCI6IjNhMTYzMWZhLTUxMWUtYmNiOS1lYTk0LTI1YWMwMTY0YjhiOSJ9.RCuBvzgy4XksHbFepPAPra-6RUgvHVEvNyn3NiOo47HwJJC4cRks7yfPH6Rvbj3BAf7DZYb9dk63UZLtJPVSCEJpG3xlOt6mx8zK4A6jxrh2nTCJI3MiOgIrsV99K02HqBfBz0kleXja4S8D7MPYAWyXrMOoeNQv6I4bNg9zRDHMh3viyLzkYHz_v6a8C059QplYEnJ9uUNQyiXx-aQGhN-pPbR_bo5PQOSwUdjsOYdvvWp6Tt_rT7V-O98otTigwfaTHSbmSb6C7QJ9VmcyF5D7F0Ll4C6FuraX74kG69wpjMevwP8_Dp_KtxsRTmD9RE4kJfv9kTbiQExEfJmrIQ", "token_type": "Bearer", "expires_in": 3599, "scope": "openid", "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjQwMzkyQUM4QzU2MzZGQTRDQTEzN0Y3NUE0MTI0OUU1MjZBNzU4RjgiLCJ4NXQiOiJRRGtxeU1WamI2VEtFMzkxcEJKSjVTYW5XUGciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2Rldi5kb2N0cnouaW46NDQzMjIvIiwiZXhwIjoxNzMxNDA2NTc5LCJpYXQiOjE3MzE0MDUzNzksImF1ZCI6InJlYWN0bmF0dmVBcHBfTW9iaWxlIiwic3ViIjoiM2ExNjFkZTYtMzk2NC1hNzg3LTRkNmEtOTg3MGRlZjcxNjE5Iiwic2Vzc2lvbl9pZCI6IjcxZjU1YzdjLWZlNzktNDk2Zi04NTExLTkxM2VhODU1NzgzMiIsImF6cCI6InJlYWN0bmF0dmVBcHBfTW9iaWxlIiwiYXRfaGFzaCI6Ijd4U1V0VkxCRkw2bEM1SkxFNDYtSXciLCJvaV90a25faWQiOiIzYTE2MzFmYS01MTJlLWNlZjUtYjFlYi05MzcxODZkNWFlNWUifQ.Vbl0-9tk9oiJpEye-mlWMBiNDhtYgZ_OOu07Rcx3eMT62xTsJoye5XscH15lIpUG0ixs5pAukcnAXKQ5u48YSWL8xgd0oRFAEIrr0d3NjdCvtW95VwVyRbZW7WHKQC08pLJL9gk-LE0dkCzWcohQjHBXi_QgI627i-xIzfX4I0BBLLBWiDxTEguV1UJ474uwiJrBjDbJWmRZWV2myRGi7NA-ZaWdi7KDWlLhW31DUOJJOnFgYphQWIA_Wm3cO49GGMdBqt7aAoWxy3N3xjExEr-pOKyGvcee6sBQ7sDubaOjljNV_Gqp463OLpu1KcRd57Hmd80bIt9qkHvo4waU4A" }
And after that when we passed this token in the application-configuration API endpoint, it still had the same response as earlier.
-
0
The scope in your access_token only have
openid
Please update your code as below:
var userClaimsPrincipalFactory = context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<Volo.Abp.Identity.IdentityUser>>(); var claimsPrincipal = await userClaimsPrincipalFactory.CreateAsync(user); //Remove -claimsPrincipal.SetScopes(claimsPrincipal.GetScopes()); -claimsPrincipal.SetResources(await GetResourcesAsync(context, claimsPrincipal.GetScopes())); /Add +claimsPrincipal.SetScopes(request.GetScopes()); +claimsPrincipal.SetResources(await GetResourcesAsync(context, request.GetScopes())); await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimsPrincipalManager>().HandleAsync(context.Request, claimsPrincipal); return new Microsoft.AspNetCore.Mvc.SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, claimsPrincipal);