Openiddict introspect not working (The access token is not valid.)
Asked Answered
S

1

6

I have 3 projects 1- SPA, 2- Web API Project, 3- Identity (setup using openiddict, ASP.NET Core 2.0 (OpenIddict.dll version 2.0.0.-rc2-0854) with EF Core.

API and Identity Server run successfully, can get the jwt token but, when I try to get value from API method which has Authorize Attribute I get an error:

WWW-Authenticate →Bearer error="invalid_token", error_description="The access token is not valid." 

In Application Insights, could see POST /connect/introspect getting called, with result Dependency result code:500 and Dependency code: Http

Same code worked before, not sure which changes break introspect.

configuration in API project

 services.AddAuthentication(options =>
        {
            options.DefaultScheme = OAuthIntrospectionDefaults.AuthenticationScheme;
        })
          .AddOAuthIntrospection(options =>
          {
              options.Authority = new Uri("http://localhost:49888");
              options.ClientId = "my-resource-server";
              options.ClientSecret = "ClientSecret";
              options.RequireHttpsMetadata = false;
          });
        services.AddCors();           
        services.AddMvc()
            .AddJsonOptions(options =>
             {
                 options.SerializerSettings.Formatting = Formatting.None;
             });

Authorized Method

  [HttpGet("GetData/{Id}")]
    [Authorize(AuthenticationSchemes = OAuthIntrospectionDefaults.AuthenticationScheme)]
    [Authorize(Roles = "Admin")]
    public IActionResult GetData(int courseId)
    {
 }

connect/introspect in Identity Project

  private async Task<AuthenticationTicket> CreateTicketAsync(OpenIdConnectRequest request, UserInfo user)
    {
        UserInfo userInfo = await _userRepository.GetUserByCredentials(request.Username, request.Password);

        if (userInfo == null)
        {
            return null;
        }

        // Create a new ClaimsIdentity holding the user identity.
        var identity = new ClaimsIdentity(
            OpenIdConnectServerDefaults.AuthenticationScheme,
            OpenIdConnectConstants.Claims.Name,
             OpenIdConnectConstants.Claims.Role
           );

        // Add a "sub" claim containing the user identifier, and attach
        // the "access_token" destination to allow OpenIddict to store it
        // in the access token, so it can be retrieved from your controllers.
        identity.AddClaim(OpenIdConnectConstants.Claims.Subject,
            user.UserId.ToString(),
            OpenIdConnectConstants.Destinations.AccessToken);
        identity.AddClaim(OpenIdConnectConstants.Claims.Name, user.Name,
            OpenIdConnectConstants.Destinations.AccessToken);

        identity.AddClaim(OpenIdConnectConstants.Claims.Role, user.Role,
           OpenIdConnectConstants.Destinations.AccessToken);

        // ... add other claims, if necessary.
        var principal = new ClaimsPrincipal(identity);

        // Create a new authentication ticket holding the user identity.
        var ticket = new AuthenticationTicket(principal,
            new Microsoft.AspNetCore.Authentication.AuthenticationProperties(),
            OpenIdConnectServerDefaults.AuthenticationScheme);

. .

Steroid answered 15/2, 2018 at 13:23 Comment(9)
Please share your authorization server logs. You're likely hitting openiddict.github.io/openiddict-documentation/guide/….Roller
In AuthenticationTicket() added following line new AuthenticationProperties(), In permission field added ["ept:introspection"], still no luck. Not find any entry in System log, following entries from Application Insights Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. Authorization failed for user: (null). The introspection response was successfully extracted: "active": false. Bearer was not authenticated. Failure message: Authentication failed because the authorization server rejected the access token.Steroid
These are the resource server logs. Update your question with the authorization server logs (you can find them in VS' output window in the debug menu).Roller
Oh yes, One of the entry as follows, OpenIddict.OpenIddictProvider:Error: The token 'c75afe3a-8915-45fe-b03e-b0165ad43f37' doesn't have any audience attached and cannot be introspected. To add an audience, use the 'ticket.SetResources(...)' extension when creating the ticket.Steroid
And have you tried calling the method suggested by the error message? In your case, it should be ticket.SetResources("my-resource-server") :PRoller
following code is present in resource server .AddOAuthIntrospection(options => { options.Authority = new Uri("localhost:49888/"); options.Audiences.Add("resource-server-2"); and same entries are present in connect/introspect ticket.SetResources("resource-server-1", "resource-server-2");Steroid
In your question, the client identifier of your resource server/API is my-resource-server. You must include in the resources list. The options.Audiences property on the introspection doesn't have any influence on the security check made by OpenIddict when validating the client is allowed to introspect the token.Roller
Typo corrected, It looks like ticket.SetResources("resource-server-1", "resource-server-2"); doesn’t add Audience in the token, decoded token don’t show Audience value. I’m missing something?Steroid
I just tested and it works fine on my machine. If you're still seeing this issue, join me at gitter.im/openiddict/openiddict-core so we can figure out what's going on.Roller
D
4

Starting with RC2, OpenIddict can be officially used with third-party applications (i.e clients you don't own). As such, we can no longer assume that all the registered applications are legit and can freely introspect tokens.

To make things explicit, you now have to specify the list of client identifiers that are able to introspect a token. For that, add the following code when creating the ticket:

var ticket = new AuthenticationTicket(
    new ClaimsPrincipal(identity),
    new AuthenticationProperties(),
    OpenIdConnectServerDefaults.AuthenticationScheme);

ticket.SetResources("tracking_api", "marketing_api");

The resources must exactly match the client_id assigned to your resource servers using the introspection handler:

services.AddAuthentication()
    .AddOAuthIntrospection(options =>
    {
        options.Authority = new Uri("http://localhost:12345/");
        options.ClientId = "marketing_api";
        options.ClientSecret = "846B62D0-DEF9-4215-A99D-86E6B8DAB342";
        options.RequireHttpsMetadata = false;
    });

https://openiddict.github.io/openiddict-documentation/guide/migration.html#if-your-authorization-server-uses-introspection-make-sure-resources-are-set-in-the-authentication-ticket

Declinature answered 17/2, 2018 at 21:3 Comment(2)
could you actualize that, please?Wacker
Relevant solution in samples there If someone has time please add new answer hereEquable

© 2022 - 2024 — McMap. All rights reserved.