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

Update the ASP.NET Core/OWIN hosts to support returning authentication properties for errored requests #2221

Merged
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
2 changes: 1 addition & 1 deletion sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ await manager.CreateAsync(new OpenIddictApplicationDescriptor
ClientId = "mvc",
ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
ClientType = ClientTypes.Confidential,
ConsentType = ConsentTypes.Explicit,
ConsentType = ConsentTypes.Systematic,
DisplayName = "MVC client application",
RedirectUris =
{
Expand Down
2 changes: 1 addition & 1 deletion sandbox/OpenIddict.Sandbox.AspNetCore.Server/Worker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ await manager.CreateAsync(new OpenIddictApplicationDescriptor
ClientId = "mvc",
ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
ClientType = ClientTypes.Confidential,
ConsentType = ConsentTypes.Explicit,
ConsentType = ConsentTypes.Systematic,
DisplayName = "MVC client application",
DisplayNames =
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,17 +156,24 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
return AuthenticateResult.NoResult();
}

var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[Properties.Error] = context.Error,
[Properties.ErrorDescription] = context.ErrorDescription,
[Properties.ErrorUri] = context.ErrorUri
});
var properties = CreateAuthenticationProperties();
properties.Items[Properties.Error] = context.Error;
properties.Items[Properties.ErrorDescription] = context.ErrorDescription;
properties.Items[Properties.ErrorUri] = context.ErrorUri;

return AuthenticateResult.Fail(SR.GetResourceString(SR.ID0113), properties);
}

else
{
var properties = CreateAuthenticationProperties();

return AuthenticateResult.Success(new AuthenticationTicket(
context.MergedPrincipal ?? new ClaimsPrincipal(new ClaimsIdentity()), properties,
OpenIddictClientAspNetCoreDefaults.AuthenticationScheme));
}

AuthenticationProperties CreateAuthenticationProperties()
{
var properties = new AuthenticationProperties
{
Expand Down Expand Up @@ -336,9 +343,7 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
properties.SetParameter(Properties.UserInfoTokenPrincipal, context.UserInfoTokenPrincipal);
}

return AuthenticateResult.Success(new AuthenticationTicket(
context.MergedPrincipal ?? new ClaimsPrincipal(new ClaimsIdentity()), properties,
OpenIddictClientAspNetCoreDefaults.AuthenticationScheme));
return properties;
}
}

Expand Down
21 changes: 13 additions & 8 deletions src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,22 @@ public override async Task<bool> InvokeAsync()
return null;
}

var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[Properties.Error] = context.Error,
[Properties.ErrorDescription] = context.ErrorDescription,
[Properties.ErrorUri] = context.ErrorUri
});
var properties = CreateAuthenticationProperties();
properties.Dictionary[Properties.Error] = context.Error;
properties.Dictionary[Properties.ErrorDescription] = context.ErrorDescription;
properties.Dictionary[Properties.ErrorUri] = context.ErrorUri;

return new AuthenticationTicket(null, properties);
return new AuthenticationTicket(new ClaimsIdentity(), properties);
}

else
{
var properties = CreateAuthenticationProperties();

return new AuthenticationTicket(context.MergedPrincipal?.Identity as ClaimsIdentity ?? new ClaimsIdentity(), properties);
}

AuthenticationProperties CreateAuthenticationProperties()
{
var properties = new AuthenticationProperties
{
Expand Down Expand Up @@ -240,7 +245,7 @@ public override async Task<bool> InvokeAsync()
properties.Dictionary[Tokens.UserInfoToken] = context.UserInfoToken;
}

return new AuthenticationTicket(context.MergedPrincipal?.Identity as ClaimsIdentity, properties);
return properties;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,10 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
return AuthenticateResult.NoResult();
}

var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[Properties.Error] = context.Error,
[Properties.ErrorDescription] = context.ErrorDescription,
[Properties.ErrorUri] = context.ErrorUri
});
var properties = CreateAuthenticationProperties();
properties.Items[Properties.Error] = context.Error;
properties.Items[Properties.ErrorDescription] = context.ErrorDescription;
properties.Items[Properties.ErrorUri] = context.ErrorUri;

return AuthenticateResult.Fail(SR.GetResourceString(SR.ID0113), properties);
}
Expand Down Expand Up @@ -199,6 +197,15 @@ OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType(
_ => null
};

var properties = CreateAuthenticationProperties(principal);

return AuthenticateResult.Success(new AuthenticationTicket(
principal ?? new ClaimsPrincipal(new ClaimsIdentity()), properties,
OpenIddictServerAspNetCoreDefaults.AuthenticationScheme));
}

AuthenticationProperties CreateAuthenticationProperties(ClaimsPrincipal? principal = null)
{
var properties = new AuthenticationProperties
{
ExpiresUtc = principal?.GetExpirationDate(),
Expand Down Expand Up @@ -325,9 +332,7 @@ OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType(
properties.StoreTokens(tokens);
}

return AuthenticateResult.Success(new AuthenticationTicket(
principal ?? new ClaimsPrincipal(new ClaimsIdentity()), properties,
OpenIddictServerAspNetCoreDefaults.AuthenticationScheme));
return properties;
}
}

Expand Down
21 changes: 13 additions & 8 deletions src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,12 @@ public override async Task<bool> InvokeAsync()
return null;
}

var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[Properties.Error] = context.Error,
[Properties.ErrorDescription] = context.ErrorDescription,
[Properties.ErrorUri] = context.ErrorUri
});
var properties = CreateAuthenticationProperties();
properties.Dictionary[Properties.Error] = context.Error;
properties.Dictionary[Properties.ErrorDescription] = context.ErrorDescription;
properties.Dictionary[Properties.ErrorUri] = context.ErrorUri;

