Open Closed

after login from HttpClient => call API return 403 Forbidden #3136


User avatar
0
mostafa_ibrahem22@hotmail.com created

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)
  • User Avatar
    0
    EngincanV created
    Support Team .NET Developer

    Hi, can you check that the permission is granted? Because, 403 error indicates that you've logged in but don't have the permission.

  • User Avatar
    0
    mostafa_ibrahem22@hotmail.com created

    User: admin => From UI Angular: Working Done 200 OK From Swagger: Working Done 200 OK From Console: 403 Forbidden

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    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.

  • User Avatar
    0
    mostafa_ibrahem22@hotmail.com created

    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

  • User Avatar
    1
    gterdem created
    Senior .NET Developer

    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

  • User Avatar
    0
    mostafa_ibrahem22@hotmail.com created
    • 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" });

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    Go to IdentityServer Management UI from your admin application. Navigate to Clients. Find your console application (value of _configuration["IdentityClients:Default:ClientId"]) and click Actions.

    Click Manage Permissions: Grant the permission (MainCore.Permissions.Countries.Default).

  • User Avatar
    0
    mostafa_ibrahem22@hotmail.com created

    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" });

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    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.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19