public async Task OnValidatePrincipalTestSuccess(bool isPersistent) { var user = new TestUser("test"); var userManager = MockHelpers.MockUserManager<TestUser>(); var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>(); var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.Zero }; var options = new Mock<IOptions<IdentityOptions>>(); options.Setup(a => a.Options).Returns(identityOptions); var httpContext = new Mock<HttpContext>(); var contextAccessor = new Mock<IHttpContextAccessor>(); contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object); var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object, contextAccessor.Object, claimsManager.Object, options.Object, null); signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>(), user.Id)).ReturnsAsync(user).Verifiable(); signInManager.Setup(s => s.SignInAsync(user, isPersistent, null)).Returns(Task.FromResult(0)).Verifiable(); var services = new ServiceCollection(); services.AddInstance(options.Object); services.AddInstance(signInManager.Object); services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<TestUser>()); httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider()); var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationScheme); id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id)); var ticket = new AuthenticationTicket(new ClaimsPrincipal(id), new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, IsPersistent = isPersistent }, IdentityOptions.ApplicationCookieAuthenticationScheme); var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions()); Assert.NotNull(context.Properties); Assert.NotNull(context.Options); Assert.NotNull(context.Principal); await SecurityStampValidator.ValidatePrincipalAsync(context); Assert.NotNull(context.Principal); signInManager.VerifyAll(); }
public async Task<string> StoreAsync(AuthenticationTicket ticket) { var guid = Guid.NewGuid(); var key = KeyPrefix + guid.ToString(); await RenewAsync(key, ticket); return key; }
public static AuthenticateResult Success(AuthenticationTicket ticket) { if (ticket == null) { throw new ArgumentNullException(nameof(ticket)); } return new AuthenticateResult() { Ticket = ticket }; }
public async Task OnValidatePrincipalThrowsWithEmptyServiceCollection() { var httpContext = new Mock<HttpContext>(); httpContext.Setup(c => c.RequestServices).Returns(new ServiceCollection().BuildServiceProvider()); var id = new ClaimsPrincipal(new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationScheme)); var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }, IdentityOptions.ApplicationCookieAuthenticationScheme); var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions()); var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => SecurityStampValidator.ValidatePrincipalAsync(context)); Assert.True(ex.Message.Contains("No service for type 'Microsoft.Framework.OptionsModel.IOptions")); }
/// <summary> /// Initializes a new instance of the <see cref="TokenEndpointContext"/> class /// </summary> /// <param name="context"></param> /// <param name="options"></param> /// <param name="request"></param> /// <param name="ticket"></param> internal TokenEndpointContext( HttpContext context, OpenIdConnectServerOptions options, OpenIdConnectMessage request, AuthenticationTicket ticket) : base(context) { Options = options; Request = request; Ticket = ticket; }
public SigningInContext( HttpContext context, AuthenticationTicket ticket) : base(context) { if (ticket != null) { Principal = ticket.Principal; Properties = ticket.Properties; } }
public TicketReceivedContext(HttpContext context, RemoteAuthenticationOptions options, AuthenticationTicket ticket) : base(context) { Options = options; AuthenticationTicket = ticket; if (ticket != null) { Principal = ticket.Principal; Properties = ticket.Properties; } }
protected ReturnEndpointContext( HttpContext context, AuthenticationTicket ticket) : base(context) { if (ticket != null) { Principal = ticket.Principal; Properties = ticket.Properties; } }
/// <summary> /// Initializes a new instance of the <see cref="SerializeAccessTokenContext"/> class /// </summary> /// <param name="context"></param> /// <param name="options"></param> /// <param name="request"></param> /// <param name="response"></param> /// <param name="ticket"></param> internal SerializeAccessTokenContext( HttpContext context, OpenIdConnectServerOptions options, OpenIdConnectMessage request, OpenIdConnectMessage response, AuthenticationTicket ticket) : base(context) { Options = options; Request = request; Response = response; AuthenticationTicket = ticket; }
/// <summary> /// Initializes a new instance of the <see cref="TokenEndpointResponseContext"/> class /// </summary> /// <param name="context"></param> /// <param name="options"></param> /// <param name="ticket"></param> /// <param name="request"></param> /// <param name="payload"></param> internal TokenEndpointResponseContext( HttpContext context, OpenIdConnectServerOptions options, AuthenticationTicket ticket, OpenIdConnectMessage request, JObject payload) : base(context) { Options = options; AuthenticationTicket = ticket; Request = request; Payload = payload; }
/// <summary> /// Initializes a new instance of the <see cref="AuthorizationEndpointResponseContext"/> class /// </summary> /// <param name="context"></param> /// <param name="options"></param> /// <param name="ticket"></param> /// <param name="request"></param> /// <param name="response"></param> internal AuthorizationEndpointResponseContext( HttpContext context, OpenIdConnectServerOptions options, AuthenticationTicket ticket, OpenIdConnectMessage request, OpenIdConnectMessage response) : base(context) { Options = options; AuthenticationTicket = ticket; Request = request; Response = response; }
public Task RenewAsync(string key, AuthenticationTicket ticket) { var options = new MemoryCacheEntryOptions(); var expiresUtc = ticket.Properties.ExpiresUtc; if(expiresUtc.HasValue) { options.SetAbsoluteExpiration(expiresUtc.Value); } options.SetSlidingExpiration(TimeSpan.FromHours(1)); // TODO: configurable. _cache.Set(key, ticket, options); return Task.FromResult(0); }
public AuthenticationTokenCreateContext(HttpContext context, ISecureDataFormat<AuthenticationTicket> secureDataFormat, AuthenticationTicket ticket) : base(context) { if (secureDataFormat == null) throw new ArgumentNullException(nameof(secureDataFormat)); if (ticket == null) throw new ArgumentNullException(nameof(ticket)); _secureDataFormat = secureDataFormat; Ticket = ticket; }
public void NullPrincipalThrows() { var properties = new AuthenticationProperties(); properties.RedirectUri = "bye"; var ticket = new AuthenticationTicket(properties, "Hello"); using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) using (var reader = new BinaryReader(stream)) { Assert.Throws<ArgumentNullException>(() => TicketSerializer.Write(writer, ticket)); } }
public Task RenewAsync(string key, AuthenticationTicket ticket) { _cache.Set(key, ticket, context => { var expiresUtc = ticket.Properties.ExpiresUtc; if (expiresUtc.HasValue) { context.SetAbsoluteExpiration(expiresUtc.Value); } context.SetSlidingExpiration(TimeSpan.FromHours(1)); // TODO: configurable. return (AuthenticationTicket)context.State; }); return Task.FromResult(0); }
public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context) { var user = us.IsValidUser(context.UserName, context.Password); if(user!= null) { // Validate the credentials here (e.g using ASP.NET Identity). // You can call Rejected() with an error code/description to reject // the request and return a message to the caller. VMUser vu = new VMUser(user); var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, user.username, "token id_token"); identity.AddClaim("profile", JsonConvert.SerializeObject(vu), "token id_token"); // By default, claims are not serialized in the access and identity tokens. // Use the overload taking a "destination" to make sure your claims // are correctly inserted in the appropriate tokens. // identity.AddClaim("urn:customclaim", "value", "token id_token"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), context.Options.AuthenticationScheme); // Call SetResources with the list of resource servers // the access token should be issued for. ticket.SetResources(new[] { "api" }); // Call SetScopes with the list of scopes you want to grant // (specify offline_access to issue a refresh token). ticket.SetScopes(new[] {"api" }); context.Validated(ticket); } else { context.Rejected(); } return Task.FromResult<object>(null); }
public void CanRoundTripEmptyPrincipal() { var properties = new AuthenticationProperties(); properties.RedirectUri = "bye"; var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello"); using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) using (var reader = new BinaryReader(stream)) { TicketSerializer.Write(writer, ticket); stream.Position = 0; var readTicket = TicketSerializer.Read(reader); readTicket.Principal.Identities.Count().ShouldBe(0); readTicket.Properties.RedirectUri.ShouldBe("bye"); readTicket.AuthenticationScheme.ShouldBe("Hello"); } }
public void CanRoundTripBootstrapContext() { var serializer = new TicketSerializer(); var properties = new AuthenticationProperties(); var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello"); ticket.Principal.AddIdentity(new ClaimsIdentity("misc") { BootstrapContext = "bootstrap" }); using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) using (var reader = new BinaryReader(stream)) { serializer.Write(writer, ticket); stream.Position = 0; var readTicket = serializer.Read(reader); Assert.Equal(1, readTicket.Principal.Identities.Count()); Assert.Equal("misc", readTicket.Principal.Identity.AuthenticationType); Assert.Equal("bootstrap", readTicket.Principal.Identities.First().BootstrapContext); } }
public override async Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsNotification notification) { string roleType; if (!UserAuthenticatedSimple(notification, out roleType)) return; //authenticate var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, notification.UserName)); identity.AddClaim(new Claim(ClaimTypes.Role, roleType)); // create metadata to pass on to refresh token provider var props = new AuthenticationProperties(new Dictionary<string, string> { { "as:client_id", notification.ClientId }, {"userName", notification.UserName } }); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, props, OpenIdConnectDefaults.AuthenticationScheme); notification.Validated(ticket); }
public void InteropSerializerCanReadNewTicket() { var user = new ClaimsPrincipal(); var identity = new ClaimsIdentity("scheme"); identity.AddClaim(new Claim("Test", "Value")); user.AddIdentity(identity); var expires = DateTime.Today; var issued = new DateTime(1979, 11, 11); var properties = new Http.Authentication.AuthenticationProperties(); properties.IsPersistent = true; properties.RedirectUri = "/redirect"; properties.Items["key"] = "value"; properties.ExpiresUtc = expires; properties.IssuedUtc = issued; var newTicket = new AuthenticationTicket(user, properties, "scheme"); var newSerializer = new TicketSerializer(); var bytes = newSerializer.Serialize(newTicket); var interopSerializer = new AspNetTicketSerializer(); var interopTicket = interopSerializer.Deserialize(bytes); Assert.NotNull(interopTicket); var newIdentity = interopTicket.Identity; Assert.NotNull(newIdentity); Assert.Equal("scheme", newIdentity.AuthenticationType); Assert.True(newIdentity.HasClaim(c => c.Type == "Test" && c.Value == "Value")); Assert.NotNull(interopTicket.Properties); Assert.True(interopTicket.Properties.IsPersistent); Assert.Equal("/redirect", interopTicket.Properties.RedirectUri); Assert.Equal("value", interopTicket.Properties.Dictionary["key"]); Assert.Equal(expires, interopTicket.Properties.ExpiresUtc); Assert.Equal(issued, interopTicket.Properties.IssuedUtc); }
public void CanRoundTripActorIdentity() { var serializer = new TicketSerializer(); var properties = new AuthenticationProperties(); var actor = new ClaimsIdentity("actor"); var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello"); ticket.Principal.AddIdentity(new ClaimsIdentity("misc") { Actor = actor }); using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) using (var reader = new BinaryReader(stream)) { serializer.Write(writer, ticket); stream.Position = 0; var readTicket = serializer.Read(reader); Assert.Equal(1, readTicket.Principal.Identities.Count()); Assert.Equal("misc", readTicket.Principal.Identity.AuthenticationType); var identity = (ClaimsIdentity) readTicket.Principal.Identity; Assert.NotNull(identity.Actor); Assert.Equal(identity.Actor.AuthenticationType, "actor"); } }
/// <summary> /// Serialize and sign the authentication ticket. /// Note: the <see cref="AccessToken"/> property /// is automatically set when this method completes. /// </summary> /// <param name="ticket">The authentication ticket to serialize.</param> /// <returns>The serialized and signed ticket.</returns> public async Task<string> SerializeTicketAsync(AuthenticationTicket ticket) { return AccessToken = await Serializer(ticket); }
public void CanRoundTripClaimProperties() { var serializer = new TicketSerializer(); var properties = new AuthenticationProperties(); var claim = new Claim("type", "value", "valueType", "issuer", "original-issuer"); claim.Properties.Add("property-1", "property-value"); // Note: a null value MUST NOT result in a crash // and MUST instead be treated like an empty string. claim.Properties.Add("property-2", null); var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello"); ticket.Principal.AddIdentity(new ClaimsIdentity(new[] { claim }, "misc")); using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) using (var reader = new BinaryReader(stream)) { serializer.Write(writer, ticket); stream.Position = 0; var readTicket = serializer.Read(reader); Assert.Equal(1, readTicket.Principal.Identities.Count()); Assert.Equal("misc", readTicket.Principal.Identity.AuthenticationType); var readClaim = readTicket.Principal.FindFirst("type"); Assert.NotNull(claim); Assert.Equal(claim.Type, "type"); Assert.Equal(claim.Value, "value"); Assert.Equal(claim.ValueType, "valueType"); Assert.Equal(claim.Issuer, "issuer"); Assert.Equal(claim.OriginalIssuer, "original-issuer"); var property1 = readClaim.Properties["property-1"]; Assert.Equal(property1, "property-value"); var property2 = readClaim.Properties["property-2"]; Assert.Equal(property2, string.Empty); } }
/// <summary> /// Serialize and sign the authentication ticket using <see cref="DataFormat"/>. /// Note: the <see cref="AuthorizationCode"/> property /// is automatically set when this method completes. /// </summary> /// <param name="ticket">The authentication ticket to serialize.</param> /// <returns>The serialized and signed ticket.</returns> public async Task<string> SerializeTicketAsync(AuthenticationTicket ticket) { return AuthorizationCode = await Serializer(ticket); }
private async Task CreateOrUpdateUserAsync(AuthenticationTicket authenticationTicket, UserManager userManager, Tenant tenant) { Guard.ArgumentNotNull(authenticationTicket, nameof(authenticationTicket)); Guard.ArgumentNotNull(userManager, nameof(userManager)); Guard.ArgumentNotNull(tenant, nameof(tenant)); var principal = authenticationTicket.Principal; string objectIdentifier = principal.GetObjectIdentifierValue(); string displayName = principal.GetDisplayNameValue(); string email = principal.GetEmailValue(); var user = await userManager.FindByObjectIdentifier(objectIdentifier) .ConfigureAwait(false); if (user == null) { // The user isn't in our database, so add them. user = new User { Created = DateTimeOffset.UtcNow, ObjectId = objectIdentifier, TenantId = tenant.Id, DisplayName = displayName, Email = email }; await userManager.CreateAsync(user) .ConfigureAwait(false); } else { // Since we aren't the system of record, we need to attempt to keep our display values in sync with the user store. // We'll do a simple form of it here. bool shouldSaveUser = false; if (!user.DisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase)) { user.DisplayName = displayName; shouldSaveUser = true; } // Do a case insensitive comparison for email matching if (!user.Email.Equals(email, StringComparison.OrdinalIgnoreCase)) { user.Email = email; shouldSaveUser = true; } if (shouldSaveUser) { await userManager .UpdateAsync(user) .ConfigureAwait(false); } } // Add in the survey user id claim. principal.Identities.First().AddClaim(new Claim(SurveyClaimTypes.SurveyUserIdClaimType, user.Id.ToString())); // Add in the user's tenant id claim. principal.Identities.First().AddClaim(new Claim(SurveyClaimTypes.SurveyTenantIdClaimType, user.TenantId.ToString())); }
public void SetTicket([NotNull] AuthenticationTicket ticket) { Ticket = ticket; }
public async Task OnValidateIdentityDoesNotRejectsWhenNotExpired() { var user = new TestUser("test"); var httpContext = new Mock<HttpContext>(); var userManager = MockHelpers.MockUserManager<TestUser>(); var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>(); var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.FromDays(1) }; var options = new Mock<IOptions<IdentityOptions>>(); options.Setup(a => a.Options).Returns(identityOptions); var contextAccessor = new Mock<IHttpContextAccessor>(); contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object); var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object, contextAccessor.Object, claimsManager.Object, options.Object, null); signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>(), user.Id)).Throws(new Exception("Shouldn't be called")); signInManager.Setup(s => s.SignInAsync(user, false, null)).Throws(new Exception("Shouldn't be called")); var services = new ServiceCollection(); services.AddInstance(options.Object); services.AddInstance(signInManager.Object); services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<TestUser>()); httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider()); var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationScheme); id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id)); var ticket = new AuthenticationTicket(new ClaimsPrincipal(id), new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }, IdentityOptions.ApplicationCookieAuthenticationScheme); var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions()); Assert.NotNull(context.Properties); Assert.NotNull(context.Options); Assert.NotNull(context.Principal); await SecurityStampValidator.ValidatePrincipalAsync(context); Assert.NotNull(context.Principal); }
public async Task OnValidateIdentityRejectsWhenNoIssuedUtc() { var user = new TestUser("test"); var httpContext = new Mock<HttpContext>(); var userManager = MockHelpers.MockUserManager<TestUser>(); var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>(); var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.Zero }; var options = new Mock<IOptions<IdentityOptions>>(); options.Setup(a => a.Value).Returns(identityOptions); var contextAccessor = new Mock<IHttpContextAccessor>(); contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object); var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object, contextAccessor.Object, claimsManager.Object, options.Object, null); signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>(), user.Id)).ReturnsAsync(null).Verifiable(); var services = new ServiceCollection(); services.AddSingleton(options.Object); services.AddSingleton(signInManager.Object); services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>()); httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider()); var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme); id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id)); var ticket = new AuthenticationTicket(new ClaimsPrincipal(id), new AuthenticationProperties(), identityOptions.Cookies.ApplicationCookieAuthenticationScheme); var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions()); Assert.NotNull(context.Properties); Assert.NotNull(context.Options); Assert.NotNull(context.Principal); await SecurityStampValidator.ValidatePrincipalAsync(context); Assert.Null(context.Principal); signInManager.VerifyAll(); }