ABP Framework version: commercial v 5.1.3 UI type: Angular DB provider: EF Core Tiered (MVC) or Identity Server Separated (Angular): yes
I Create new fluter app and console app to access API
after login from HttpClient => call API return 403 Forbidden
[Authorize()] => Working 200 OK [Authorize(MainCorePermissions.Countries.Default)] => Not Working 403 Forbidden
app.settings.json
{ "RemoteServices": { "Default": { "BaseUrl": "https://localhost:44360/" }, "MainCore": { "BaseUrl": "https://localhost:44380/" }, "Naama": { "BaseUrl": "https://localhost:44358/" } }, "IdentityClients": { "Default": { "GrantType": "password", "ClientId": "MainCore_App", "ClientSecret": "1q2w3e*", "UserName": "admin", "UserPassword": "1q2w3E*", "Authority": "https://localhost:44360/", "Scope": "MainCore" }, "Naama": { "GrantType": "password", "ClientId": "Naama_App", "ClientSecret": "1q2w3e*", "UserName": "admin", "UserPassword": "1q2w3E*", "Authority": "https://localhost:44330", "Scope": "Naama" } } }
=============Code ==============================
using IdentityModel.Client; using Microsoft.Extensions.Configuration;
var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: false);
IConfiguration _configuration = builder.Build();
//Obtain access token from the IDS4 server
// discover endpoints from metadata var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync(_configuration["IdentityClients:Default:Authority"]); if (disco.IsError) { Console.WriteLine(disco.Error); return; }
// request token var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest { Address = disco.TokenEndpoint, ClientId = _configuration["IdentityClients:Default:ClientId"], ClientSecret = _configuration["IdentityClients:Default:ClientSecret"], UserName = _configuration["IdentityClients:Default:UserName"], Password = _configuration["IdentityClients:Default:UserPassword"], Scope = _configuration["IdentityClients:Default:Scope"] });
if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; }
Console.WriteLine(tokenResponse.Json);
//Perform the actual HTTP request
using (var httpClient = new HttpClient()) { httpClient.SetBearerToken(tokenResponse.AccessToken);
var url = _configuration["RemoteServices:MainCore:BaseUrl"] +
"api/main-core/country";
var responseMessage = await httpClient.GetAsync(url);
if (responseMessage.IsSuccessStatusCode)
{
var responseString = await responseMessage.Content.ReadAsStringAsync();
Console.WriteLine("Result: " + responseString);
}
else
{
throw new Exception("Remote server returns error code: " + responseMessage.StatusCode);
}
}
9 Answer(s)
-
0
Hi, can you check that the permission is granted? Because, 403 error indicates that you've logged in but don't have the permission.
-
0
User: admin => From UI Angular: Working Done 200 OK From Swagger: Working Done 200 OK From Console: 403 Forbidden
-
0
Console application authorization is non-user interactive Client Credentials flow while others are user-related authorization flows.
You need to grant permission to the console application itself. You can use IdentityServer Management UI or IdentityServer Dataseeder.
-
0
i already have a custom mobile login form, I want to use "RequestPasswordTokenAsync" as my authentication method, but the user should have the same permission as if he/she logged in from the custom mobile login form,
https://localhost:44360/api/main-core/country Remote server returns error code: 403 Forbidden
-
1
You can use IdentityServer Management UI and save your mobile application to identityserver and give necessary permissions. Here is a guide for server-to-server communication configuration for microservices. This is the case when you are trying to make a request from a console application to an API.
This is out of ABP scope but you can check these links for better understanding and implementation: https://stackoverflow.com/questions/43121401/how-to-use-identity-server-4-sign-in-with-desktop-mobile-apps https://cuteprogramming.wordpress.com/2018/07/14/connecting-android-app-with-identity-server-4 https://damienbod.com/2019/02/20/asp-net-core-oauth-device-flow-client-with-identityserver4
-
0
https://community.abp.io/posts/consume-an-abp-framework-api-from-a-.net-core-console-application-5b8o2lrw
in the above article Authorize with policy working without any problems, why in here not working.
How to add Custom Claims when used RequestPasswordTokenAsync I add custom claim but not send in token from console, but custom claims sent from angular and Swagger?
in token SubjectId equal abp user id, why authorizer not working, and how can custom authorizerProvider (custom permissions) to handle these case?
public class SocialSecurityNumberClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency { public async Task ContributeAsync(AbpClaimsPrincipalContributorContext context) { var identity = context.ClaimsPrincipal.Identities.FirstOrDefault(); var userId = identity?.FindUserId(); if (userId.HasValue) { var userService = context.ServiceProvider.GetRequiredService<IUserAppService>(); //Your custom service var socialSecurityNumber = await Task.FromResult("10"); identity.AddClaim(new Claim("SocialSecurityNumber", socialSecurityNumber)); } } }
// request token var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest { Address = disco.TokenEndpoint, ClientId = _configuration["IdentityClients:Default:ClientId"], ClientSecret = _configuration["IdentityClients:Default:ClientSecret"], UserName = _configuration["IdentityClients:Default:UserName"], Password = _configuration["IdentityClients:Default:UserPassword"], Scope = "email openid profile role phone address MainCore" });
-
0
-
0
Thanks for your reply, but How do I add Custom Claims when using RequestPasswordTokenAsync I add custom claims but do not send in tokens from the console, but the custom claims are sent from angular and Swagger? and how can a custom authorized provider?
public class SocialSecurityNumberClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency { public async Task ContributeAsync(AbpClaimsPrincipalContributorContext context) { var identity = context.ClaimsPrincipal.Identities.FirstOrDefault(); var userId = identity?.FindUserId(); if (userId.HasValue) { var userService = context.ServiceProvider.GetRequiredService<IUserAppService>(); //Your custom service var socialSecurityNumber = await Task.FromResult("10"); identity.AddClaim(new Claim("SocialSecurityNumber", socialSecurityNumber)); } } }
// request token var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest { Address = disco.TokenEndpoint, ClientId = _configuration["IdentityClients:Default:ClientId"], ClientSecret = _configuration["IdentityClients:Default:ClientSecret"], UserName = _configuration["IdentityClients:Default:UserName"], Password = _configuration["IdentityClients:Default:UserPassword"], Scope = "email openid profile role phone address MainCore" });
-
0
There is no user in server-to-server interactions hence there is no user claims to customize.
For adding custom claims you can check the answers from these issues:
- https://support.abp.io/QA/Questions/930/Create-custom-claims-and-add-them-to-ICurrentUser--ICurrentPrincipalAccessor
- https://support.abp.io/QA/Questions/1190/Adding-Custom-Claims-to-the-Logged-in-User
- https://support.abp.io/QA/Questions/1013/How-to-customize-claims
If you are asking for how to integrate custom mobile application to identityserver, it is out of ABP scope. As much as I would like to help, I have no expertise on this subject..
You can check the links i have provided in this answer.