public static async Task ValidateAsync_WrongAudience() { AuthenticationSettings authenticationSettings = new() { Google = new GoogleAuthenticationSettings { ClientId = ClientId, }, }; IOptions <AuthenticationSettings> options = Options.Create(authenticationSettings); using (HttpClientTestingFactory http = new()) { GoogleAssertionGrantHandler handler = new(options, http.HttpClient); Task <AssertionGrantResult> resultTask = handler.ValidateAsync(Assertion); http.Expect(ValidationEndpoint).Respond(JsonConvert.SerializeObject(new JsonWebToken { Aud = "SomeOtherClientId", Sub = ExternalUserId, })); AssertionGrantResult result = await resultTask; Assert.NotNull(result); Assert.False(result.IsSuccessful); http.EnsureNoOutstandingRequests(); } }
public void IsSuccessful(bool isSuccessful, string externalUserId, string externalUserEmail, string error) { var result = new AssertionGrantResult { ExternalUserId = externalUserId, ExternalUserEmail = externalUserEmail, Error = error, }; Assert.Equal(isSuccessful, result.IsSuccessful); }
public static async Task ValidateAsync_HttpError() { AuthenticationSettings authenticationSettings = new(); IOptions <AuthenticationSettings> options = Options.Create(authenticationSettings); using (HttpClientTestingFactory http = new()) { GoogleAssertionGrantHandler handler = new(options, http.HttpClient); Task <AssertionGrantResult> resultTask = handler.ValidateAsync(Assertion); http.Expect(ValidationEndpoint).Respond(HttpStatusCode.BadRequest); AssertionGrantResult result = await resultTask; Assert.NotNull(result); Assert.False(result.IsSuccessful); http.EnsureNoOutstandingRequests(); } }
public async Task <ActionResult> ExchangeAsync() { OpenIddictRequest request = HttpContext.GetOpenIddictServerRequest(); if (request.IsPasswordGrantType()) { // Allow the user to log in with their email address too. // We already check that usernames are only "word" chars (\w+), so this check is sufficient. ApplicationUser user = request.Username.Contains("@", StringComparison.Ordinal) ? await _userManager.FindByEmailAsync(request.Username) : await _userManager.FindByNameAsync(request.Username); if (user == null) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The username/password couple is invalid.", }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } // Validate the username/password parameters and ensure the account is not locked out. SignInResult result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, lockoutOnFailure : false); if (!result.Succeeded) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The username/password couple is invalid.", }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } return(await SignInAsync(request, user)); } if (request.IsRefreshTokenGrantType()) { // Retrieve the claims principal stored in the refresh token. AuthenticateResult result = await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); // Retrieve the user profile corresponding to the refresh token. ApplicationUser user = await _signInManager.ValidateSecurityStampAsync(result.Principal); if (user == null) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The refresh token is no longer valid.", }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } // Ensure the user is still allowed to sign in. if (!await _signInManager.CanSignInAsync(user)) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is no longer allowed to sign in.", }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } // Reuse the properties stored in the refresh token, including the scopes originally granted. return(await SignInAsync(request, user)); } IAssertionGrantHandler assertionGrantHandler = _assertionGrantHandlerProvider.GetHandler(request.GrantType); if (assertionGrantHandler != null) { // Reject the request if the "assertion" parameter is missing. if (string.IsNullOrEmpty(request.Assertion)) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidRequest, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The mandatory 'assertion' parameter was missing.", }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } AssertionGrantResult validationResult = await assertionGrantHandler.ValidateAsync(request.Assertion); if (!validationResult.IsSuccessful) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = validationResult.Error, }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } // Find the user associated with this external log in ApplicationUser user = await _userManager.FindByLoginAsync(assertionGrantHandler.Name, validationResult.ExternalUserId); if (user == null) { if (!string.IsNullOrEmpty(request.Username)) { // They provided a user name, so try to implicitly create an account for them user = new ApplicationUser { UserName = request.Username, Email = validationResult.ExternalUserEmail }; IdentityResult creationResult = await _userManager.CreateAsync(user); if (!creationResult.Succeeded) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = string.Join(" ", creationResult.Errors.Select(error => error.Description)), }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } } if (user == null) { // If the user is already logged in, use the current user user = await _userManager.GetUserAsync(User); } // Add the login if we found a user if (user != null) { UserLoginInfo login = new(assertionGrantHandler.Name, validationResult.ExternalUserId, assertionGrantHandler.Name); IdentityResult addLoginResult = await _userManager.AddLoginAsync(user, login); if (!addLoginResult.Succeeded) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = string.Join(" ", addLoginResult.Errors.Select(error => error.Description)), }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } } else { // Ask the user to create an account. AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.AccountSelectionRequired, }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } } // Ensure the user is allowed to sign in. if (!await _signInManager.CanSignInAsync(user)) { AuthenticationProperties properties = new(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is no longer allowed to sign in.", }); return(Forbid(properties, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } return(await SignInAsync(request, user)); } throw new NotImplementedException("The specified grant type is not implemented."); }