问题
I'am writing a test application with asp.net core 2.0, AspNet.Security.OpenIdConnect.Server and AspNet.Security.OAuth.Extensions. I ran into a problem with introspection of the access token. When I get my token from /connect/token and send it to my resource server I get the following errors in my server:
fail: AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler[0]
The introspection request was rejected with the following error: invalid_request ; (null)
info: AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler[0]
The introspection response was successfully returned: {
"error": "invalid_request"
}
And in my resource server:
fail: AspNet.Security.OAuth.Introspection.OAuthIntrospectionHandler[0]
An error occurred while validating an access token: the remote server returned a BadRequest response with the following payload: Date: Sat, 21 Oct 2017 17:11:50 GMT
Server: Kestrel
{"error":"invalid_request"}.
info: AspNet.Security.OAuth.Introspection.OAuthIntrospectionHandler[7]
Bearer was not authenticated. Failure message: Authentication failed because the authorization server rejected the access token.
This is ConfigureServices method from my Startup class of my resource server (WebApi):
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication().AddOAuthIntrospection(
options =>
{
options.Authority = new Uri("http://localhost:64855/");
options.Audiences.Add("resource_server");
options.ClientId = "client_id";
options.ClientSecret = "client_secret";
options.RequireHttpsMetadata = false;
});
services.AddMvc();
}
This is my protected by AuthorizeAttribute controller in resource server:
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = OAuthIntrospectionDefaults.AuthenticationScheme)]
public class ValuesController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] {"value1", "value2"};
}
}
This is Startup class in auth server:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(
options =>
{
options.DefaultScheme = OAuthValidationDefaults.AuthenticationScheme;
})
.AddOAuthValidation(
options =>
{
options.Audiences.Add("resource_server");
});
services.AddAuthentication().AddOpenIdConnectServer(options =>
{
options.TokenEndpointPath = "/connect/token";
options.IntrospectionEndpointPath = "/connect/introspect";
options.AllowInsecureHttp = true;
options.ApplicationCanDisplayErrors = true;
options.Provider.OnValidateTokenRequest = context =>
{
if (!context.Request.IsPasswordGrantType() && !context.Request.IsRefreshTokenGrantType())
{
context.Reject(
error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
description: "Only grant_type=password and refresh_token " +
"requests are accepted by this server.");
return Task.CompletedTask;
}
if (string.Equals(context.ClientId, "client_id", StringComparison.Ordinal) &&
string.Equals(context.ClientSecret, "client_secret", StringComparison.Ordinal))
{
context.Validate();
}
return Task.CompletedTask;
};
options.Provider.OnHandleTokenRequest = context =>
{
if (context.Request.IsPasswordGrantType())
{
if (!string.Equals(context.Request.Username, "Bob", StringComparison.Ordinal) ||
!string.Equals(context.Request.Password, "P@ssw0rd", StringComparison.Ordinal))
{
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Invalid user credentials.");
return Task.CompletedTask;
}
var identity = new ClaimsIdentity(context.Scheme.Name,
OpenIdConnectConstants.Claims.Name,
OpenIdConnectConstants.Claims.Role);
identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "[unique id]");
identity.AddClaim("urn:customclaim", "value",
OpenIdConnectConstants.Destinations.AccessToken,
OpenIdConnectConstants.Destinations.IdentityToken);
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
context.Scheme.Name);
ticket.SetScopes(
OpenIdConnectConstants.Scopes.Profile,
OpenIdConnectConstants.Scopes.OfflineAccess);
context.Validate(ticket);
}
return Task.CompletedTask;
};
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
It seems to me that I somewhere missed something when configuring the server and the client, but I can not understand where. Or maybe I'm just doing something wrong. Maybe, I should implement introspect method by myself... don't know( I already tried to override methods in OpenIdServerConnectProvider, but nothing happened in the end.
Tell me please what can be the problem or what I did wrong. Thanks.
UPD: after all fixes, thanks to Pinpoint, this is my working solution: https://github.com/mstya/Introspection.Sample I hope it helps someone.
回答1:
Or maybe I'm just doing something wrong. Maybe, I should implement introspect method by myself... don't know( I already tried to override methods in OpenIdServerConnectProvider, but nothing happened in the end.
You forgot to implement the ValidateIntrospectionRequest
event. Just like ValidateTokenRequest
, you have to validate the client credentials and call context.Validate()
if they are valid.
来源:https://stackoverflow.com/questions/46866209/aspnet-security-oauth-extensions-error-while-introspection