|
|
|
@ -88,7 +88,7 @@ namespace OpenIddict.Tests |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); |
|
|
|
ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.AccessToken); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
@ -124,7 +124,7 @@ namespace OpenIddict.Tests |
|
|
|
|
|
|
|
builder.Services.AddSingleton(manager); |
|
|
|
|
|
|
|
builder.Configure(options => options.RefreshTokenFormat = format.Object); |
|
|
|
builder.Configure(options => options.AccessTokenFormat = format.Object); |
|
|
|
}); |
|
|
|
|
|
|
|
var client = new OpenIdConnectClient(server.CreateClient()); |
|
|
|
@ -146,7 +146,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAccessToken_ReturnsNullForMissingTokenIdentifier() |
|
|
|
public async Task DeserializeAccessToken_ReturnsNullForMissingReferenceTokenIdentifier() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var token = new OpenIddictToken(); |
|
|
|
@ -201,7 +201,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAccessToken_ReturnsNullForMissingTokenCiphertext() |
|
|
|
public async Task DeserializeAccessToken_ReturnsNullForMissingReferenceTokenCiphertext() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var token = new OpenIddictToken(); |
|
|
|
@ -259,7 +259,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAccessToken_ReturnsNullForInvalidTokenCiphertext() |
|
|
|
public async Task DeserializeAccessToken_ReturnsNullForInvalidReferenceTokenCiphertext() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
@ -325,7 +325,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAccessToken_ReturnsExpectedToken() |
|
|
|
public async Task DeserializeAccessToken_ReturnsExpectedReferenceToken() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
@ -337,7 +337,6 @@ namespace OpenIddict.Tests |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
@ -471,7 +470,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAuthorizationCode_AuthorizationCodeIsNotRetrievedFromDatabaseWhenReferenceTokensAreDisabled() |
|
|
|
public async Task DeserializeAuthorizationCode_AuthorizationCodeIsNotRetrievedUsingHashWhenReferenceTokensAreDisabled() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
@ -483,7 +482,6 @@ namespace OpenIddict.Tests |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
@ -497,6 +495,9 @@ namespace OpenIddict.Tests |
|
|
|
instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(token); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.IsValidAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
}); |
|
|
|
@ -541,7 +542,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsNullForMissingTokenIdentifier() |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsNullForMissingReferenceTokenIdentifier() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var token = new OpenIddictToken(); |
|
|
|
@ -596,7 +597,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsNullForMissingTokenCiphertext() |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsNullForMissingReferenceTokenCiphertext() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var token = new OpenIddictToken(); |
|
|
|
@ -654,7 +655,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsNullForInvalidTokenCiphertext() |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsNullForInvalidReferenceTokenCiphertext() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
@ -720,7 +721,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsExpectedToken() |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsExpectedReferenceToken() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
@ -731,9 +732,6 @@ namespace OpenIddict.Tests |
|
|
|
new AuthenticationProperties(), |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) |
|
|
|
@ -816,6 +814,192 @@ namespace OpenIddict.Tests |
|
|
|
format.Verify(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA"), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsNullForMissingTokenIdentifier() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); |
|
|
|
|
|
|
|
var ticket = new AuthenticationTicket( |
|
|
|
new ClaimsPrincipal(identity), |
|
|
|
new AuthenticationProperties(), |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) |
|
|
|
.Returns(ticket); |
|
|
|
|
|
|
|
var server = CreateAuthorizationServer(builder => |
|
|
|
{ |
|
|
|
builder.Services.AddSingleton(CreateApplicationManager(instance => |
|
|
|
{ |
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
})); |
|
|
|
|
|
|
|
builder.Configure(options => options.AuthorizationCodeFormat = format.Object); |
|
|
|
}); |
|
|
|
|
|
|
|
var client = new OpenIdConnectClient(server.CreateClient()); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
Token = "2YotnFZFEjr1zCsicMWpAA", |
|
|
|
TokenTypeHint = OpenIdConnectConstants.TokenTypeHints.AuthorizationCode |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Single(response.GetParameters()); |
|
|
|
Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsNullForInvalidTokenCiphertext() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) |
|
|
|
.Returns(value: null); |
|
|
|
|
|
|
|
var server = CreateAuthorizationServer(builder => |
|
|
|
{ |
|
|
|
builder.Services.AddSingleton(CreateApplicationManager(instance => |
|
|
|
{ |
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
})); |
|
|
|
|
|
|
|
builder.Configure(options => options.AuthorizationCodeFormat = format.Object); |
|
|
|
}); |
|
|
|
|
|
|
|
var client = new OpenIdConnectClient(server.CreateClient()); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
Token = "2YotnFZFEjr1zCsicMWpAA", |
|
|
|
TokenTypeHint = OpenIdConnectConstants.TokenTypeHints.AuthorizationCode |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Single(response.GetParameters()); |
|
|
|
Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); |
|
|
|
|
|
|
|
format.Verify(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA"), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeAuthorizationCode_ReturnsExpectedToken() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); |
|
|
|
|
|
|
|
var ticket = new AuthenticationTicket( |
|
|
|
new ClaimsPrincipal(identity), |
|
|
|
new AuthenticationProperties(), |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) |
|
|
|
.Returns(ticket); |
|
|
|
|
|
|
|
var token = new OpenIddictToken(); |
|
|
|
|
|
|
|
var manager = CreateTokenManager(instance => |
|
|
|
{ |
|
|
|
instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(token); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.IsValidAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetCreationDateAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(new DateTimeOffset(2017, 01, 01, 00, 00, 00, TimeSpan.Zero)); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetExpirationDateAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(new DateTimeOffset(2017, 01, 10, 00, 00, 00, TimeSpan.Zero)); |
|
|
|
}); |
|
|
|
|
|
|
|
var server = CreateAuthorizationServer(builder => |
|
|
|
{ |
|
|
|
builder.Services.AddSingleton(CreateApplicationManager(instance => |
|
|
|
{ |
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
})); |
|
|
|
|
|
|
|
builder.Services.AddSingleton(manager); |
|
|
|
|
|
|
|
builder.Configure(options => |
|
|
|
{ |
|
|
|
options.SystemClock = Mock.Of<ISystemClock>(mock => mock.UtcNow == |
|
|
|
new DateTimeOffset(2017, 01, 05, 00, 00, 00, TimeSpan.Zero)); |
|
|
|
|
|
|
|
options.AuthorizationCodeFormat = format.Object; |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
var client = new OpenIdConnectClient(server.CreateClient()); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
Token = "2YotnFZFEjr1zCsicMWpAA", |
|
|
|
TokenTypeHint = OpenIdConnectConstants.TokenTypeHints.AuthorizationCode |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.True((bool) response[OpenIdConnectConstants.Claims.Active]); |
|
|
|
Assert.Equal("3E228451-1555-46F7-A471-951EFBA23A56", response[OpenIdConnectConstants.Claims.JwtId]); |
|
|
|
Assert.Equal(1483228800, (long) response[OpenIdConnectConstants.Claims.IssuedAt]); |
|
|
|
Assert.Equal(1484006400, (long) response[OpenIdConnectConstants.Claims.ExpiresAt]); |
|
|
|
|
|
|
|
Mock.Get(manager).Verify(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>()), Times.AtLeastOnce()); |
|
|
|
Mock.Get(manager).Verify(mock => mock.GetIdAsync(token, It.IsAny<CancellationToken>()), Times.AtLeastOnce()); |
|
|
|
format.Verify(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA"), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForMalformedReferenceToken() |
|
|
|
{ |
|
|
|
@ -866,7 +1050,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_RefreshTokenIsNotRetrievedFromDatabaseWhenReferenceTokensAreDisabled() |
|
|
|
public async Task DeserializeRefreshToken_RefreshTokenIsNotRetrievedUsingHashWhenReferenceTokensAreDisabled() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
@ -878,7 +1062,6 @@ namespace OpenIddict.Tests |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
@ -892,6 +1075,9 @@ namespace OpenIddict.Tests |
|
|
|
instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(token); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.IsValidAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
}); |
|
|
|
@ -936,7 +1122,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForMissingTokenIdentifier() |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForMissingReferenceTokenIdentifier() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var token = new OpenIddictToken(); |
|
|
|
@ -991,7 +1177,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForMissingTokenCiphertext() |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForMissingReferenceTokenCiphertext() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var token = new OpenIddictToken(); |
|
|
|
@ -1049,7 +1235,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForInvalidTokenCiphertext() |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForInvalidReferenceTokenCiphertext() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
@ -1115,7 +1301,7 @@ namespace OpenIddict.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_ReturnsExpectedToken() |
|
|
|
public async Task DeserializeRefreshToken_ReturnsExpectedReferenceToken() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
@ -1126,9 +1312,6 @@ namespace OpenIddict.Tests |
|
|
|
new AuthenticationProperties(), |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) |
|
|
|
@ -1211,6 +1394,192 @@ namespace OpenIddict.Tests |
|
|
|
format.Verify(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA"), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForMissingTokenIdentifier() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); |
|
|
|
|
|
|
|
var ticket = new AuthenticationTicket( |
|
|
|
new ClaimsPrincipal(identity), |
|
|
|
new AuthenticationProperties(), |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) |
|
|
|
.Returns(ticket); |
|
|
|
|
|
|
|
var server = CreateAuthorizationServer(builder => |
|
|
|
{ |
|
|
|
builder.Services.AddSingleton(CreateApplicationManager(instance => |
|
|
|
{ |
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
})); |
|
|
|
|
|
|
|
builder.Configure(options => options.RefreshTokenFormat = format.Object); |
|
|
|
}); |
|
|
|
|
|
|
|
var client = new OpenIdConnectClient(server.CreateClient()); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
Token = "2YotnFZFEjr1zCsicMWpAA", |
|
|
|
TokenTypeHint = OpenIdConnectConstants.TokenTypeHints.RefreshToken |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Single(response.GetParameters()); |
|
|
|
Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_ReturnsNullForInvalidTokenCiphertext() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) |
|
|
|
.Returns(value: null); |
|
|
|
|
|
|
|
var server = CreateAuthorizationServer(builder => |
|
|
|
{ |
|
|
|
builder.Services.AddSingleton(CreateApplicationManager(instance => |
|
|
|
{ |
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
})); |
|
|
|
|
|
|
|
builder.Configure(options => options.RefreshTokenFormat = format.Object); |
|
|
|
}); |
|
|
|
|
|
|
|
var client = new OpenIdConnectClient(server.CreateClient()); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
Token = "2YotnFZFEjr1zCsicMWpAA", |
|
|
|
TokenTypeHint = OpenIdConnectConstants.TokenTypeHints.RefreshToken |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Single(response.GetParameters()); |
|
|
|
Assert.False((bool) response[OpenIdConnectConstants.Claims.Active]); |
|
|
|
|
|
|
|
format.Verify(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA"), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task DeserializeRefreshToken_ReturnsExpectedToken() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Bricoleur"); |
|
|
|
|
|
|
|
var ticket = new AuthenticationTicket( |
|
|
|
new ClaimsPrincipal(identity), |
|
|
|
new AuthenticationProperties(), |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
|
|
|
|
format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) |
|
|
|
.Returns(ticket); |
|
|
|
|
|
|
|
var token = new OpenIddictToken(); |
|
|
|
|
|
|
|
var manager = CreateTokenManager(instance => |
|
|
|
{ |
|
|
|
instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(token); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.IsValidAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetCreationDateAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(new DateTimeOffset(2017, 01, 01, 00, 00, 00, TimeSpan.Zero)); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetExpirationDateAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(new DateTimeOffset(2017, 01, 10, 00, 00, 00, TimeSpan.Zero)); |
|
|
|
}); |
|
|
|
|
|
|
|
var server = CreateAuthorizationServer(builder => |
|
|
|
{ |
|
|
|
builder.Services.AddSingleton(CreateApplicationManager(instance => |
|
|
|
{ |
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
})); |
|
|
|
|
|
|
|
builder.Services.AddSingleton(manager); |
|
|
|
|
|
|
|
builder.Configure(options => |
|
|
|
{ |
|
|
|
options.SystemClock = Mock.Of<ISystemClock>(mock => mock.UtcNow == |
|
|
|
new DateTimeOffset(2017, 01, 05, 00, 00, 00, TimeSpan.Zero)); |
|
|
|
|
|
|
|
options.RefreshTokenFormat = format.Object; |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
var client = new OpenIdConnectClient(server.CreateClient()); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
Token = "2YotnFZFEjr1zCsicMWpAA", |
|
|
|
TokenTypeHint = OpenIdConnectConstants.TokenTypeHints.RefreshToken |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.True((bool) response[OpenIdConnectConstants.Claims.Active]); |
|
|
|
Assert.Equal("3E228451-1555-46F7-A471-951EFBA23A56", response[OpenIdConnectConstants.Claims.JwtId]); |
|
|
|
Assert.Equal(1483228800, (long) response[OpenIdConnectConstants.Claims.IssuedAt]); |
|
|
|
Assert.Equal(1484006400, (long) response[OpenIdConnectConstants.Claims.ExpiresAt]); |
|
|
|
|
|
|
|
Mock.Get(manager).Verify(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>()), Times.AtLeastOnce()); |
|
|
|
Mock.Get(manager).Verify(mock => mock.GetIdAsync(token, It.IsAny<CancellationToken>()), Times.AtLeastOnce()); |
|
|
|
format.Verify(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA"), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task SerializeAccessToken_AccessTokenIsNotPersistedWhenReferenceTokensAreDisabled() |
|
|
|
{ |
|
|
|
@ -1736,7 +2105,6 @@ namespace OpenIddict.Tests |
|
|
|
OpenIdConnectServerDefaults.AuthenticationScheme); |
|
|
|
|
|
|
|
ticket.SetTokenId("60FFF7EA-F98E-437B-937E-5073CC313103"); |
|
|
|
ticket.SetTokenUsage(OpenIdConnectConstants.TokenUsages.RefreshToken); |
|
|
|
ticket.SetScopes(OpenIdConnectConstants.Scopes.OpenId, OpenIdConnectConstants.Scopes.OfflineAccess); |
|
|
|
|
|
|
|
var format = new Mock<ISecureDataFormat<AuthenticationTicket>>(); |
|
|
|
@ -1754,6 +2122,9 @@ namespace OpenIddict.Tests |
|
|
|
instance.Setup(mock => mock.FindByIdAsync("60FFF7EA-F98E-437B-937E-5073CC313103", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(token); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.GetIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("60FFF7EA-F98E-437B-937E-5073CC313103"); |
|
|
|
|
|
|
|
instance.Setup(mock => mock.IsRedeemedAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(false); |
|
|
|
|
|
|
|
|