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 @@ -32,7 +32,7 @@
using Duende.IdentityServer.Hosting.DynamicProviders;
using Duende.IdentityServer.Internal;
using Duende.IdentityServer.Stores.Empty;
using Duende;
using Duende.IdentityServer.Endpoints.Results;

namespace Microsoft.Extensions.DependencyInjection;

Expand Down Expand Up @@ -123,23 +123,52 @@ public static IIdentityServerBuilder AddDefaultEndpoints(this IIdentityServerBui
builder.AddEndpoint<TokenEndpoint>(EndpointNames.Token, ProtocolRoutePaths.Token.EnsureLeadingSlash());
builder.AddEndpoint<UserInfoEndpoint>(EndpointNames.UserInfo, ProtocolRoutePaths.UserInfo.EnsureLeadingSlash());

builder.AddEndpointResultGenerator<AuthorizeInteractionPageResult, AuthorizeInteractionPageResultGenerator>();
builder.AddEndpointResultGenerator<AuthorizeResult, AuthorizeResultGenerator>();
builder.AddEndpointResultGenerator<BackchannelAuthenticationResult, BackchannelAuthenticationResultGenerator>();
builder.AddEndpointResultGenerator<BadRequestResult, BadRequestResultGenerator>();
builder.AddEndpointResultGenerator<CheckSessionResult, CheckSessionResultGenerator>();
builder.AddEndpointResultGenerator<DeviceAuthorizationResult, DeviceAuthorizationResultGenerator>();
builder.AddEndpointResultGenerator<DiscoveryDocumentResult, DiscoveryDocumentResultGenerator>();
builder.AddEndpointResultGenerator<EndSessionCallbackResult, EndSessionCallbackResultGenerator>();
builder.AddEndpointResultGenerator<EndSessionResult, EndSessionResultGenerator>();
builder.AddEndpointResultGenerator<IntrospectionResult, IntrospectionResultGenerator>();
builder.AddEndpointResultGenerator<JsonWebKeysResult, JsonWebKeysResultGenerator>();
builder.AddEndpointResultGenerator<ProtectedResourceErrorResult, ProtectedResourceErrorResultGenerator>();
builder.AddEndpointResultGenerator<StatusCodeResult, StatusCodeResultGenerator>();
builder.AddEndpointResultGenerator<TokenErrorResult, TokenErrorResultGenerator>();
builder.AddEndpointResultGenerator<TokenResult, TokenResultGenerator>();
builder.AddEndpointResultGenerator<TokenRevocationErrorResult, TokenRevocationErrorResultGenerator>();
builder.AddEndpointResultGenerator<UserInfoResult, UserInfoResultGenerator>();

return builder;
}

/// <summary>
/// Adds the endpoint.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TEndpoint"></typeparam>
/// <param name="builder">The builder.</param>
/// <param name="name">The name.</param>
/// <param name="path">The path.</param>
/// <returns></returns>
public static IIdentityServerBuilder AddEndpoint<T>(this IIdentityServerBuilder builder, string name, PathString path)
where T : class, IEndpointHandler
public static IIdentityServerBuilder AddEndpoint<TEndpoint>(this IIdentityServerBuilder builder, string name, PathString path)
where TEndpoint : class, IEndpointHandler
{
builder.Services.AddTransient<T>();
builder.Services.AddSingleton(new Duende.IdentityServer.Hosting.Endpoint(name, path, typeof(T)));
builder.Services.AddTransient<TEndpoint>();
builder.Services.AddSingleton(new Duende.IdentityServer.Hosting.Endpoint(name, path, typeof(TEndpoint)));

return builder;
}

