Open Closed

Token based API integration & API metering #7815


0
SRTMDEV created

Hi,

We are looking for a way to expose our APIs to external applications. We do not want external application to store/access username and password, instead we are looking for a token based authentication solution. Where user can create/expire/delete tokens from our application. External applications can pass on token for authentication before invoking APIs.

In addition to that we are looking for way to capture the number of calls per API and way to restrict them as per configured values as per tenant.

Do we have any out of box feature in AspNetZero which can be used for above requirement? Looking forward for positive response.


10 Answer(s)
  • 0
    maliming created

    We do not want external application to store/access username and password, instead we are looking for a token based authentication solution. Where user can create/expire/delete tokens from our application.

    This sounds very consistent with the OAuth2 design. Zero integrates with Identity Server 4 and you can check them out.

    https://identityserver4.readthedocs.io/en/latest/

    In addition to that we are looking for way to capture the number of calls per API and way to restrict them as per configured values as per tenant.

    You can use an interceptor/filter for your api.

    See https://aspnetboilerplate.com/Pages/Documents/Articles/Aspect-Oriented-Programming-using-Interceptors/index.html

  • 0
    SRTMDEV created

    We setup identityServer4 and it works perfectly with grant type "password". When we try with "client_credentils" it generates the access token but when we call api it says unauthorized access token, hence we are not able to access the api. Can you shared thoughts on this ? or Can you share a sample which use grant-type "client_credentials"?

  • 0
    maliming created

    hi @mandatly Can you share the code for the IdentityServerConfig class and the IdentityServer settings in the appsetting.jsonfile?

  • 0
    SRTMDEV created

    Yes,

    This is IdentityServerConfig

    public static class IdentityServerConfig
        {
            public static IEnumerable<ApiResource> GetApiResources()
            {
                return new List<ApiResource>
                {
                    new ApiResource("default-api", "Default (all) API")
                    {
                        Description = "AllFunctionalityYouHaveInTheApplication",
                        ApiSecrets= {new Secret("secret") }
                    }
                };
            }
    
            public static IEnumerable<IdentityResource> GetIdentityResources()
            {
                return new List<IdentityResource>
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile(),
                    new IdentityResources.Email(),
                    new IdentityResources.Phone()
                };
            }
    
            public static IEnumerable<Client> GetClients(IConfigurationRoot configuration)
            {
                var clients = new List<Client>();
    
                foreach (var child in configuration.GetSection("IdentityServer:Clients").GetChildren())
                {
                    clients.Add(new Client
                    {
                        ClientId = child["ClientId"],
                        ClientName = child["ClientName"],
                        AllowedGrantTypes = child.GetSection("AllowedGrantTypes").GetChildren().Select(c => c.Value).ToArray(),
                        RequireConsent = bool.Parse(child["RequireConsent"] ?? "false"),
                        AllowOfflineAccess = bool.Parse(child["AllowOfflineAccess"] ?? "false"),
                        ClientSecrets = child.GetSection("ClientSecrets").GetChildren().Select(secret => new Secret(secret["Value"].Sha256())).ToArray(),
                        AllowedScopes = child.GetSection("AllowedScopes").GetChildren().Select(c => c.Value).ToArray(),
                        RedirectUris = child.GetSection("RedirectUris").GetChildren().Select(c => c.Value).ToArray(),
                        PostLogoutRedirectUris = child.GetSection("PostLogoutRedirectUris").GetChildren().Select(c => c.Value).ToArray(),
                    });
                }
    
                return clients;
            }
        }
    

    this is the appsetting.json for IdentityServer4

      "IdentityServer": {
        "IsEnabled": "true",
        "Authority": "http://localhost:22742/",
        "ApiName": "default-api",
        "ApiSecret": "secret",
        "Clients": [
          {
            "ClientId": "client",
            "AllowedGrantTypes": [
              "password",
              "client_credentials"
            ],
            "ClientSecrets": [
              {
                "Value": "def2edf7-5d42-4edc-a84a-30136c340e13"
              }
            ],
            "AllowedScopes": [
              "default-api",
              "profile"
            ]
          },
          {
            "ClientId": "demo",
            "ClientName": "MVC Client Demo",
            "AllowedGrantTypes": [
              "hybrid",
              "client_credentials",
              "password"
            ],
            "RequireConsent": "true",
            "ClientSecrets": [
              {
                "Value": "def2edf7-5d42-4edc-a84a-30136c340e13"
              }
            ],
            "RedirectUris": [
              "http://openidclientdemo.com:8001/signin-oidc"
            ],
            "PostLogoutRedirectUris": [
              "http://openidclientdemo.com:8001/signout-callback-oidc"
            ],
            "AllowedScopes": [
              "openid",
              "profile",
              "default-api"
            ],
            "AllowOfflineAccess": "true"
          }
        ]
      },
    
  • 1
    maliming created

    hi @mandatly The identity server provides a basic example: https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html

    As you probably know, client_credentials only requires the client, not the concept of the user. But abp authentication & authorization must have the concept of the user.

    Why do you want to use client_credentials to get the token?

  • 0
    SRTMDEV created

    We want to generate access token behalf of tenant for our API Management Module with IdentityServer4 grant-type client_credentials .

    Below are the our requirement for API Management Module,

    • First we want to disable direct API access and only API accessible from our front-end or domain URLs.
    • If tenant want to access the API they have options to enable API access and generate the client secret for that Service Module or Single API Endpoint with the allowed list of IPs or Domain URLs or Origin to access the API otherwise it should be restrict API. Client will generate the access token by sending the client secret and client-Id, he/she should be able to access the API from that List of IP or domain or Origin API.
    • We also want to provide report to tenant about API usage from that client-secret and also Tenant should be able to set limit of API request like, he/she can only call 3600 request/hour.

    Can you share your thoughts on this ?, Or What is the best solution for this?, Or any suggestion?

  • 0
    maliming created

    Grant type using client_credentials is not compatible with abp permission checking.

    If your API Management Module uses its own permissions check this should be fine, which means you can use other features of abp.

    Regarding api request restrictions and reports, these can be implemented using middleware, interceptors, etc.

  • 0
    SRTMDEV created

    What all grant types are comptible with ABP permission checking?

  • 0
    maliming created

    These grant types can get the user's information. authorization-code implicit password Openid connect

  • 0
    ismcagdas created

    This issue is closed because it has not had recent activity for a long time.