return new AuthenticationTicket(null, properties);
return new AuthenticationTicket(new ClaimsIdentity(), properties);
}

else
Expand Down Expand Up @@ -191,6 +189,13 @@ OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType(
_ => null
};

var properties = CreateAuthenticationProperties(principal);

return new AuthenticationTicket(principal?.Identity as ClaimsIdentity ?? new ClaimsIdentity(), properties);
}

AuthenticationProperties CreateAuthenticationProperties(ClaimsPrincipal? principal = null)
{
var properties = new AuthenticationProperties
{
ExpiresUtc = principal?.GetExpirationDate(),
Expand Down Expand Up @@ -240,7 +245,7 @@ OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType(
properties.Dictionary[Tokens.UserCode] = context.UserCode;
}

return new AuthenticationTicket(principal?.Identity as ClaimsIdentity, properties);
return properties;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,10 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
return AuthenticateResult.NoResult();
}

var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[Properties.Error] = context.Error,
[Properties.ErrorDescription] = context.ErrorDescription,
[Properties.ErrorUri] = context.ErrorUri
});
var properties = CreateAuthenticationProperties();
properties.Items[Properties.Error] = context.Error;
properties.Items[Properties.ErrorDescription] = context.ErrorDescription;
properties.Items[Properties.ErrorUri] = context.ErrorUri;

return AuthenticateResult.Fail(SR.GetResourceString(SR.ID0113), properties);
}
Expand All @@ -177,6 +175,15 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
_ => null
};

var properties = CreateAuthenticationProperties(principal);

return AuthenticateResult.Success(new AuthenticationTicket(
principal ?? new ClaimsPrincipal(new ClaimsIdentity()), properties,
OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme));
}

AuthenticationProperties CreateAuthenticationProperties(ClaimsPrincipal? principal = null)
{
var properties = new AuthenticationProperties
{
ExpiresUtc = principal?.GetExpirationDate(),
Expand Down Expand Up @@ -208,9 +215,7 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
properties.StoreTokens(tokens);
}

return AuthenticateResult.Success(new AuthenticationTicket(
principal ?? new ClaimsPrincipal(new ClaimsIdentity()), properties,
OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme));
return properties;
}
}

Expand Down
21 changes: 13 additions & 8 deletions src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,12 @@ public override async Task<bool> InvokeAsync()
return null;
}

var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[Properties.Error] = context.Error,
[Properties.ErrorDescription] = context.ErrorDescription,
[Properties.ErrorUri] = context.ErrorUri
});
var properties = CreateAuthenticationProperties();
properties.Dictionary[Properties.Error] = context.Error;
properties.Dictionary[Properties.ErrorDescription] = context.ErrorDescription;
properties.Dictionary[Properties.ErrorUri] = context.ErrorUri;

return new AuthenticationTicket(null, properties);
return new AuthenticationTicket(new ClaimsIdentity(), properties);
}

else
Expand All @@ -170,6 +168,13 @@ public override async Task<bool> InvokeAsync()
_ => null
};

var properties = CreateAuthenticationProperties(principal);

return new AuthenticationTicket(principal?.Identity as ClaimsIdentity ?? new ClaimsIdentity(), properties);
}

AuthenticationProperties CreateAuthenticationProperties(ClaimsPrincipal? principal = null)
{
var properties = new AuthenticationProperties
{
ExpiresUtc = principal?.GetExpirationDate(),
Expand All @@ -184,7 +189,7 @@ public override async Task<bool> InvokeAsync()
properties.Dictionary[TokenTypeHints.AccessToken] = context.AccessToken;
}

return new AuthenticationTicket(principal?.Identity as ClaimsIdentity, properties);
return properties;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using Xunit;
using Xunit.Abstractions;
using static OpenIddict.Server.OpenIddictServerEvents;
using static OpenIddict.Server.OpenIddictServerHandlers;
using static OpenIddict.Server.OpenIddictServerHandlers.Protection;

#if SUPPORTS_JSON_NODES
Expand Down Expand Up @@ -134,6 +135,54 @@ public async Task ProcessAuthentication_ExpirationDateIsMappedToIssuedUtc()
Assert.Equal(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.ExpiresUtc);
}

[Fact]
public async Task ProcessAuthentication_CustomPropertiesAreAddedForErroredAuthenticationResults()
{
// Arrange
await using var server = await CreateServerAsync(options =>
{
options.EnableDegradedMode();
options.SetAuthorizationEndpointUris("/authenticate/properties");

options.UseAspNetCore()
.EnableErrorPassthrough()
.EnableAuthorizationEndpointPassthrough();

options.AddEventHandler<ProcessAuthenticationContext>(builder =>
{
builder.UseInlineHandler(context =>
{
context.RejectIdentityToken = true;

context.Properties["custom_property"] = "value";

return default;
});

builder.SetOrder(EvaluateValidatedTokens.Descriptor.Order + 1);
});
});

await using var client = await server.CreateClientAsync();

// Act
var response = await client.PostAsync("/authenticate/properties", new OpenIddictRequest
{
ClientId = "Fabrikam",
IdTokenHint = "id_token_hint",
Nonce = "n-0S6_WzA2Mj",
RedirectUri = "http://www.fabrikam.com/path",
ResponseType = "id_token",
Scope = Scopes.OpenId
});

// Assert
var properties = new AuthenticationProperties(response.GetParameters()
.ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value));

Assert.Equal("value", properties.Items["custom_property"]);
}

[Fact]
public async Task ProcessChallenge_ImportsAuthenticationProperties()
{
Expand Down
Loading