proudmonkey / ApiBoilerPlate

A simple yet organized project template for building ASP.NET Core APIs in .NET Core 3.1
MIT License
361 stars 77 forks source link

What Url do I goto to get a auth token and how is it used ? #4

Closed punkouter2021 closed 4 years ago

punkouter2021 commented 4 years ago

Good sample but I can't figure out what I call to get a token that I can then .. I guess put in the header using fiddler to call the protected API . Help ?

proudmonkey commented 4 years ago

The template uses IdentityServer4 and the Token endpoint is available via IDS Discovery Endpoint. The discovery endpoint is available via /.well-known/openid-configuration relative to the base address of your AuthServer. For example, if you perform a GET request to the following endpoint:

https://<YOUR-AUTHSERVER-DOMAIN>.well-known/openid-configuration

you will then be presented with the following JSON schema below:

{
    "issuer": "https://<YOUR-AUTHSERVER-DOMAIN>",
    "jwks_uri": "https://<YOUR-AUTHSERVER-DOMAIN>/.well-known/openid-configuration/jwks",
    "authorization_endpoint": "https://<YOUR-AUTHSERVER-DOMAIN>/connect/authorize",
    "token_endpoint": "https://<YOUR-AUTHSERVER-DOMAIN>/connect/token",
    "userinfo_endpoint": "https://<YOUR-AUTHSERVER-DOMAIN>/connect/userinfo",
    "end_session_endpoint": "https://<YOUR-AUTHSERVER-DOMAIN>/connect/endsession",
    "check_session_iframe": "https://<YOUR-AUTHSERVER-DOMAIN>/connect/checksession",
    "revocation_endpoint": "https://<YOUR-AUTHSERVER-DOMAIN>/connect/revocation",
    "introspection_endpoint": "https://<YOUR-AUTHSERVER-DOMAIN>/connect/introspect",
    "device_authorization_endpoint": "https://<YOUR-AUTHSERVER-DOMAIN>/connect/deviceauthorization",
    "frontchannel_logout_supported": true,
    "frontchannel_logout_session_supported": true,
    "backchannel_logout_supported": true,
    "backchannel_logout_session_supported": true,
    "scopes_supported": [
        "SampleApi",
        "offline_access"
    ],
    "claims_supported": [],
    "grant_types_supported": [
        "authorization_code",
        "client_credentials",
        "refresh_token",
        "implicit",
        "urn:ietf:params:oauth:grant-type:device_code"
    ],
    "response_types_supported": [
        "code",
        "token",
        "id_token",
        "id_token token",
        "code id_token",
        "code token",
        "code id_token token"
    ],
    "response_modes_supported": [
        "form_post",
        "query",
        "fragment"
    ],
    "token_endpoint_auth_methods_supported": [
        "client_secret_basic",
        "client_secret_post"
    ],
    "id_token_signing_alg_values_supported": [
        "RS256"
    ],
    "subject_types_supported": [
        "public"
    ],
    "code_challenge_methods_supported": [
        "plain",
        "S256"
    ],
    "request_parameter_supported": true
}

You can see that the Token Endpoint can be accessed at: https://<YOUR-AUTHSERVER-DOMAIN>/connect/token

The template automatically handles requesting a token for you. At line 61 of Infrastructure/Installers/RegisterApiResources.cs class, You can find that the Discover Endpoint is injected as a Singleton. This means that everytime you instantiate an HttpClient object, the Discovery endpoint is binded automatically, allowing you to call the token endpoint directly without configuring them all over again.

You can see how it is being configured at Services/AuthServerConnect.cs class. And you can see how the token is automatically requested and set a Bearer Authorization header when you call a protected resource at Infrastructure/Handlers/ProtectedApiBearerTokenHandler.cs class.

Requesting a JWT Token Sample

To request a token manually, you can do something like this in Postman:

curl -X POST 
   https://<YOUR-AUTHSERVER-DOMAIN>/connect/token
  -H 'Content-Type: application/x-www-form-urlencoded'
  -d 'client_id=<SUPPLY_CLIENTID_HERE>&client_secret=<SUPPLY_SECRET_HERE>&grant_type=client_credentials'

Note that the client_id, client_secret and scope MUST be registered in your AuthServer.

When the credentials you supplied for requesting a JWT token is valid, it should return something lke this:

{
  "access_token": "<JWT TOKEN STRING>",
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "SampleApi"
}

Accessing Protected APIs Sample

curl -X GET \
  https://localhost:44321/api/v1/sample \
  -H 'Authorization: Bearer <INSERT JWT TOKEN STRING> \
  -H 'Content-Type: application/json' \
  -H 'Host: https://localhost:44321' \

That's it! If you are new to IdentityServer4, you should checkout the official docs for more information: http://docs.identityserver.io/en/latest/

punkouter2021 commented 4 years ago

Dumb question. What is ? That's some totally different server ? I assumed the app was all self contained

proudmonkey commented 4 years ago

It's not dumb at all! It's perfectly understandable. We ask questions so we can learn :) Yes, the AuthServer should be in a separate server to decouple it from your API apps.

Can I close this issue now?

punkouter2021 commented 4 years ago

So this authserve is a totally separate project? I am used to the classic forms authentication and tokens where everything is in one project so this has me confused. So I download this thing called identity server first and then run your code ?

proudmonkey commented 4 years ago

The template assumed that your AuthServer is in separate project because it is designed for microservice approach. You can still integrate AuthServer and combine it with your UI and APIs as you like. You just need to configure AuthServer yourself. Here's a great article explaining how you can setup IDS4 with ASP.NET Core: https://www.scottbrady91.com/Identity-Server/Getting-Started-with-IdentityServer-4

punkouter2021 commented 4 years ago

Ok. I am totally unfamiliar with that. So Ill see if I can set that up.

proudmonkey commented 4 years ago

Cool! To help you better understand more, you can think of this template as ApiResource for your IDS4 AuthServer.