21 changed files with 2723 additions and 16 deletions
@ -0,0 +1,24 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFrameworks>netcoreapp2.1;netcoreapp3.0;net472</TargetFrameworks> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0' "> |
||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\OpenIddict.Server.AspNetCore\OpenIddict.Server.AspNetCore.csproj" /> |
||||
|
<ProjectReference Include="..\OpenIddict.Server.IntegrationTests\OpenIddict.Server.IntegrationTests.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(AspNetCoreVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' "> |
||||
|
<Reference Include="System.Net.Http" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,58 @@ |
|||||
|
/* |
||||
|
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
* See https://github.com/openiddict/openiddict-core for more information concerning
|
||||
|
* the license and the contributors participating to this project. |
||||
|
*/ |
||||
|
|
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using OpenIddict.Abstractions; |
||||
|
using OpenIddict.Server.FunctionalTests; |
||||
|
using Xunit; |
||||
|
using static OpenIddict.Abstractions.OpenIddictConstants; |
||||
|
|
||||
|
namespace OpenIddict.Server.AspNetCore.FunctionalTests |
||||
|
{ |
||||
|
public partial class OpenIddictServerAspNetCoreIntegrationTests : OpenIddictServerIntegrationTests |
||||
|
{ |
||||
|
[Fact(Skip = "The handler responsible of rejecting such requests has not been ported yet.")] |
||||
|
public async Task ExtractAuthorizationRequest_RequestIdParameterIsRejectedWhenRequestCachingIsDisabled() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var client = CreateClient(options => options.EnableDegradedMode()); |
||||
|
|
||||
|
// Act
|
||||
|
var response = await client.PostAsync("/connect/authorize", new OpenIddictRequest |
||||
|
{ |
||||
|
RequestId = "EFAF3596-F868-497F-96BB-AA2AD1F8B7E7" |
||||
|
}); |
||||
|
|
||||
|
// Assert
|
||||
|
Assert.Equal(Errors.InvalidRequest, response.Error); |
||||
|
Assert.Equal("The 'request_id' parameter is not supported.", response.ErrorDescription); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task ExtractAuthorizationRequest_InvalidRequestIdParameterIsRejected() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var client = CreateClient(options => |
||||
|
{ |
||||
|
options.Services.AddDistributedMemoryCache(); |
||||
|
|
||||
|
options.UseAspNetCore() |
||||
|
.EnableAuthorizationEndpointCaching(); |
||||
|
}); |
||||
|
|
||||
|
// Act
|
||||
|
var response = await client.PostAsync("/connect/authorize", new OpenIddictRequest |
||||
|
{ |
||||
|
RequestId = "EFAF3596-F868-497F-96BB-AA2AD1F8B7E7" |
||||
|
}); |
||||
|
|
||||
|
// Assert
|
||||
|
Assert.Equal(Errors.InvalidRequest, response.Error); |
||||
|
Assert.Equal("The specified 'request_id' parameter is invalid.", response.ErrorDescription); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,107 @@ |
|||||
|
/* |
||||
|
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
* See https://github.com/openiddict/openiddict-core for more information concerning
|
||||
|
* the license and the contributors participating to this project. |
||||
|
*/ |
||||
|
|
||||
|
using System; |
||||
|
using System.Security.Claims; |
||||
|
using System.Text.Json; |
||||
|
using Microsoft.AspNetCore.Authentication; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.TestHost; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using OpenIddict.Abstractions; |
||||
|
using OpenIddict.Server.FunctionalTests; |
||||
|
using static OpenIddict.Abstractions.OpenIddictConstants; |
||||
|
|
||||
|
namespace OpenIddict.Server.AspNetCore.FunctionalTests |
||||
|
{ |
||||
|
public partial class OpenIddictServerAspNetCoreIntegrationTests : OpenIddictServerIntegrationTests |
||||
|
{ |
||||
|
protected override OpenIddictServerIntegrationTestClient CreateClient(Action<OpenIddictServerBuilder> configuration = null) |
||||
|
{ |
||||
|
var builder = new WebHostBuilder(); |
||||
|
|
||||
|
builder.UseEnvironment("Testing"); |
||||
|
|
||||
|
builder.ConfigureServices(ConfigureServices); |
||||
|
builder.ConfigureServices(services => |
||||
|
{ |
||||
|
services.AddOpenIddict() |
||||
|
.AddServer(options => |
||||
|
{ |
||||
|
// Disable the transport security requirement during testing.
|
||||
|
options.UseAspNetCore() |
||||
|
.DisableTransportSecurityRequirement(); |
||||
|
|
||||
|
configuration?.Invoke(options); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
builder.Configure(app => |
||||
|
{ |
||||
|
app.Use(next => async context => |
||||
|
{ |
||||
|
await next(context); |
||||
|
|
||||
|
var feature = context.Features.Get<OpenIddictServerAspNetCoreFeature>(); |
||||
|
var response = feature?.Transaction.GetProperty<object>("custom_response"); |
||||
|
if (response != null) |
||||
|
{ |
||||
|
context.Response.ContentType = "application/json"; |
||||
|
await context.Response.WriteAsync(JsonSerializer.Serialize(response)); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
app.UseAuthentication(); |
||||
|
|
||||
|
app.Use(next => context => |
||||
|
{ |
||||
|
if (context.Request.Path == "/invalid-signin") |
||||
|
{ |
||||
|
var identity = new ClaimsIdentity(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); |
||||
|
identity.AddClaim(Claims.Subject, "Bob le Bricoleur"); |
||||
|
|
||||
|
var principal = new ClaimsPrincipal(identity); |
||||
|
|
||||
|
return context.SignInAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, principal); |
||||
|
} |
||||
|
|
||||
|
else if (context.Request.Path == "/invalid-signout") |
||||
|
{ |
||||
|
return context.SignOutAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); |
||||
|
} |
||||
|
|
||||
|
else if (context.Request.Path == "/invalid-challenge") |
||||
|
{ |
||||
|
return context.ChallengeAsync( |
||||
|
OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, |
||||
|
new AuthenticationProperties()); |
||||
|
} |
||||
|
|
||||
|
else if (context.Request.Path == "/invalid-authenticate") |
||||
|
{ |
||||
|
return context.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); |
||||
|
} |
||||
|
|
||||
|
return next(context); |
||||
|
}); |
||||
|
|
||||
|
app.Run(context => |
||||
|
{ |
||||
|
context.Response.ContentType = "application/json"; |
||||
|
return context.Response.WriteAsync(JsonSerializer.Serialize(new |
||||
|
{ |
||||
|
name = "Bob le Magnifique" |
||||
|
})); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
var server = new TestServer(builder); |
||||
|
return new OpenIddictServerIntegrationTestClient(server.CreateClient()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,27 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFrameworks>netcoreapp2.1;netcoreapp3.0;net472</TargetFrameworks> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<EmbeddedResource Include="Certificate.cer" /> |
||||
|
<EmbeddedResource Include="Certificate.pfx" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\OpenIddict.Core\OpenIddict.Core.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\OpenIddict.Server\OpenIddict.Server.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="AngleSharp" Version="$(AngleSharpVersion)" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(ExtensionsVersion)" /> |
||||
|
<PackageReference Include="Moq" Version="$(MoqVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' "> |
||||
|
<Reference Include="System.Net.Http" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,458 @@ |
|||||
|
/* |
||||
|
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
* See https://github.com/openiddict/openiddict-core for more information concerning
|
||||
|
* the license and the contributors participating to this project. |
||||
|
*/ |
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Net.Http; |
||||
|
using System.Text; |
||||
|
using System.Text.Encodings.Web; |
||||
|
using System.Text.Json; |
||||
|
using System.Threading.Tasks; |
||||
|
using AngleSharp.Html.Parser; |
||||
|
using Microsoft.Extensions.Primitives; |
||||
|
using OpenIddict.Abstractions; |
||||
|
|
||||
|
namespace OpenIddict.Server.FunctionalTests |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Exposes methods that allow sending OpenID Connect
|
||||
|
/// requests and extracting the corresponding responses.
|
||||
|
/// </summary>
|
||||
|
public class OpenIddictServerIntegrationTestClient |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the OpenID Connect client.
|
||||
|
/// </summary>
|
||||
|
public OpenIddictServerIntegrationTestClient() |
||||
|
: this(new HttpClient()) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the OpenID Connect client.
|
||||
|
/// </summary>
|
||||
|
/// <param name="client">The HTTP client used to communicate with the OpenID Connect server.</param>
|
||||
|
public OpenIddictServerIntegrationTestClient(HttpClient client) |
||||
|
: this(client, new HtmlParser()) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the OpenID Connect client.
|
||||
|
/// </summary>
|
||||
|
/// <param name="client">The HTTP client used to communicate with the OpenID Connect server.</param>
|
||||
|
/// <param name="parser">The HTML parser used to parse the responses returned by the OpenID Connect server.</param>
|
||||
|
public OpenIddictServerIntegrationTestClient(HttpClient client, HtmlParser parser) |
||||
|
{ |
||||
|
if (client == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(client)); |
||||
|
} |
||||
|
|
||||
|
if (parser == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(parser)); |
||||
|
} |
||||
|
|
||||
|
HttpClient = client; |
||||
|
HtmlParser = parser; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the underlying HTTP client used to
|
||||
|
/// communicate with the OpenID Connect server.
|
||||
|
/// </summary>
|
||||
|
public HttpClient HttpClient { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the underlying HTML parser used to parse the
|
||||
|
/// responses returned by the OpenID Connect server.
|
||||
|
/// </summary>
|
||||
|
public HtmlParser HtmlParser { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends an empty OpenID Connect request to the given endpoint using GET
|
||||
|
/// and converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public Task<OpenIddictResponse> GetAsync(string uri) |
||||
|
=> GetAsync(uri, new OpenIddictRequest()); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends an empty OpenID Connect request to the given endpoint using GET
|
||||
|
/// and converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public Task<OpenIddictResponse> GetAsync(Uri uri) |
||||
|
=> GetAsync(uri, new OpenIddictRequest()); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends a generic OpenID Connect request to the given endpoint using GET
|
||||
|
/// and converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <param name="request">The OpenID Connect request to send.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public Task<OpenIddictResponse> GetAsync(string uri, OpenIddictRequest request) |
||||
|
{ |
||||
|
if (request == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(request)); |
||||
|
} |
||||
|
|
||||
|
if (string.IsNullOrEmpty(uri)) |
||||
|
{ |
||||
|
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri)); |
||||
|
} |
||||
|
|
||||
|
return GetAsync(new Uri(uri, UriKind.RelativeOrAbsolute), request); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends a generic OpenID Connect request to the given endpoint using GET
|
||||
|
/// and converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <param name="request">The OpenID Connect request to send.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public Task<OpenIddictResponse> GetAsync(Uri uri, OpenIddictRequest request) |
||||
|
=> SendAsync(HttpMethod.Get, uri, request); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends a generic OpenID Connect request to the given endpoint using POST
|
||||
|
/// and converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <param name="request">The OpenID Connect request to send.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public Task<OpenIddictResponse> PostAsync(string uri, OpenIddictRequest request) |
||||
|
{ |
||||
|
if (request == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(request)); |
||||
|
} |
||||
|
|
||||
|
if (string.IsNullOrEmpty(uri)) |
||||
|
{ |
||||
|
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri)); |
||||
|
} |
||||
|
|
||||
|
return PostAsync(new Uri(uri, UriKind.RelativeOrAbsolute), request); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends a generic OpenID Connect request to the given endpoint using POST
|
||||
|
/// and converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <param name="request">The OpenID Connect request to send.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public Task<OpenIddictResponse> PostAsync(Uri uri, OpenIddictRequest request) |
||||
|
=> SendAsync(HttpMethod.Post, uri, request); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends a generic OpenID Connect request to the given endpoint and
|
||||
|
/// converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="method">The HTTP method used to send the OpenID Connect request.</param>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <param name="request">The OpenID Connect request to send.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public Task<OpenIddictResponse> SendAsync(string method, string uri, OpenIddictRequest request) |
||||
|
{ |
||||
|
if (request == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(request)); |
||||
|
} |
||||
|
|
||||
|
if (string.IsNullOrEmpty(method)) |
||||
|
{ |
||||
|
throw new ArgumentException("The HTTP method cannot be null or empty.", nameof(method)); |
||||
|
} |
||||
|
|
||||
|
if (string.IsNullOrEmpty(uri)) |
||||
|
{ |
||||
|
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri)); |
||||
|
} |
||||
|
|
||||
|
return SendAsync(new HttpMethod(method), uri, request); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends a generic OpenID Connect request to the given endpoint and
|
||||
|
/// converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="method">The HTTP method used to send the OpenID Connect request.</param>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <param name="request">The OpenID Connect request to send.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public Task<OpenIddictResponse> SendAsync(HttpMethod method, string uri, OpenIddictRequest request) |
||||
|
{ |
||||
|
if (method == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(method)); |
||||
|
} |
||||
|
|
||||
|
if (request == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(request)); |
||||
|
} |
||||
|
|
||||
|
if (string.IsNullOrEmpty(uri)) |
||||
|
{ |
||||
|
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri)); |
||||
|
} |
||||
|
|
||||
|
return SendAsync(method, new Uri(uri, UriKind.RelativeOrAbsolute), request); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sends a generic OpenID Connect request to the given endpoint and
|
||||
|
/// converts the returned response to an OpenID Connect response.
|
||||
|
/// </summary>
|
||||
|
/// <param name="method">The HTTP method used to send the OpenID Connect request.</param>
|
||||
|
/// <param name="uri">The endpoint to which the request is sent.</param>
|
||||
|
/// <param name="request">The OpenID Connect request to send.</param>
|
||||
|
/// <returns>The OpenID Connect response returned by the server.</returns>
|
||||
|
public virtual async Task<OpenIddictResponse> SendAsync(HttpMethod method, Uri uri, OpenIddictRequest request) |
||||
|
{ |
||||
|
if (method == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(method)); |
||||
|
} |
||||
|
|
||||
|
if (uri == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(uri)); |
||||
|
} |
||||
|
|
||||
|
if (request == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(nameof(request)); |
||||
|
} |
||||
|
|
||||
|
if (HttpClient.BaseAddress == null && !uri.IsAbsoluteUri) |
||||
|
{ |
||||
|
throw new ArgumentException("The address cannot be a relative URI when no base address " + |
||||
|
"is associated with the HTTP client.", nameof(uri)); |
||||
|
} |
||||
|
|
||||
|
return await GetResponseAsync(await HttpClient.SendAsync(CreateRequestMessage(request, method, uri))); |
||||
|
} |
||||
|
|
||||
|
private HttpRequestMessage CreateRequestMessage(OpenIddictRequest request, HttpMethod method, Uri uri) |
||||
|
{ |
||||
|
// Note: a dictionary is deliberately not used here to allow multiple parameters with the
|
||||
|
// same name to be specified. While initially not allowed by the core OAuth2 specification,
|
||||
|
// this is required for derived drafts like the OAuth2 token exchange specification.
|
||||
|
var parameters = new List<KeyValuePair<string, string>>(); |
||||
|
|
||||
|
foreach (var parameter in request.GetParameters()) |
||||
|
{ |
||||
|
// If the parameter is null or empty, send an empty value.
|
||||
|
if (OpenIddictParameter.IsNullOrEmpty(parameter.Value)) |
||||
|
{ |
||||
|
parameters.Add(new KeyValuePair<string, string>(parameter.Key, string.Empty)); |
||||
|
|
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var values = (string[]) parameter.Value; |
||||
|
if (values == null || values.Length == 0) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
foreach (var value in values) |
||||
|
{ |
||||
|
parameters.Add(new KeyValuePair<string, string>(parameter.Key, value)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (method == HttpMethod.Get && parameters.Count != 0) |
||||
|
{ |
||||
|
var builder = new StringBuilder(); |
||||
|
|
||||
|
foreach (var parameter in parameters) |
||||
|
{ |
||||
|
if (builder.Length != 0) |
||||
|
{ |
||||
|
builder.Append('&'); |
||||
|
} |
||||
|
|
||||
|
builder.Append(UrlEncoder.Default.Encode(parameter.Key)); |
||||
|
builder.Append('='); |
||||
|
builder.Append(UrlEncoder.Default.Encode(parameter.Value)); |
||||
|
} |
||||
|
|
||||
|
if (!uri.IsAbsoluteUri) |
||||
|
{ |
||||
|
uri = new Uri(HttpClient.BaseAddress, uri); |
||||
|
} |
||||
|
|
||||
|
uri = new UriBuilder(uri) { Query = builder.ToString() }.Uri; |
||||
|
} |
||||
|
|
||||
|
var message = new HttpRequestMessage(method, uri); |
||||
|
|
||||
|
if (method != HttpMethod.Get) |
||||
|
{ |
||||
|
message.Content = new FormUrlEncodedContent(parameters); |
||||
|
} |
||||
|
|
||||
|
return message; |
||||
|
} |
||||
|
|
||||
|
private async Task<OpenIddictResponse> GetResponseAsync(HttpResponseMessage message) |
||||
|
{ |
||||
|
if (message.Headers.Location != null) |
||||
|
{ |
||||
|
var payload = message.Headers.Location.Fragment; |
||||
|
if (string.IsNullOrEmpty(payload)) |
||||
|
{ |
||||
|
payload = message.Headers.Location.Query; |
||||
|
} |
||||
|
|
||||
|
if (string.IsNullOrEmpty(payload)) |
||||
|
{ |
||||
|
return new OpenIddictResponse(); |
||||
|
} |
||||
|
|
||||
|
string UnescapeDataString(string value) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(value)) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return Uri.UnescapeDataString(value.Replace("+", "%20")); |
||||
|
} |
||||
|
|
||||
|
// Note: a dictionary is deliberately not used here to allow multiple parameters with the
|
||||
|
// same name to be retrieved. While initially not allowed by the core OAuth2 specification,
|
||||
|
// this is required for derived drafts like the OAuth2 token exchange specification.
|
||||
|
var parameters = new List<KeyValuePair<string, string>>(); |
||||
|
|
||||
|
foreach (var element in new StringTokenizer(payload, OpenIddictConstants.Separators.Ampersand)) |
||||
|
{ |
||||
|
var segment = element; |
||||
|
if (segment.Length == 0) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
// Always skip the first char (# or ?).
|
||||
|
if (segment.Offset == 0) |
||||
|
{ |
||||
|
segment = segment.Subsegment(1, segment.Length - 1); |
||||
|
} |
||||
|
|
||||
|
var index = segment.IndexOf('='); |
||||
|
if (index == -1) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var name = UnescapeDataString(segment.Substring(0, index)); |
||||
|
if (string.IsNullOrEmpty(name)) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var value = UnescapeDataString(segment.Substring(index + 1, segment.Length - (index + 1))); |
||||
|
|
||||
|
parameters.Add(new KeyValuePair<string, string>(name, value)); |
||||
|
} |
||||
|
|
||||
|
return new OpenIddictResponse( |
||||
|
from parameter in parameters |
||||
|
group parameter by parameter.Key into grouping |
||||
|
let values = grouping.Select(parameter => parameter.Value) |
||||
|
select new KeyValuePair<string, StringValues>(grouping.Key, values.ToArray())); |
||||
|
} |
||||
|
|
||||
|
else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "application/json", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
using var stream = await message.Content.ReadAsStreamAsync(); |
||||
|
|
||||
|
return await JsonSerializer.DeserializeAsync<OpenIddictResponse>(stream); |
||||
|
} |
||||
|
|
||||
|
else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/html", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
using var stream = await message.Content.ReadAsStreamAsync(); |
||||
|
using var document = await HtmlParser.ParseDocumentAsync(stream); |
||||
|
|
||||
|
// Note: a dictionary is deliberately not used here to allow multiple parameters with the
|
||||
|
// same name to be retrieved. While initially not allowed by the core OAuth2 specification,
|
||||
|
// this is required for derived drafts like the OAuth2 token exchange specification.
|
||||
|
var parameters = new List<KeyValuePair<string, string>>(); |
||||
|
|
||||
|
foreach (var element in document.Body.GetElementsByTagName("input")) |
||||
|
{ |
||||
|
var name = element.GetAttribute("name"); |
||||
|
if (string.IsNullOrEmpty(name)) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var value = element.GetAttribute("value"); |
||||
|
|
||||
|
parameters.Add(new KeyValuePair<string, string>(name, value)); |
||||
|
} |
||||
|
|
||||
|
return new OpenIddictResponse( |
||||
|
from parameter in parameters |
||||
|
group parameter by parameter.Key into grouping |
||||
|
let values = grouping.Select(parameter => parameter.Value) |
||||
|
select new KeyValuePair<string, StringValues>(grouping.Key, values.ToArray())); |
||||
|
} |
||||
|
|
||||
|
else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/plain", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
using (var stream = await message.Content.ReadAsStreamAsync()) |
||||
|
using (var reader = new StreamReader(stream)) |
||||
|
{ |
||||
|
// Note: a dictionary is deliberately not used here to allow multiple parameters with the
|
||||
|
// same name to be retrieved. While initially not allowed by the core OAuth2 specification,
|
||||
|
// this is required for derived drafts like the OAuth2 token exchange specification.
|
||||
|
var parameters = new List<KeyValuePair<string, string>>(); |
||||
|
|
||||
|
for (var line = await reader.ReadLineAsync(); line != null; line = await reader.ReadLineAsync()) |
||||
|
{ |
||||
|
var index = line.IndexOf(':'); |
||||
|
if (index == -1) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var name = line.Substring(0, index); |
||||
|
if (string.IsNullOrEmpty(name)) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var value = line.Substring(index + 1); |
||||
|
|
||||
|
parameters.Add(new KeyValuePair<string, string>(name, value)); |
||||
|
} |
||||
|
|
||||
|
return new OpenIddictResponse( |
||||
|
from parameter in parameters |
||||
|
group parameter by parameter.Key into grouping |
||||
|
let values = grouping.Select(parameter => parameter.Value) |
||||
|
select new KeyValuePair<string, StringValues>(grouping.Key, values.ToArray())); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return new OpenIddictResponse(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,170 @@ |
|||||
|
/* |
||||
|
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
* See https://github.com/openiddict/openiddict-core for more information concerning
|
||||
|
* the license and the contributors participating to this project. |
||||
|
*/ |
||||
|
|
||||
|
using System; |
||||
|
using System.Security.Claims; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Moq; |
||||
|
using OpenIddict.Abstractions; |
||||
|
using OpenIddict.Core; |
||||
|
using static OpenIddict.Abstractions.OpenIddictConstants; |
||||
|
using static OpenIddict.Server.OpenIddictServerEvents; |
||||
|
|
||||
|
namespace OpenIddict.Server.FunctionalTests |
||||
|
{ |
||||
|
public abstract partial class OpenIddictServerIntegrationTests |
||||
|
{ |
||||
|
protected virtual void ConfigureServices(IServiceCollection services) |
||||
|
{ |
||||
|
services.AddOpenIddict() |
||||
|
.AddCore(options => |
||||
|
{ |
||||
|
options.SetDefaultApplicationEntity<OpenIddictApplication>() |
||||
|
.SetDefaultAuthorizationEntity<OpenIddictAuthorization>() |
||||
|
.SetDefaultScopeEntity<OpenIddictScope>() |
||||
|
.SetDefaultTokenEntity<OpenIddictToken>(); |
||||
|
|
||||
|
options.Services.AddSingleton(CreateApplicationManager()) |
||||
|
.AddSingleton(CreateAuthorizationManager()) |
||||
|
.AddSingleton(CreateScopeManager()) |
||||
|
.AddSingleton(CreateTokenManager()); |
||||
|
}) |
||||
|
|
||||
|
.AddServer(options => |
||||
|
{ |
||||
|
// Enable the tested endpoints.
|
||||
|
options.SetAuthorizationEndpointUris("/connect/authorize") |
||||
|
.SetConfigurationEndpointUris("/.well-known/openid-configuration") |
||||
|
.SetCryptographyEndpointUris("/.well-known/jwks") |
||||
|
.SetIntrospectionEndpointUris("/connect/introspect") |
||||
|
.SetLogoutEndpointUris("/connect/logout") |
||||
|
.SetRevocationEndpointUris("/connect/revoke") |
||||
|
.SetTokenEndpointUris("/connect/token") |
||||
|
.SetUserinfoEndpointUris("/connect/userinfo"); |
||||
|
|
||||
|
options.AllowAuthorizationCodeFlow() |
||||
|
.AllowClientCredentialsFlow() |
||||
|
.AllowImplicitFlow() |
||||
|
.AllowPasswordFlow() |
||||
|
.AllowRefreshTokenFlow(); |
||||
|
|
||||
|
// Accept anonymous clients by default.
|
||||
|
options.AcceptAnonymousClients(); |
||||
|
|
||||
|
// Disable permission enforcement by default.
|
||||
|
options.IgnoreEndpointPermissions() |
||||
|
.IgnoreGrantTypePermissions() |
||||
|
.IgnoreScopePermissions(); |
||||
|
|
||||
|
options.AddSigningCertificate( |
||||
|
assembly: typeof(OpenIddictServerIntegrationTests).Assembly, |
||||
|
resource: "OpenIddict.Server.IntegrationTests.Certificate.pfx", |
||||
|
password: "Owin.Security.OpenIdConnect.Server"); |
||||
|
|
||||
|
options.AddEncryptionCertificate( |
||||
|
assembly: typeof(OpenIddictServerIntegrationTests).Assembly, |
||||
|
resource: "OpenIddict.Server.IntegrationTests.Certificate.pfx", |
||||
|
password: "Owin.Security.OpenIdConnect.Server"); |
||||
|
|
||||
|
options.AddEventHandler<ValidateAuthorizationRequestContext>(builder => |
||||
|
builder.UseInlineHandler(context => default)); |
||||
|
|
||||
|
options.AddEventHandler<ValidateIntrospectionRequestContext>(builder => |
||||
|
builder.UseInlineHandler(context => default)); |
||||
|
|
||||
|
options.AddEventHandler<ValidateLogoutRequestContext>(builder => |
||||
|
builder.UseInlineHandler(context => default)); |
||||
|
|
||||
|
options.AddEventHandler<ValidateRevocationRequestContext>(builder => |
||||
|
builder.UseInlineHandler(context => default)); |
||||
|
|
||||
|
options.AddEventHandler<ValidateTokenRequestContext>(builder => |
||||
|
builder.UseInlineHandler(context => default)); |
||||
|
|
||||
|
options.AddEventHandler<HandleAuthorizationRequestContext>(builder => |
||||
|
{ |
||||
|
builder.UseInlineHandler(context => |
||||
|
{ |
||||
|
var identity = new ClaimsIdentity("Bearer"); |
||||
|
identity.AddClaim(Claims.Subject, "Bob le Magnifique"); |
||||
|
|
||||
|
context.Principal = new ClaimsPrincipal(identity); |
||||
|
context.HandleAuthentication(); |
||||
|
|
||||
|
return default; |
||||
|
}); |
||||
|
|
||||
|
builder.SetOrder(int.MaxValue); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
protected abstract OpenIddictServerIntegrationTestClient CreateClient(Action<OpenIddictServerBuilder> configuration = null); |
||||
|
|
||||
|
protected OpenIddictApplicationManager<OpenIddictApplication> CreateApplicationManager( |
||||
|
Action<Mock<OpenIddictApplicationManager<OpenIddictApplication>>> configuration = null) |
||||
|
{ |
||||
|
var manager = new Mock<OpenIddictApplicationManager<OpenIddictApplication>>( |
||||
|
Mock.Of<IOpenIddictApplicationCache<OpenIddictApplication>>(), |
||||
|
Mock.Of<IOpenIddictApplicationStoreResolver>(), |
||||
|
Mock.Of<ILogger<OpenIddictApplicationManager<OpenIddictApplication>>>(), |
||||
|
Mock.Of<IOptionsMonitor<OpenIddictCoreOptions>>()); |
||||
|
|
||||
|
configuration?.Invoke(manager); |
||||
|
|
||||
|
return manager.Object; |
||||
|
} |
||||
|
|
||||
|
protected OpenIddictAuthorizationManager<OpenIddictAuthorization> CreateAuthorizationManager( |
||||
|
Action<Mock<OpenIddictAuthorizationManager<OpenIddictAuthorization>>> configuration = null) |
||||
|
{ |
||||
|
var manager = new Mock<OpenIddictAuthorizationManager<OpenIddictAuthorization>>( |
||||
|
Mock.Of<IOpenIddictAuthorizationCache<OpenIddictAuthorization>>(), |
||||
|
Mock.Of<IOpenIddictAuthorizationStoreResolver>(), |
||||
|
Mock.Of<ILogger<OpenIddictAuthorizationManager<OpenIddictAuthorization>>>(), |
||||
|
Mock.Of<IOptionsMonitor<OpenIddictCoreOptions>>()); |
||||
|
|
||||
|
configuration?.Invoke(manager); |
||||
|
|
||||
|
return manager.Object; |
||||
|
} |
||||
|
|
||||
|
protected OpenIddictScopeManager<OpenIddictScope> CreateScopeManager( |
||||
|
Action<Mock<OpenIddictScopeManager<OpenIddictScope>>> configuration = null) |
||||
|
{ |
||||
|
var manager = new Mock<OpenIddictScopeManager<OpenIddictScope>>( |
||||
|
Mock.Of<IOpenIddictScopeCache<OpenIddictScope>>(), |
||||
|
Mock.Of<IOpenIddictScopeStoreResolver>(), |
||||
|
Mock.Of<ILogger<OpenIddictScopeManager<OpenIddictScope>>>(), |
||||
|
Mock.Of<IOptionsMonitor<OpenIddictCoreOptions>>()); |
||||
|
|
||||
|
configuration?.Invoke(manager); |
||||
|
|
||||
|
return manager.Object; |
||||
|
} |
||||
|
|
||||
|
protected OpenIddictTokenManager<OpenIddictToken> CreateTokenManager( |
||||
|
Action<Mock<OpenIddictTokenManager<OpenIddictToken>>> configuration = null) |
||||
|
{ |
||||
|
var manager = new Mock<OpenIddictTokenManager<OpenIddictToken>>( |
||||
|
Mock.Of<IOpenIddictTokenCache<OpenIddictToken>>(), |
||||
|
Mock.Of<IOpenIddictTokenStoreResolver>(), |
||||
|
Mock.Of<ILogger<OpenIddictTokenManager<OpenIddictToken>>>(), |
||||
|
Mock.Of<IOptionsMonitor<OpenIddictCoreOptions>>()); |
||||
|
|
||||
|
configuration?.Invoke(manager); |
||||
|
|
||||
|
return manager.Object; |
||||
|
} |
||||
|
|
||||
|
public class OpenIddictApplication { } |
||||
|
public class OpenIddictAuthorization { } |
||||
|
public class OpenIddictScope { } |
||||
|
public class OpenIddictToken { } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net472</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\OpenIddict.Server.Owin\OpenIddict.Server.Owin.csproj" /> |
||||
|
<ProjectReference Include="..\OpenIddict.Server.IntegrationTests\OpenIddict.Server.IntegrationTests.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.Owin.Testing" Version="$(OwinVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' "> |
||||
|
<Reference Include="System.Net.Http" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,58 @@ |
|||||
|
/* |
||||
|
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
* See https://github.com/openiddict/openiddict-core for more information concerning
|
||||
|
* the license and the contributors participating to this project. |
||||
|
*/ |
||||
|
|
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using OpenIddict.Abstractions; |
||||
|
using OpenIddict.Server.FunctionalTests; |
||||
|
using Xunit; |
||||
|
using static OpenIddict.Abstractions.OpenIddictConstants; |
||||
|
|
||||
|
namespace OpenIddict.Server.Owin.FunctionalTests |
||||
|
{ |
||||
|
public partial class OpenIddictServerOwinIntegrationTests : OpenIddictServerIntegrationTests |
||||
|
{ |
||||
|
[Fact(Skip = "The handler responsible of rejecting such requests has not been ported yet.")] |
||||
|
public async Task ExtractAuthorizationRequest_RequestIdParameterIsRejectedWhenRequestCachingIsDisabled() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var client = CreateClient(options => options.EnableDegradedMode()); |
||||
|
|
||||
|
// Act
|
||||
|
var response = await client.PostAsync("/connect/authorize", new OpenIddictRequest |
||||
|
{ |
||||
|
RequestId = "EFAF3596-F868-497F-96BB-AA2AD1F8B7E7" |
||||
|
}); |
||||
|
|
||||
|
// Assert
|
||||
|
Assert.Equal(Errors.InvalidRequest, response.Error); |
||||
|
Assert.Equal("The 'request_id' parameter is not supported.", response.ErrorDescription); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task ExtractAuthorizationRequest_InvalidRequestIdParameterIsRejected() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var client = CreateClient(options => |
||||
|
{ |
||||
|
options.Services.AddDistributedMemoryCache(); |
||||
|
|
||||
|
options.UseOwin() |
||||
|
.EnableAuthorizationEndpointCaching(); |
||||
|
}); |
||||
|
|
||||
|
// Act
|
||||
|
var response = await client.PostAsync("/connect/authorize", new OpenIddictRequest |
||||
|
{ |
||||
|
RequestId = "EFAF3596-F868-497F-96BB-AA2AD1F8B7E7" |
||||
|
}); |
||||
|
|
||||
|
// Assert
|
||||
|
Assert.Equal(Errors.InvalidRequest, response.Error); |
||||
|
Assert.Equal("The specified 'request_id' parameter is invalid.", response.ErrorDescription); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,118 @@ |
|||||
|
/* |
||||
|
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
* See https://github.com/openiddict/openiddict-core for more information concerning
|
||||
|
* the license and the contributors participating to this project. |
||||
|
*/ |
||||
|
|
||||
|
using System; |
||||
|
using System.Security.Claims; |
||||
|
using System.Text.Json; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Owin; |
||||
|
using Microsoft.Owin.Testing; |
||||
|
using OpenIddict.Abstractions; |
||||
|
using OpenIddict.Server.FunctionalTests; |
||||
|
using Owin; |
||||
|
using static OpenIddict.Abstractions.OpenIddictConstants; |
||||
|
|
||||
|
namespace OpenIddict.Server.Owin.FunctionalTests |
||||
|
{ |
||||
|
public partial class OpenIddictServerOwinIntegrationTests : OpenIddictServerIntegrationTests |
||||
|
{ |
||||
|
protected override OpenIddictServerIntegrationTestClient CreateClient(Action<OpenIddictServerBuilder> configuration = null) |
||||
|
{ |
||||
|
var services = new ServiceCollection(); |
||||
|
ConfigureServices(services); |
||||
|
|
||||
|
services.AddOpenIddict() |
||||
|
.AddServer(options => |
||||
|
{ |
||||
|
// Disable the transport security requirement during testing.
|
||||
|
options.UseOwin() |
||||
|
.DisableTransportSecurityRequirement(); |
||||
|
|
||||
|
configuration?.Invoke(options); |
||||
|
}); |
||||
|
|
||||
|
var provider = services.BuildServiceProvider(); |
||||
|
|
||||
|
var server = TestServer.Create(app => |
||||
|
{ |
||||
|
app.Use(async (context, next) => |
||||
|
{ |
||||
|
using var scope = provider.CreateScope(); |
||||
|
|
||||
|
context.Set(typeof(IServiceProvider).FullName, scope.ServiceProvider); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
await next(); |
||||
|
} |
||||
|
|
||||
|
finally |
||||
|
{ |
||||
|
context.Environment.Remove(typeof(IServiceProvider).FullName); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
app.Use(async (context, next) => |
||||
|
{ |
||||
|
await next(); |
||||
|
|
||||
|
var transaction = context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName); |
||||
|
var response = transaction?.GetProperty<object>("custom_response"); |
||||
|
if (response != null) |
||||
|
{ |
||||
|
context.Response.ContentType = "application/json"; |
||||
|
await context.Response.WriteAsync(JsonSerializer.Serialize(response)); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
app.UseOpenIddictServer(); |
||||
|
|
||||
|
app.Use((context, next) => |
||||
|
{ |
||||
|
if (context.Request.Path == new PathString("/invalid-signin")) |
||||
|
{ |
||||
|
var identity = new ClaimsIdentity(OpenIddictServerOwinDefaults.AuthenticationType); |
||||
|
identity.AddClaim(Claims.Subject, "Bob le Bricoleur"); |
||||
|
|
||||
|
context.Authentication.SignIn(identity); |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
else if (context.Request.Path == new PathString("/invalid-signout")) |
||||
|
{ |
||||
|
context.Authentication.SignOut(OpenIddictServerOwinDefaults.AuthenticationType); |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
else if (context.Request.Path == new PathString("/invalid-challenge")) |
||||
|
{ |
||||
|
context.Authentication.Challenge(OpenIddictServerOwinDefaults.AuthenticationType); |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
else if (context.Request.Path == new PathString("/invalid-authenticate")) |
||||
|
{ |
||||
|
return context.Authentication.AuthenticateAsync(OpenIddictServerOwinDefaults.AuthenticationType); |
||||
|
} |
||||
|
|
||||
|
return next(); |
||||
|
}); |
||||
|
|
||||
|
app.Run(context => |
||||
|
{ |
||||
|
context.Response.ContentType = "application/json"; |
||||
|
return context.Response.WriteAsync(JsonSerializer.Serialize(new |
||||
|
{ |
||||
|
name = "Bob le Magnifique" |
||||
|
})); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
return new OpenIddictServerIntegrationTestClient(server.HttpClient); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue