private static TestServer CreateResourceServer(Action<OAuthValidationOptions> configuration = null) {
var builder = new WebHostBuilder();
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(MockBehavior.Strict);
format.Setup(mock => mock.Unprotect(It.Is<string>(token => token == "invalid-token")))
.Returns(value: null);
format.Setup(mock => mock.Unprotect(It.Is<string>(token => token == "valid-token")))
.Returns(delegate {
var identity = new ClaimsIdentity(OAuthValidationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Fabrikam"));
var properties = new AuthenticationProperties();
return new AuthenticationTicket(new ClaimsPrincipal(identity),
properties, OAuthValidationDefaults.AuthenticationScheme);
});
format.Setup(mock => mock.Unprotect(It.Is<string>(token => token == "valid-token-with-scopes")))
.Returns(delegate {
var identity = new ClaimsIdentity(OAuthValidationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Fabrikam"));
var properties = new AuthenticationProperties();
properties.Items[OAuthValidationConstants.Properties.Scopes] =
"C54A8F5E-0387-43F4-BA43-FD4B50DC190D 5C57E3BD-9EFB-4224-9AB8-C8C5E009FFD7";
return new AuthenticationTicket(new ClaimsPrincipal(identity),
properties, OAuthValidationDefaults.AuthenticationScheme);
});
format.Setup(mock => mock.Unprotect(It.Is<string>(token => token == "valid-token-with-single-audience")))
.Returns(delegate {
var identity = new ClaimsIdentity(OAuthValidationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Fabrikam"));
var properties = new AuthenticationProperties(new Dictionary<string, string> {
[OAuthValidationConstants.Properties.Audiences] = "http://www.google.com/"
});
return new AuthenticationTicket(new ClaimsPrincipal(identity),
properties, OAuthValidationDefaults.AuthenticationScheme);
});
format.Setup(mock => mock.Unprotect(It.Is<string>(token => token == "valid-token-with-multiple-audiences")))
.Returns(delegate {
var identity = new ClaimsIdentity(OAuthValidationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Fabrikam"));
var properties = new AuthenticationProperties(new Dictionary<string, string> {
[OAuthValidationConstants.Properties.Audiences] = "http://www.google.com/ http://www.fabrikam.com/"
});
return new AuthenticationTicket(new ClaimsPrincipal(identity),
properties, OAuthValidationDefaults.AuthenticationScheme);
});
format.Setup(mock => mock.Unprotect(It.Is<string>(token => token == "expired-token")))
.Returns(delegate {
var identity = new ClaimsIdentity(OAuthValidationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Fabrikam"));
var properties = new AuthenticationProperties();
properties.ExpiresUtc = DateTimeOffset.UtcNow - TimeSpan.FromDays(1);
return new AuthenticationTicket(new ClaimsPrincipal(identity),
properties, OAuthValidationDefaults.AuthenticationScheme);
});
builder.UseEnvironment("Testing");
builder.ConfigureLogging(options => options.AddDebug());
builder.ConfigureServices(services => {
services.AddAuthentication();
});
builder.Configure(app => {
app.UseOAuthValidation(options => {
options.AutomaticAuthenticate = true;
options.AutomaticChallenge = true;
options.AccessTokenFormat = format.Object;
// Run the configuration delegate
// registered by the unit tests.
configuration?.Invoke(options);
});
app.Map("/ticket", map => map.Run(async context => {
var ticket = new AuthenticateContext(OAuthValidationDefaults.AuthenticationScheme);
await context.Authentication.AuthenticateAsync(ticket);
if (!ticket.Accepted || ticket.Principal == null || ticket.Properties == null) {
await context.Authentication.ChallengeAsync();
return;
}
context.Response.ContentType = "application/json";
// Return the authentication ticket as a JSON object.
await context.Response.WriteAsync(JsonConvert.SerializeObject(new {
Claims = from claim in ticket.Principal.Claims
select new { claim.Type, claim.Value },
Properties = from property in ticket.Properties
select new { Name = property.Key, property.Value }
}));
}));
app.Run(context => {
if (!context.User.Identities.Any(identity => identity.IsAuthenticated)) {
return context.Authentication.ChallengeAsync();
}
var identifier = context.User.FindFirst(ClaimTypes.NameIdentifier).Value;
return context.Response.WriteAsync(identifier);
});
});
return new TestServer(builder);
}
}