I'm working on IdentityServer4.AdminUI which developed on github GitHub IdentityServer4.AdminUI
First of all I created a new user simply and set it's password, then I Created new ApiResource with name Api_Name. Then I Created IdentityResource with the same name Api_Name. Finally I Created new client with name Api_Client and set client Allowed Scopes to Api_Name and Allowed Grant Types to Password and finally Set the client secret to secret
Now, I created new WebApi project (Core 2.1) and use this in startup class
public void ConfigureServices(IServiceCollection services) {
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvcCore().AddAuthorization().AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options => {
options.Authority = "http://localhost:5000"; //Identity Server URL
options.RequireHttpsMetadata = false; // make it false since we are not using https
options.ApiName = "Api_Name"; //api name which should be registered in IdentityServer
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
else {
app.UseHsts();
}
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseMvc();
}
and sure I used [Authorize] attribute in WebApi controller
Finally, the test. I Created console application and use this code
var identityServer = await DiscoveryClient.GetAsync("http://localhost:5000"); //discover the IdentityServer
if (identityServer.IsError) {
Console.Write(identityServer.Error);
return;
}
HttpClient client = new HttpClient();
var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest {
Address = identityServer.TokenEndpoint,
ClientId = "Api_Client",
ClientSecret = "secret",
UserName = "Majd",
Password = "P@ssw0rd@123"
});
if (tokenResponse.IsError) {
Console.WriteLine(tokenResponse.Error);
return;
}
//Call the API
client.SetBearerToken(tokenResponse.AccessToken);
var response = await client.GetAsync("https://localhost:44368/api/values");
var response2 = await client.GetAsync("https://localhost:44368/api/values/1");
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
Console.ReadKey();
The problem is response2 return UnAuthorized 401. so why i got this error since I used the received access token from the identity server
You need to also add a requested scope in your token request (even though you said that the client is allowed to access Api_Name
).
var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest {
Address = identityServer.TokenEndpoint,
ClientId = "Api_Client",
ClientSecret = "secret",
UserName = "Majd",
Password = "P@ssw0rd@123",
Scope = "Api_Name"
});
In IDS4, the tokens are only issued for the scopes that have been requested, unlike IDS3 where you would get all the scopes that the client is allowed. So as far as your Api authentication middleware is concerned, your client was not allowed to access it because the token did not suffice.