/// <summary>
/// Adds the endpoint.
/// </summary>
public static IIdentityServerBuilder AddEndpointResultGenerator<TResult, TResultGenerator>(this IIdentityServerBuilder builder)
where TResult : class, IEndpointResult
where TResultGenerator : class, Duende.IdentityServer.Hosting.IEndpointResultGenerator<TResult>
{
builder.Services.AddTransient<Duende.IdentityServer.Hosting.IEndpointResultGenerator<TResult>, TResultGenerator>();
return builder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using Duende.IdentityServer.Validation;
using Microsoft.AspNetCore.Http;
using Duende.IdentityServer.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Duende.IdentityServer.Services;
using static Duende.IdentityServer.IdentityServerConstants;

Expand All @@ -21,12 +20,8 @@ namespace Duende.IdentityServer.Endpoints.Results;
/// Result for an interactive page
/// </summary>
/// <seealso cref="IEndpointResult" />
public abstract class AuthorizeInteractionPageResult : IEndpointResult
public abstract class AuthorizeInteractionPageResult : EndpointResult<AuthorizeInteractionPageResult>
{
private readonly ValidatedAuthorizeRequest _request;
private string _redirectUrl;
private string _returnUrlParameterName;

/// <summary>
/// Initializes a new instance of the <see cref="AuthorizeInteractionPageResult"/> class.
/// </summary>
Expand All @@ -36,51 +31,66 @@ public abstract class AuthorizeInteractionPageResult : IEndpointResult
/// <exception cref="System.ArgumentNullException">request</exception>
public AuthorizeInteractionPageResult(ValidatedAuthorizeRequest request, string redirectUrl, string returnUrlParameterName)
{
_request = request ?? throw new ArgumentNullException(nameof(request));
_redirectUrl = redirectUrl ?? throw new ArgumentNullException(nameof(redirectUrl));
_returnUrlParameterName = returnUrlParameterName ?? throw new ArgumentNullException(nameof(returnUrlParameterName));
Request = request ?? throw new ArgumentNullException(nameof(request));
RedirectUrl = redirectUrl ?? throw new ArgumentNullException(nameof(redirectUrl));
ReturnUrlParameterName = returnUrlParameterName ?? throw new ArgumentNullException(nameof(returnUrlParameterName));
}

private IServerUrls _urls;
private IAuthorizationParametersMessageStore _authorizationParametersMessageStore;
/// <summary>
/// The validated authorize request
/// </summary>
public ValidatedAuthorizeRequest Request { get; }

private void Init(HttpContext context)
{
_urls = context.RequestServices.GetRequiredService<IServerUrls>();
_authorizationParametersMessageStore = context.RequestServices.GetService<IAuthorizationParametersMessageStore>();
}
/// <summary>
/// The redirect URI
/// </summary>
public string RedirectUrl { get; }

/// <summary>
/// Executes the result.
/// The return URL param name
/// </summary>
/// <param name="context">The HTTP context.</param>
/// <returns></returns>
public async Task ExecuteAsync(HttpContext context)
public string ReturnUrlParameterName { get; }
}

class AuthorizeInteractionPageResultGenerator : IEndpointResultGenerator<AuthorizeInteractionPageResult>
{
private readonly IServerUrls _urls;
private readonly IAuthorizationParametersMessageStore _authorizationParametersMessageStore;

/// <summary>
/// Initializes a new instance of the <see cref="AuthorizeInteractionPageResult"/> class.
/// </summary>
public AuthorizeInteractionPageResultGenerator(IServerUrls urls, IAuthorizationParametersMessageStore authorizationParametersMessageStore = null)
{
Init(context);
_urls = urls;
_authorizationParametersMessageStore = authorizationParametersMessageStore;
}

/// <inheritdoc/>
public async Task ExecuteAsync(AuthorizeInteractionPageResult result, HttpContext context)
{
var returnUrl = _urls.BasePath.EnsureTrailingSlash() + ProtocolRoutePaths.AuthorizeCallback;

if (_authorizationParametersMessageStore != null)
{
var msg = new Message<IDictionary<string, string[]>>(_request.ToOptimizedFullDictionary());
var msg = new Message<IDictionary<string, string[]>>(result.Request.ToOptimizedFullDictionary());
var id = await _authorizationParametersMessageStore.WriteAsync(msg);
returnUrl = returnUrl.AddQueryString(Constants.AuthorizationParamsStore.MessageStoreIdParameterName, id);
}
else
{
returnUrl = returnUrl.AddQueryString(_request.ToOptimizedQueryString());
returnUrl = returnUrl.AddQueryString(result.Request.ToOptimizedQueryString());
}

var url = _redirectUrl;
var url = result.RedirectUrl;
if (!url.IsLocalUrl())
{
// this converts the relative redirect path to an absolute one if we're
// redirecting to a different server
returnUrl = _urls.Origin + returnUrl;
}

url = url.AddQueryString(_returnUrlParameterName, returnUrl);
url = url.AddQueryString(result.ReturnUrlParameterName, returnUrl);
context.Response.Redirect(_urls.GetAbsoluteUrl(url));
}
}
Loading