Agustin Luques
Agustin Luques

Reputation: 67

OpenIdDict is ignoring AuthenticationProperties

I'm migrating from .Net Framewrok to Net Core and I'm using OpenIdDict instead of a SimpleAuthorizationProvider.

I can't modify the frontend so I need to send the token with the same response structure. I'm adding AuthenticationProperties but it seems OpenIdDict is ignoring them.

public async Task<IActionResult> Token()
        {
            var request = HttpContext.GetOpenIddictServerRequest() ??
                throw new InvalidOperationException("The OpenID Connect request cannot be retrieved.");


            var user = await _userManager.FindByNameAsync(request.Username);


            var principal = await _signInManager.CreateUserPrincipalAsync(user);

            foreach (var claim in principal.Claims)
            {
                claim.SetDestinations(GetDestinations(claim, principal));
            }

            principal.SetAccessTokenLifetime(TimeSpan.FromSeconds(180));


            // Include resources and scopes, as appropriate
            var scope = new[]
            {
                Scopes.OfflineAccess,
            };
            principal.SetScopes(scope);

            var props = new AuthenticationProperties(new Dictionary<string, string>
            {
                {"id", "user.Id"},
                {"userName", "context.UserName"},
                {"firstName", "user.FirstName"},
                {"lastName", "user.LastName"},
                {"profilePicUri", "string.IsNullOrEmpty(user.ProfilePicUri) ? 'NA' : user.ProfilePicUri"},
                {"language", "user.Language ?? 'en'"},
                {"lastLoginDateTime", "user.LastLoginDateTime.ToString()"},
                {"roles", "appUserRoles"},
                {"roleNames", "appUserRoleNames"},
                {"actions", "appUserRoleActions"},
                {"azureADToken", "azureAdToken"},
                {"userSessionId", "userSessionId"},
                {"as:client_id", "context.ClientId == null ? string.Empty : context.ClientId"}
            });

            // Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
            return SignIn(principal, props, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
        }

But I'm seeing the response like this:

{
    "access_token": "...",
    "refresh_token": "RqE4_j1N2yL_JYQKAupFVOigDGbs3tZCD9RifP3Suz0",
    "token_type": "Bearer",
    "expires_in": 179,
    "scope": "offline_access"
}

And I want to see with all the others properties too. I can't decode de token to obtain them from the claims.

My StartUp.cs has

services.AddOpenIddict()
                // Register the OpenIddict core components.
                .AddCore(options =>
                {
                    // Configure OpenIddict to use the Entity Framework Core stores and models.
                    options.UseEntityFrameworkCore()
                           .UseDbContext<ApplicationDbContext>();
                })
                // Register the OpenIddict server components.
                .AddServer(options =>
                {
                    // Enable the token endpoint (required to use the password flow).
                    options.SetTokenEndpointUris("/connect/token");

                    // Allow client applications to use the grant_type=password flow.
                    options.AllowPasswordFlow()
                           .AllowRefreshTokenFlow();


                    // Accept requests sent by unknown clients (i.e that don't send a client_id).
                    // When this option is not used, a client registration must be
                    // created for each client using IOpenIddictApplicationManager.
                    options.AcceptAnonymousClients();

                    // Register the signing and encryption credentials.
                    options.AddDevelopmentEncryptionCertificate()
                           .AddDevelopmentSigningCertificate();

                    // Register the ASP.NET Core host and configure the ASP.NET Core-specific options.
                    options.UseAspNetCore()
                           .EnableStatusCodePagesIntegration()
                           .EnableAuthorizationEndpointPassthrough()
                           .EnableLogoutEndpointPassthrough()
                           .EnableTokenEndpointPassthrough()
                           .EnableUserinfoEndpointPassthrough()
                           .EnableVerificationEndpointPassthrough()
                           .DisableTransportSecurityRequirement();
                })
                // Register the OpenIddict validation components.
                .AddValidation(options =>
                {
                    // Import the configuration from the local OpenIddict server instance.
                    options.UseLocalServer();

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

Upvotes: 1

Views: 1508

Answers (1)

K&#233;vin Chalet
K&#233;vin Chalet

Reputation: 42070

You must explicitly add the custom properties you want using the events model. Here's how you can do that:

services.AddOpenIddict()
    .AddServer(options =>
    {
        options.AddEventHandler<ProcessSignInContext>(builder =>
        {
            builder.UseInlineHandler(context =>
            {
                // Retrieve the AuthenticationProperties set from the authorization controller
                // and add a "custom_property" containing the value of the "property" property.
                var properties = context.Transaction.GetProperty<AuthenticationProperties>(
                    typeof(AuthenticationProperties).FullName);

                context.Response["custom_property"] = properties?.GetString("property");

                return default;
            });
        });
    });

Upvotes: 4

Related Questions