openiddict / openiddict-core

Flexible and versatile OAuth 2.0/OpenID Connect stack for .NET
https://openiddict.com/
Apache License 2.0
4.43k stars 520 forks source link

Productive Introspect (Resources) #2161

Closed chamavv closed 2 months ago

chamavv commented 2 months ago

Confirm you've already contributed to this project or that you sponsor it

Version

5.6.0

Question

Hello, good afternoon, I would like to see if you can support me. I am using the following structure: my server application with openiddict, a client with angular and my application with webapi. I'm using introspective. using the resource. Everything works fine for me in tests, but when publishing when it reaches the API it marks me as unauthorized. In tests the entire flow works well. I put my settings

1.-

builder.Services.AddDbContext<IntranetContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("IntranetConnection"));
    options.UseOpenIddict();

});

builder.Services.AddScoped<IPasswordHasher<IdentityUser>, PasswordHasher<IdentityUser>>();

builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
builder.Logging.AddEventLog();

builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<IntranetContext>()
    .AddDefaultTokenProviders();

builder.Services.Configure<IdentityOptions>(options =>
{
    options.ClaimsIdentity.UserNameClaimType = Claims.Name;
    options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
    options.ClaimsIdentity.RoleClaimType = Claims.Role;
    options.SignIn.RequireConfirmedAccount = false;
});

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
          .AddCookie(options =>
          {
              options.AccessDeniedPath = "/connect/signin";
              options.LoginPath = "/connect/signin";
              options.LogoutPath = "/connect/signout";
              //options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
              //options.Cookie.SameSite = SameSiteMode.None;
          });

builder.Services.AddQuartzHostedService(options => options.WaitForJobsToComplete = true);
GlobalBoostraper.GlobalRegisterServices(builder.Services, builder.Configuration);
builder.Services.AddScoped<IPasswordHasher<IdentityUser>, PasswordHasher<IdentityUser>>();
builder.Services.AddOpenIddict()

    .AddCore(options =>
    {
        options.UseEntityFrameworkCore()
               .UseDbContext<IntranetContext>();
        options.UseQuartz();
    })
    .AddServer(options =>
    {
        options.SetAuthorizationEndpointUris(builder.Configuration["OpenIddict:Endpoints:Authorization"]!)
               .SetTokenEndpointUris(builder.Configuration["OpenIddict:Endpoints:Token"]!)
               .SetIntrospectionEndpointUris(builder.Configuration["OpenIddict:Endpoints:Introspection"]!)
               .SetLogoutEndpointUris(builder.Configuration["OpenIddict:Endpoints:Logout"]!)
               .SetUserinfoEndpointUris(builder.Configuration["OpenIddict:Endpoints:Userinfo"]!);

        options.AllowAuthorizationCodeFlow()
               .RequireProofKeyForCodeExchange()
               .AllowClientCredentialsFlow()
               .AllowPasswordFlow()
               .AllowHybridFlow()
               .AllowRefreshTokenFlow();

        options.SetAccessTokenLifetime(TimeSpan.FromMinutes(30));
        options.SetIdentityTokenLifetime(TimeSpan.FromMinutes(30));
        options.SetRefreshTokenLifetime(TimeSpan.FromDays(14));

        options.RegisterScopes(
           OpenIddictConstants.Scopes.OpenId,
           OpenIddictConstants.Scopes.Profile,
           OpenIddictConstants.Scopes.Email,
           OpenIddictConstants.Scopes.OfflineAccess,
           "api_IPD",
           "api_Eficiencia");

        options.AddDevelopmentEncryptionCertificate()
               .AddDevelopmentSigningCertificate();

        options.UseAspNetCore()
             //.EnableTokenEndpointPassthrough()
             .EnableAuthorizationEndpointPassthrough()
             .EnableLogoutEndpointPassthrough()
             .EnableVerificationEndpointPassthrough()
              .EnableStatusCodePagesIntegration();
        //.EnableUserinfoEndpointPassthrough();

        options.AddEventHandler<OpenIddictServerEvents.HandleTokenRequestContext>
        (builder => builder.UseScopedHandler<CustomValidationHandler>());
    })
    .AddValidation(options =>
    {
        options.UseLocalServer();
        options.UseAspNetCore();
        options.EnableAuthorizationEntryValidation();
    });

builder.Services.AddQuartz(options =>
{
    options.UseMicrosoftDependencyInjectionJobFactory();
    options.UseSimpleTypeLoader();
    options.UseInMemoryStore();
});

2.- Angular

export const authConfig: AuthConfig = {
  issuer: environment.urlIdentity,
  redirectUri: environment.urlRedirectBase  ,
   postLogoutRedirectUri: environment.urlRedirectBase,
  clientId: 'eficienciaFrontTest',
  scope: 'openid profile email offline_access api_Eficiencia',
  responseType: 'code',
  requireHttps: true, 
  showDebugInformation: true,
  useSilentRefresh: true,
  silentRefreshRedirectUri: environment.urlRedirectBase+ 'silent-refresh.html',
  timeoutFactor: 0.75,
  sessionChecksEnabled: true,
  clearHashAfterLogin: false,
};

3.- Mi configuración del API

builder.Services.AddOpenIddict()
       .AddValidation(options =>
       {
           // Note: the validation handler uses OpenID Connect discovery
           // to retrieve the issuer signing keys used to validate tokens.
           options.SetIssuer(builder.Configuration.GetValue<string>("OpenIddict:Url"));
           options.AddAudiences("resource_server_2");

           options.UseIntrospection()
              .SetClientId("resource_server_2")
              .SetClientSecret("EficienciaTalleres2025#4");

           // Register the System.Net.Http integration.
           options.UseSystemNetHttp();

           // Register the ASP.NET Core host.
           options.UseAspNetCore();

       options.AddEventHandler<OpenIddictValidationEvents.ProcessAuthenticationContext>(builder =>
       {
           builder.UseInlineHandler(context =>
           {
               Console.WriteLine(context.ValidateAccessToken);
               return ValueTask.CompletedTask;
           });
       });

           options.AddEventHandler<OpenIddictValidationEvents.PrepareConfigurationRequestContext>(builder =>
           {
               builder.UseInlineHandler(context =>
               {
                   Console.WriteLine(context.Error);
                   return ValueTask.CompletedTask;
               });
           });
       });

It is only when I publish in productive, the client does the authentication well, but when I communicate with the api in productive it fails. You can support me. Thank you so much

kevinchalet commented 2 months ago

Hi,

Support is reserved to sponsors and contributors. For more information on how to sponsor the project on GitHub, visit https://github.com/sponsors/kevinchalet.

Hope to see you on board soon!