// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Authentication.OpenIdConnect;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.WebEncoders;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Xunit;
namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
{
///
/// These tests are designed to test OpenIdConnectAuthenticationHandler.
///
public class OpenIdConnectHandlerTests
{
private const string nonceForOpenIdConnect = "abc";
private static SecurityToken specCompliantOpenIdConnect = new JwtSecurityToken("issuer", "audience", new List { new Claim("iat", EpochTime.GetIntDate(DateTime.UtcNow).ToString()), new Claim("nonce", nonceForOpenIdConnect) }, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromDays(1));
private const string ExpectedStateParameter = "expectedState";
[Theory, MemberData(nameof(AuthenticateCoreStateDataSet))]
public async Task AuthenticateCoreState(Action action, OpenIdConnectMessage message)
{
var handler = new OpenIdConnectHandlerForTestingAuthenticate();
var server = CreateServer(action, UrlEncoder.Default, handler);
await server.CreateClient().PostAsync("http://localhost", new FormUrlEncodedContent(message.Parameters.Where(pair => pair.Value != null)));
}
public static TheoryData, OpenIdConnectMessage> AuthenticateCoreStateDataSet
{
get
{
var formater = new AuthenticationPropertiesFormaterKeyValue();
var properties = new AuthenticationProperties();
var dataset = new TheoryData, OpenIdConnectMessage>();
// expected user state is added to the message.Parameters.Items[ExpectedStateParameter]
// Userstate == null
var message = new OpenIdConnectMessage();
message.State = UrlEncoder.Default.UrlEncode(formater.Protect(properties));
message.Code = Guid.NewGuid().ToString();
message.Parameters.Add(ExpectedStateParameter, null);
dataset.Add(SetStateOptions, message);
// Userstate != null
message = new OpenIdConnectMessage();
properties.Items.Clear();
var userstate = Guid.NewGuid().ToString();
message.Code = Guid.NewGuid().ToString();
properties.Items.Add(OpenIdConnectDefaults.UserstatePropertiesKey, userstate);
message.State = UrlEncoder.Default.UrlEncode(formater.Protect(properties));
message.Parameters.Add(ExpectedStateParameter, userstate);
dataset.Add(SetStateOptions, message);
return dataset;
}
}
// Setup an event to check for expected state.
// The state gets set by the runtime after the 'MessageReceivedContext'
private static void SetStateOptions(OpenIdConnectOptions options)
{
options.AuthenticationScheme = "OpenIdConnectHandlerTest";
options.ConfigurationManager = TestUtilities.DefaultOpenIdConnectConfigurationManager;
options.ClientId = Guid.NewGuid().ToString();
options.StateDataFormat = new AuthenticationPropertiesFormaterKeyValue();
options.SignInScheme = "Cookies";
options.Events = new OpenIdConnectEvents()
{
OnTokenResponseReceived = context =>
{
context.HandleResponse();
if (context.ProtocolMessage.State == null && !context.ProtocolMessage.Parameters.ContainsKey(ExpectedStateParameter))
return Task.FromResult