How to get access token from Identity Server by passing username and password?
Asked Answered
D

3

7

We are using identity server to generate access token for our web services. We have added swagger also. But the problem we faced is, to generate an access token by using a code snippet for API automation. Is there any automated way to get access token by using the username and password?

Dachau answered 29/7, 2017 at 14:41 Comment(0)
R
2

The way I've tackled this is to add a client credentials client if there is a configured test client secret, I configure this secret only in the test environments but obviously not in higher environments meaning the client never gets added there.

So either in your appsettings.{appropriate_environment}.settings or via an environment variable set up a client secret, then in your IdentityServer config you can add:

//attempt to get the test client secret
var testClientSecret = configuration["TestClientSecret"];
if (!String.IsNullOrWhiteSpace(testClientSecret))
{
    clients.Add(new Client
    {
        ClientId = "MyTestClient",

        AllowedGrantTypes = GrantTypes.ClientCredentials,

        ClientSecrets =
        {
            new Secret(testClientSecret.Sha256())
        },

        AllowedScopes = { "MyApiScope", "MyOtherApiScope", "etc." }
    });
};

Then I have a Postman collection of tests which first POSTs to:

https://{{idp_base_url}}/connect/token

Using basic auth with username of the test client name and password as the client secret (where {{idp_base_url}} is a postman environment variable containing the IdentityServer host appropriate for the environment).

Then I run a few tests but also store the access token to the API:

//tests...
var tokenData = JSON.parse(responseBody);
//more tests...
postman.setEnvironmentVariable("cc_token", tokenData.access_token);

Subsequent tests in the collection can then run your API tests using this token with a bearer token auth header using the above Postman environment variable:

Postman bearer token

Repartee answered 29/7, 2017 at 15:20 Comment(0)
W
2

Another way is to use IdentityModel NuGet to get the token. Example:

var client = new HttpClient();
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
    Address = $"{IdentityServerUrl}/connect/token",
    ClientId = "THE_CLIENT_ID",
    ClientSecret = IdentityServerPass,
    Scope = "api.read"

}).ConfigureAwait(false);
tokenResponse.HttpResponse.EnsureSuccessStatusCode();
Whilst answered 20/4, 2020 at 18:58 Comment(1)
That should be the accepted answer. Thanks!!Cartwheel
I
1

First of all declare a class named Token.

public class Token
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }

    [JsonProperty("token_type")]
    public string TokenType { get; set; }

    [JsonProperty("expires_in")]
    public int ExpiresIn { get; set; }

    [JsonProperty("userName")]
    public string Username { get; set; }

    [JsonProperty(".issued")]
    public string IssuedAt { get; set; }

    [JsonProperty(".expires")]
    public string ExpiresAt { get; set; }
}

In Postman we use username, password and grant_type in POST method to generate the access_token from the baseURl/token uri. To know what url you should use, check in the Startup.Auth.cs file in App_Start Folder.

OAuthOptions = new OAuthAuthorizationServerOptions
{
     TokenEndpointPath = new PathString("/Token"),
     .....
}

The appropriate URL is determined by the string inside the PathString() constructor.

Once you know what url to call, now to get the access token, consider the following code.

var keyValues = new List<KeyValuePair<string, string>>
{
    new KeyValuePair<string, string>("username", username),
    new KeyValuePair<string, string>("password",password),
    new KeyValuePair<string, string>("grant_type", "password")
};

var request = new HttpRequestMessage(HttpMethod.Post, "baseUrl/Token");

request.Content = new FormUrlEncodedContent(keyValues);

var client = new HttpClient();

var response = await client.SendAsync(request);

var content = await response.Content.ReadAsStringAsync();
var accessTokenVar = JsonConvert.DeserializeObject<AuthenticationToken>(content);

Now the access token can be accessed using the accessTokenVar.

Inconsistent answered 2/8, 2017 at 16:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.