by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 06:59
    kinosang commented #736
  • Aug 03 17:50
    kevinchalet closed #858
  • Aug 03 17:50
    kevinchalet commented #858
  • Aug 03 17:49
    kevinchalet labeled #1051
  • Aug 03 17:49
    kevinchalet milestoned #1051
  • Aug 03 17:49
    kevinchalet labeled #1051
  • Aug 03 17:49
    kevinchalet opened #1051
  • Aug 03 17:41
    kevinchalet commented #736
  • Aug 03 17:12

    kevinchalet on 3.0.0-beta3

    (compare)

  • Aug 03 10:53
    igorklimenko commented #1049
  • Aug 03 10:27
    kevinchalet commented #1049
  • Aug 03 10:10
    kinosang commented #1049
  • Aug 03 10:08
    kinosang commented #1049
  • Aug 03 10:05
    kinosang commented #1049
  • Aug 03 10:01
    igorklimenko commented #1049
  • Aug 03 05:53

    kevinchalet on dev

    Remove authorization code/ident… (compare)

  • Aug 03 05:53
    kevinchalet closed #1050
  • Aug 03 05:40
    kevinchalet assigned #1050
  • Aug 03 05:40
    kevinchalet milestoned #1050
  • Aug 03 05:40
    kevinchalet opened #1050
Kévin Chalet
@kevinchalet
It's still there, but all the classes are now suffixed with Context, like in ASOS.
So the class you're looking for is HandleTokenRequestContext.
vincesocal
@vincesocal_gitlab
here is my implementation, but it does not return the token. what did I do wrong?
                builder.AddEventHandler<OpenIddictServerEvents.HandleTokenRequestContext>(configuration =>
                    configuration.UseInlineHandler(context =>
                    {
                        var identity = new ClaimsIdentity(TokenValidationParameters.DefaultAuthenticationType);
                        identity.AddClaim(Claims.Subject, "Demo User", Destinations.AccessToken, Destinations.IdentityToken);
                        identity.AddClaim(Claims.Role, "demo", Destinations.AccessToken, Destinations.IdentityToken);
                        identity.AddClaim(Claims.Audience, "app-api-bnl", Destinations.AccessToken, Destinations.IdentityToken);

                        var claimsPrinciple = new ClaimsPrincipal(identity);
                        claimsPrinciple.SetScopes(Scopes.OpenId, Scopes.Email, Scopes.Profile, Scopes.Roles);

                        context.Principal = claimsPrinciple;

                        return default;
                    }));
