Versatile OpenID Connect stack for ASP.NET Core and Microsoft.Owin (compatible with ASP.NET 4.6.1)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

228 lines
8.3 KiB

/*
* 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.Collections.Immutable;
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 Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenIddict.Validation.IntegrationTests;
using Xunit;
using Xunit.Abstractions;
using static OpenIddict.Validation.OpenIddictValidationEvents;
using static OpenIddict.Validation.OpenIddictValidationHandlers.Protection;
namespace OpenIddict.Validation.AspNetCore.IntegrationTests;
public partial class OpenIddictValidationAspNetCoreIntegrationTests : OpenIddictValidationIntegrationTests
{
public OpenIddictValidationAspNetCoreIntegrationTests(ITestOutputHelper outputHelper)
: base(outputHelper)
{
}
[Fact]
public async Task ProcessAuthentication_CreationDateIsMappedToIssuedUtc()
{
// Arrange
await using var server = await CreateServerAsync(options =>
{
options.AddEventHandler<ValidateTokenContext>(builder =>
{
builder.UseInlineHandler(context =>
{
Assert.Equal("access_token", context.Token);
Assert.Equal([TokenTypeIdentifiers.AccessToken], context.ValidTokenTypes);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetTokenType(TokenTypeIdentifiers.AccessToken)
.SetClaim(Claims.Subject, "Bob le Magnifique")
.SetCreationDate(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero));
return default;
});
builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500);
});
});
await using var client = await server.CreateClientAsync();
// Act
var response = await client.GetAsync("/authenticate/properties", new OpenIddictRequest
{
AccessToken = "access_token"
});
// Assert
var properties = new AuthenticationProperties(response.GetParameters()
.ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value));
Assert.Equal(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.IssuedUtc);
}
[Fact]
public async Task ProcessAuthentication_ExpirationDateIsMappedToIssuedUtc()
{
// Arrange
await using var server = await CreateServerAsync(options =>
{
options.AddEventHandler<ValidateTokenContext>(builder =>
{
builder.UseInlineHandler(context =>
{
Assert.Equal("access_token", context.Token);
Assert.Equal([TokenTypeIdentifiers.AccessToken], context.ValidTokenTypes);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetTokenType(TokenTypeIdentifiers.AccessToken)
.SetExpirationDate(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero));
return default;
});
builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500);
});
});
await using var client = await server.CreateClientAsync();
// Act
var response = await client.GetAsync("/authenticate/properties", new OpenIddictRequest
{
AccessToken = "access_token"
});
// Assert
var properties = new AuthenticationProperties(response.GetParameters()
.ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value));
Assert.Equal(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.ExpiresUtc);
}
protected override
#if SUPPORTS_WEB_INTEGRATION_IN_GENERIC_HOST
async
#endif
ValueTask<OpenIddictValidationIntegrationTestServer> CreateServerAsync(Action<OpenIddictValidationBuilder>? configuration = null)
{
#if SUPPORTS_WEB_INTEGRATION_IN_GENERIC_HOST
var builder = new HostBuilder();
#else
var builder = new WebHostBuilder();
#endif
builder.UseEnvironment("Testing");
builder.ConfigureLogging(options => options.AddXUnit(OutputHelper));
builder.ConfigureServices(ConfigureServices);
builder.ConfigureServices(services =>
{
services.AddOpenIddict()
.AddValidation(options =>
{
options.UseAspNetCore();
configuration?.Invoke(options);
});
});
#if SUPPORTS_WEB_INTEGRATION_IN_GENERIC_HOST
builder.ConfigureWebHost(options =>
{
options.UseTestServer();
options.Configure(ConfigurePipeline);
});
#else
builder.Configure(ConfigurePipeline);
#endif
#if SUPPORTS_WEB_INTEGRATION_IN_GENERIC_HOST
var host = await builder.StartAsync();
return new OpenIddictValidationAspNetCoreIntegrationTestServer(host);
#else
var server = new TestServer(builder);
return new(new OpenIddictValidationAspNetCoreIntegrationTestServer(server));
#endif
void ConfigurePipeline(IApplicationBuilder app)
{
app.Use(next => async context =>
{
await next(context);
var feature = context.Features.Get<OpenIddictValidationAspNetCoreFeature>();
var response = feature?.Transaction?.GetProperty<object>("custom_response");
if (response is not null)
{
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonSerializer.Serialize(response));
}
});
app.UseAuthentication();
app.Use(next => async context =>
{
if (context.Request.Path == "/authenticate")
{
var result = await context.AuthenticateAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
if (result?.Principal is null)
{
await context.ChallengeAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
return;
}
var claims = result.Principal.Claims.GroupBy(claim => claim.Type)
.Select(group => new KeyValuePair<string, ImmutableArray<string?>?>(
group.Key, group.Select(claim => claim.Value).ToImmutableArray<string?>()));
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(claims)));
return;
}
else if (context.Request.Path == "/authenticate/properties")
{
var result = await context.AuthenticateAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
if (result?.Properties is null)
{
return;
}
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(result.Properties.Items)));
return;
}
else if (context.Request.Path == "/challenge")
{
await context.ChallengeAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
return;
}
await next(context);
});
app.Run(context =>
{
context.Response.ContentType = "application/json";
return context.Response.WriteAsync(JsonSerializer.Serialize(new
{
name = "Bob le Magnifique"
}));
});
}
}
}