Skip to content
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 @@ -177,8 +177,8 @@ private string BuildRedirectUri(AuthorizeResponse response)

if (response.IsError && !uri.Contains('#'))
{
// https://tools.ietf.org/html/draft-bradley-oauth-open-redirector-00
uri += "#_=_";
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-29#section-4.1.3
uri += "#_";
}

return uri;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,67 @@ public async Task form_post_mode_should_not_add_deprecated_header_when_it_is_dis
_context.Response.Headers.ContentSecurityPolicy.First().Should().Contain($"script-src '{IdentityServerConstants.ContentSecurityPolicyHashes.AuthorizeScript}'");
_context.Response.Headers["X-Content-Security-Policy"].Should().BeEmpty();
}

[InlineData(OidcConstants.AuthorizeErrors.AccessDenied)]
[InlineData(OidcConstants.AuthorizeErrors.AccountSelectionRequired)]
[InlineData(OidcConstants.AuthorizeErrors.LoginRequired)]
[InlineData(OidcConstants.AuthorizeErrors.ConsentRequired)]
[InlineData(OidcConstants.AuthorizeErrors.InteractionRequired)]
[InlineData(OidcConstants.AuthorizeErrors.TemporarilyUnavailable)]
[InlineData(OidcConstants.AuthorizeErrors.UnmetAuthenticationRequirements)]
[Theory]
public async Task error_resulting_in_redirect_should_attach_fragment_to_location_header(string error)
{
_response.Error = error;
_response.Request = new ValidatedAuthorizeRequest
{
ClientId = "client",
GrantType = OidcConstants.GrantTypes.Implicit,
ResponseMode = OidcConstants.ResponseModes.Query,
RedirectUri = "http://client/callback",
ResponseType = OidcConstants.ResponseTypes.Token,
};

await _subject.WriteHttpResponse(new AuthorizeResult(_response), _context);

_context.Response.StatusCode.Should().Be(302);
var location = _context.Response.Headers.Location.First();
location.Should().StartWith("http://client/callback");
location.Should().Contain("#_");
}

[InlineData(OidcConstants.AuthorizeErrors.InvalidRequest)]
[InlineData(OidcConstants.AuthorizeErrors.UnauthorizedClient)]
[InlineData(OidcConstants.AuthorizeErrors.UnsupportedResponseType)]
[InlineData(OidcConstants.AuthorizeErrors.InvalidScope)]
[InlineData(OidcConstants.AuthorizeErrors.ServerError)]
[InlineData(OidcConstants.AuthorizeErrors.InvalidRequestUri)]
[InlineData(OidcConstants.AuthorizeErrors.InvalidRequestObject)]
[InlineData(OidcConstants.AuthorizeErrors.RequestNotSupported)]
[InlineData(OidcConstants.AuthorizeErrors.RequestUriNotSupported)]
[InlineData(OidcConstants.AuthorizeErrors.RegistrationNotSupported)]
[InlineData(OidcConstants.AuthorizeErrors.InvalidTarget)]
[Theory]
public async Task error_resulting_in_error_page_should_attach_fragment_to_error_model_redirect_uri(string error)
{
_response.Error = error;
_response.Request = new ValidatedAuthorizeRequest
{
ClientId = "client",
GrantType = OidcConstants.GrantTypes.Implicit,
ResponseMode = OidcConstants.ResponseModes.Query,
RedirectUri = "http://client/callback",
ResponseType = OidcConstants.ResponseTypes.Token,
};

await _subject.WriteHttpResponse(new AuthorizeResult(_response), _context);

_context.Response.StatusCode.Should().Be(302);
var location = _context.Response.Headers.Location.First();
var queryString = new Uri(location).Query;
var queryParams = QueryHelpers.ParseQuery(queryString);
var errorId = queryParams.First(kvp => kvp.Key == _options.UserInteraction.ErrorIdParameter).Value;
var errorMessage = await _mockErrorMessageStore.ReadAsync(errorId);
errorMessage.Data.RedirectUri.Should().Contain("#_");
}
}
Loading