Reputation: 67
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
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