vincesocal
@vincesocal_gitlab
Do I have to manually set the context.Response? How is the context.Response populated before returning to the client?
Kévin Chalet
@kevinchalet
Your snippet is fine. What does it return? Anything interesting in the logs?
vincesocal
@vincesocal_gitlab
@kevinchalet only the following
info: OpenIddict.Server.OpenIddictServerProvider[0]
The token request was successfully extracted: {
"grant_type": "password",
"username": "Demo",
"password": "[redacted]"
}.
info: OpenIddict.Server.OpenIddictServerProvider[0]
The token request was successfully validated.
same thing happened when I used UseInMemoryDatabase with AddCore()
Kévin Chalet
@kevinchalet
Share your Startup, please.
vincesocal
@vincesocal_gitlab
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
        services.AddControllers();

        // openid
        services.AddOpenIddict()
            // Register the OpenIddict server components.
            .AddServer(builder =>
            {
                // Enable the password flow
                builder.AllowPasswordFlow();

                // Enable the token endpoint
                builder.SetTokenEndpointUris($"/api/v1.0/connect/token");

                // Register the signing and encryption credentials.  Used dev for now until we have a pfx
                builder.AddDevelopmentEncryptionCertificate()
                    .AddDevelopmentSigningCertificate();

                // Register the ASP.NET Core host and configure the ASP.NET Core specific options
                builder.UseAspNetCore()
                    .EnableTokenEndpointPassthrough()
                    .DisableTransportSecurityRequirement(); // During development ONLY!

                #region Disable openiddict core features like database-backed store

                // Enabled, all the features that rely on the OpenIddict application, authorization, scope
                // and token managers (contained in the OpenIddict.Core package) are automatically disabled
                builder.EnableDegradedMode();

                builder.AddEventHandler<OpenIddictServerEvents.ValidateTokenRequestContext>(configuration =>
                    configuration.UseInlineHandler(context =>
                    {
                        if (!context.Request.IsPasswordGrantType())
                        {
                            context.Reject(error: Errors.UnsupportedGrantType, description: "The specified grant type is not supported");
                            return default;
                        }

                        if (string.Compare(context.ClientId, "demo_app", StringComparison.OrdinalIgnoreCase) != 0)
                        {
                            context.Reject(error: Errors.InvalidClient, description: "The specified 'client_id' doesn't match a registered application.");
                            return default;
                        }

                        if (context.Request.Username != "Demo" || context.Request.Password != "DemoTest123!")
                        {
                            context.Reject(error: Errors.InvalidGrant, description: "Invalid username or password");
                            return default;
                        }

                        return default;
                    }));

                builder.AddEventHandler<OpenIddictServerEvents.HandleTokenRequestContext>(configuration =>
                    configuration.UseInlineHandler(context =>
                    {
                        var identity = new ClaimsIdentity(TokenValidationParameters.DefaultAuthenticationType);
                        identity.AddClaim(Claims.Subject, "Demo User", Destinations.AccessToken, Destinat
it seems to be cut off. Paste the set up again
        services.AddOpenIddict()
            // Register the OpenIddict server components.
            .AddServer(builder =>
            {
                // Enable the password flow
                builder.AllowPasswordFlow();

                // Enable the token endpoint
                builder.SetTokenEndpointUris($"/api/v1.0/connect/token");

                // Register the signing and encryption credentials.  Used dev for now until we have a pfx
                builder.AddDevelopmentEncryptionCertificate()
                    .AddDevelopmentSigningCertificate();

                // Register the ASP.NET Core host and configure the ASP.NET Core specific options
                builder.UseAspNetCore()
                    .EnableTokenEndpointPassthrough()
                    .DisableTransportSecurityRequirement(); // During development ONLY!

                #region Disable openiddict core features like database-backed store

                // Enabled, all the features that rely on the OpenIddict application, authorization, scope
                // and token managers (contained in the OpenIddict.Core package) are automatically disabled
                builder.EnableDegradedMode();

                builder.AddEventHandler<OpenIddictServerEvents.ValidateTokenRequestContext>(configuration =>
                    configuration.UseInlineHandler(context =>
                    {
                        if (!context.Request.IsPasswordGrantType())
                        {
                            context.Reject(error: Errors.UnsupportedGrantType, description: "The specified grant type is not supported");
                            return default;
                        }

                        if (string.Compare(context.ClientId, "demo_app", StringComparison.OrdinalIgnoreCase) != 0)
                        {
                            context.Reject(error: Errors.InvalidClient, description: "The specified 'client_id' doesn't match a registered application.");
                            return default;
                        }

                        if (context.Request.Username != "Demo" || context.Request.Password != "DemoTest123!")
                        {
                            context.Reject(error: Errors.InvalidGrant, description: "Invalid username or password");
                            return default;
                        }

                        return default;
                    }));

                builder.AddEventHandler<OpenIddictServerEvents.HandleTokenRequestContext>(configuration =>
                    configuration.UseInlineHandler(context =>
                    {
                        var identity = new ClaimsIdentity(TokenValidationParameters.DefaultAuthenticationType);
                        identity.AddClaim(Claims.Subject, "Demo User", Destinations.AccessToken, Destinations.IdentityToken);
                        identity.AddClaim(Claims.Role, "demo", Destinations.AccessToken, Destinations.IdentityToken);
                        identity.AddClaim(Claims.Audience, "app-api-bnl", Destinations.AccessToken, Destinations.IdentityToken);

                        var claimsPrinciple = new ClaimsPrincipal(identity);
                        claimsPrinciple.SetScopes(Scopes.OpenId, Scopes.Email, Scopes.Profile, Scopes.Roles);

                        context.Principal = claimsPrinciple;
                        context.HandleRequest();

                        return default;
                    }));

                #endregion Disable openiddict core features like database-backed store
            })

            // Register the OpenIddict validation components.
            .AddValidation(options =>
            {
                // Import the configuration from the local OpenIddict server instance
                options.UseLocalServer();
            .AddValidation(options =>
            {
                // Import the configuration from the local OpenIddict server instance
                options.UseLocalServer();

                // Register the ASP.NET Core host
                options.UseAspNetCore();
            });
if I took out by commenting //context.HandleRequest(); I got 404
Kévin Chalet
@kevinchalet
Remove EnableTokenEndpointPassthrough().
It indicates to OpenIddict that you don't want to use the events model to handle token requests and that you want the requests to be handled later in the ASP.NET Core pipeline.
Typically, in a MVC controller.
vincesocal
@vincesocal_gitlab
@kevinchalet thanks Kevin!
Kévin Chalet
@kevinchalet
You're welcome :smile:
@vincesocal_gitlab out of curiosity, are you migrating from ASOS or is it for a completely new app?
vincesocal
@vincesocal_gitlab
@kevinchalet I have been using my own brewed implementation but I found yours! :D
so it is a completely new app
thanks again. It helps!
robertovaldesperez
@robertovaldesperez
hi @kevinchalet is posible decorate a proxy layer (layer between controller layer and services layer) with [Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)].
I have four layers Controller, Proxy, Service and Repository
Kévin Chalet
@kevinchalet
Hey. It’s not exactly an OpenIddict-specific question, but anyway: no, that attribute has no effect outside ASP.NET Core. But nothing prevents you from flowing the principal from the controller to your proxy layer.
Alexey
@askalione
Hi, @kevinchalet, i'm trying to use OpenIddict 3.0 and i have two questions:
  1. What i should configure in prod instead of AddDevelopmentEncryptionCertificate()? (i'm new on encryption)
  2. How can i configure scheme name to "Bearer" (for example) instead of OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme ("OpenIddict.Validation.AspNetCore")?
Kévin Chalet
@kevinchalet
Hi.
You can generate a certificate and store it in an appropriate place (Azure Key Vault, X.509 machine store, etc.)
Regarding the scheme, it's not configurable. However, you can create your own Bearer -> OpenIddict.Validation.AspNetCore redirection using the ASP.NET Core AddSchemeHandler() extension.
Alexey
@askalione
@kevinchalet thank you!
I have not found docs about AddSchemeHandler() extensions, can u please give me a link?
I'm trying AddPolicyScheme() but dont understand how it's work yet.
Kévin Chalet
@kevinchalet
Ah yeah, it’s AddPolicyScheme, my bad.
Dunno if there’s any docs yet.
Alexey
@askalione
You mean something like that? -
services.AddAuthentication(options =>
{
    options.DefaultScheme = "PolicyScheme";
})
.AddCookie("CookieScheme")
.AddPolicyScheme("PolicyScheme", "PolicyScheme", options =>
{
    options.ForwardDefaultSelector = context =>
    {
        var header = context.Request.Headers["Authorization"].FirstOrDefault();
        if (header?.StartsWith("Bearer ") == true)
        {
            return OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme;
        }

        return "CookieScheme";
    };
});
Kévin Chalet
@kevinchalet
Well, falling back to cookies for Bearer is quite dangerous, so yeah, but without the if and the cookies handler.
Alexey
@askalione
@kevinchalet okay, thank you!
Alexey
@askalione
@kevinchalet , it's great! ty!
@kevinchalet, can u help me pls.
After decorate Controller [Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)] the response has become just 401 status code only with empty content.
But i need return some json content { statusCode: 401, message: "Unauthorized" } beside Response.StatusCode 401.
How i can handle authorization result?
Kévin Chalet
@kevinchalet
You have multiple options to support that: you can use the status code middleware shipping with ASP.NET Core to intercept 401 responses and return the body you want or you can use OpenIddict's event model (see https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs)
That said, unless you have legacy clients that use this specific content, consider using the standard WWW-Authenticate response header.
@/all OpenIddict 3.0 beta2 is out. Read https://kevinchalet.com/2020/07/08/openiddict-3-0-beta2-is-out/ for more information.
Alexey
@askalione
@kevinchalet, sorry for one more question.
When i do AuthorizationCode flow and callback with authorization code - IIS error - 404.15 - Query String Too Long
Is it OK that code too much length (see screenshot)?
Is it possible to somehow reduce the size of authorization code? (Actualy principal have 4 claims payload)?
Kévin Chalet
@kevinchalet
Did you read my blog post? :worried:
Alexey
@askalione

You mean this ? -

With response_mode=form_post being impacted by same-site, some applications are moving back to the query response mode (the default mode for the authorization code flow). To avoid token length issues with clients using response_mode=query and having strict query string limits, authorization codes are now reference tokens in OpenIddict 3.0 beta2.

I'm using OpenIddict 3.0 beta1 for now
Can i use options.UseReferenceTokens() with options.EnableDegradedMode()?
Kévin Chalet
@kevinchalet
No, reference tokens are only supported with the degraded mode disabled.
You’ll get full length authorization codes with the degraded mode enabled.