My setup,
- An IdentityServer using MVC Identity to store the Users, created with
dotnet new mvc -au Individualand applying the http://docs.identityserver.io/en/release/quickstarts/0_overview.html tutorial, running in localhost 5000. - A client App, but now I'm using postman to do tests.
- A WEB API, created with
dotnet new webapi, running in localhost 5001.
The IdentityServer resources and clients configuration is the following, notice that I'm using reference tokens:
public static IEnumerable<IdentityResource> GetIdentityResources() {
return new List<IdentityResource>{ new IdentityResources.OpenId() };
}
public static IEnumerable<ApiResource> GetApiResources() {
return new List<ApiResource>{
new ApiResource("api_resource", "API Resource") {
Description= "API Resource Access",
ApiSecrets= new List<Secret> { new Secret("apiSecret".Sha256()) },
}
};
}
public static IEnumerable<Client> GetClients() {
return new List<Client>{
new Client {
ClientId= "angular-client",
ClientSecrets= { new Secret("secret".Sha256()) },
AllowedGrantTypes= GrantTypes.ResourceOwnerPassword,
AllowOfflineAccess= true,
AccessTokenType = AccessTokenType.Reference,
AlwaysIncludeUserClaimsInIdToken= true,
AllowedScopes= { "api_resource" }
}
}
The password and user is send with postman and the token received is send to the WEB API also with postman, something like call localhost:5001/v1/test with the token pasted in option bearer token.
In the API Startup, in ConfigureServices I'm adding the lines below
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority= "http://localhost:5000";
options.ApiName= "api_resource";
options.ApiSecret = "apiSecret";
});
And I'm getting the Id of the user inside the controller as follows:
public async Task<IActionResult> Get(int id) {
var discoveryClient = new DiscoveryClient("http://localhost:5000");
var doc = await discoveryClient.GetAsync();
var introspectionClient = new IntrospectionClient(
doc.IntrospectionEndpoint,
"api_resource",
"apiSecret");
var token= await HttpContext.GetTokenAsync("access_token");
var response = await introspectionClient.SendAsync(
new IntrospectionRequest { Token = token });
var userId = response.Claims.Single(c => c.Type == "sub").Value;
}
The question itself is, am I using the right path to get the Id from the reference token?, because now It works but I don't want to miss anything, specially thinking that is a security concern.
I'm asking also because I have seen anothers using
string userId = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
that is more straightforward but doesn't seems to fit with reference tokens.
Thanks in advance.