Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the manual claims mapping logic from the Mortis.Client sample #284

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Web.Mvc;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using OpenIddict.Abstractions;
using OpenIddict.Client.Owin;
using static OpenIddict.Abstractions.OpenIddictConstants;

Expand Down Expand Up @@ -39,7 +38,7 @@ public async Task<ActionResult> LogOut(string returnUrl)
// Retrieve the identity stored in the local authentication cookie. If it's not available,
// this indicate that the user is already logged out locally (or has not logged in yet).
var result = await context.Authentication.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationType);
if (result is not { Identity: ClaimsIdentity identity })
if (result is not { Identity: ClaimsIdentity })
{
// Only allow local return URLs to prevent open redirect attacks.
return Redirect(Url.IsLocalUrl(returnUrl) ? returnUrl : "/");
Expand Down Expand Up @@ -112,33 +111,15 @@ public async Task<ActionResult> LogInCallback()
//
// By default, all claims extracted during the authorization dance are available. The claims collection stored
// in the cookie can be filtered out or mapped to different names depending the claim name or its issuer.
var claims = new List<Claim>(result.Identity.Claims
.Select(claim => claim switch
{
// Map the standard "sub" and custom "id" claims to ClaimTypes.NameIdentifier, which is
// the default claim type used by .NET and is required by the antiforgery components.
{ Type: Claims.Subject }
=> new Claim(ClaimTypes.NameIdentifier, claim.Value, claim.ValueType, claim.Issuer),

// Map the standard "name" claim to ClaimTypes.Name.
{ Type: Claims.Name }
=> new Claim(ClaimTypes.Name, claim.Value, claim.ValueType, claim.Issuer),

_ => claim
})
.Where(claim => claim switch
{
// Preserve the basic claims that are necessary for the application to work correctly.
{ Type: ClaimTypes.NameIdentifier or ClaimTypes.Name } => true,

// Don't preserve the other claims.
_ => false
}));

// The antiforgery components require both the ClaimTypes.NameIdentifier and identityprovider claims
// so the latter is manually added using the issuer identity resolved from the remote server.
claims.Add(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
result.Identity.GetClaim(Claims.AuthorizationServer)));
var claims = result.Identity.Claims.Where(claim => claim.Type is ClaimTypes.NameIdentifier or ClaimTypes.Name
//
// Preserve the registration details to be able to resolve them later.
//
or Claims.Private.RegistrationId or Claims.Private.ProviderName
//
// The ASP.NET 4.x antiforgery module requires preserving the "identityprovider" claim.
//
or "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider");

var identity = new ClaimsIdentity(claims,
authenticationType: CookieAuthenticationDefaults.AuthenticationType,
Expand All @@ -149,10 +130,10 @@ public async Task<ActionResult> LogInCallback()
var properties = new AuthenticationProperties(result.Properties.Dictionary
.Where(item => item switch
{
// Preserve the redirect URL.
// Preserve the return URL.
{ Key: ".redirect" } => true,

// Preserve the access, identity and refresh tokens returned in the token response, if available.
// If needed, the tokens returned by the authorization server can be stored in the authentication cookie.
{
Key: OpenIddictClientOwinConstants.Tokens.BackchannelAccessToken or
OpenIddictClientOwinConstants.Tokens.BackchannelIdentityToken or
Expand All @@ -165,7 +146,7 @@ OpenIddictClientOwinConstants.Tokens.BackchannelIdentityToken or
.ToDictionary(pair => pair.Key, pair => pair.Value));

context.Authentication.SignIn(properties, identity);
return Redirect(properties.RedirectUri);
return Redirect(properties.RedirectUri ?? "/");
}

// Note: this controller uses the same callback action for all providers
Expand Down
2 changes: 2 additions & 0 deletions samples/Mortis/Mortis.Client/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public void Configuration(IAppBuilder app)
options.AddRegistration(new OpenIddictClientRegistration
{
Issuer = new Uri("https://localhost:44349/", UriKind.Absolute),
ProviderName = "Local",
ProviderDisplayName = "Local OIDC server",

ClientId = "mvc",
ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
Expand Down