public async Task <AuthenticationResult> AuthenticateExternalAsync(ExternalIdentity identity, SignInData signInData) { if (identity == null) { throw new ArgumentNullException("externalUser"); } try { var tenant = String.IsNullOrWhiteSpace(signInData.Tenant) ? userAccountService.Configuration.DefaultTenant : signInData.Tenant; var acct = this.userAccountService.GetByLinkedAccount(tenant, identity.Provider, identity.ProviderId); if (acct == null) { return(await ProcessNewExternalAccountAsync(tenant, identity.Provider, identity.ProviderId, identity.Claims)); } else { return(await ProcessExistingExternalAccountAsync(acct.ID, identity.Provider, identity.ProviderId, identity.Claims)); } } catch (ValidationException ex) { return(await Task.FromResult(new AuthenticationResult(ex.Message))); } }
private async Task <AuthenticateResult> GetAppropriateAuthenticationResult(ExternalIdentity externalIdentity) { var account = await _userRepository.GetUserForExternalProviderAsync(externalIdentity.Provider, externalIdentity.ProviderId); if (account != null) { return(CreateSuccesFullAuthentication(externalIdentity, account)); } var emailClaim = externalIdentity.Claims.FirstOrDefault(c => c.Type == "email"); if (emailClaim == null) { return(new AuthenticateResult("An email is claim required to authenticate.")); } var userWithMatchingEmailClaim = await _userRepository.GetUserByEmailAsync(emailClaim.Value); if (userWithMatchingEmailClaim == null && externalIdentity.Provider == "windows") { return(AskWindowsAuthenticatedUserForAdditionalInfo(externalIdentity)); } if (userWithMatchingEmailClaim == null) { return(CreateNewUserAndAuthenticate(externalIdentity)); } return(await AuthenticateExistingUserWithNewExternalProvider( externalIdentity, userWithMatchingEmailClaim)); }
public async Task <ExternalIdentity> Get(string authToken, string applicationKey) { var token = await _externalApplicationService.GetTokenAsync(authToken, applicationKey); var identity = await _identityService.GetIdentityAsync(token.IdentityId); var extensions = await GetIdentityAttributesAsExternsions(identity); var externalIdentity = new ExternalIdentity { GivenName = identity.GivenName, IdentityId = identity.IdentityId, Surname = identity.Surname, Email = identity.Email, PhoneNumber = identity.PhoneNumber, Issuer = RinsenIdentityConstants.RinsenIdentityProvider, Expiration = token.Expiration, CorrelationId = token.CorrelationId, Extensions = extensions }; await _externalApplicationService.LogExportedExternalIdentity(externalIdentity, token.ExternalApplicationId); return(externalIdentity); }
/// <summary> /// This method gets called when the user uses an external identity provider to authenticate. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> public override async Task AuthenticateExternalAsync(ExternalAuthenticationContext context) { ExternalIdentity externalIdentity = context.ExternalIdentity; if (externalIdentity == null) { throw new ArgumentNullException(nameof(externalIdentity)); } User user = await _users.FindOneAsync(u => u.Provider == externalIdentity.Provider && u.ProviderId == externalIdentity.ProviderId); if (user == null) { Claim name = externalIdentity.Claims.FirstOrDefault(x => x.Type == Constants.ClaimTypes.Name); string displayName = name == null ? externalIdentity.ProviderId : name.Value; user = new User { Id = CryptoRandom.CreateUniqueId(), Provider = externalIdentity.Provider, ProviderId = externalIdentity.ProviderId, Username = displayName, Claims = externalIdentity.Claims.ToModel() }; await _users.CreateAsync(user); } context.AuthenticateResult = new AuthenticateResult(user.Id, GetDisplayName(user), identityProvider: externalIdentity.Provider); }
/// <summary> /// This method gets called when the user uses an external identity provider to authenticate. /// </summary> /// <param name="externalUser">The external user.</param> /// <returns> /// The authentication result. /// </returns> public virtual Task <AuthenticateResult> AuthenticateExternalAsync(ExternalIdentity externalUser) { var query = from u in _users where u.Provider == externalUser.Provider && u.ProviderId == externalUser.ProviderId select u; var user = query.SingleOrDefault(); if (user == null) { var name = externalUser.Claims.FirstOrDefault(x => x.Type == Constants.ClaimTypes.Name); if (name == null) { return(Task.FromResult <AuthenticateResult>(null)); } user = new InMemoryUser { Subject = CryptoRandom.CreateUniqueId(), Provider = externalUser.Provider, ProviderId = externalUser.ProviderId, Username = name.Value, Claims = externalUser.Claims }; _users.Add(user); } var p = IdentityServerPrincipal.Create(user.Subject, GetDisplayName(user), Constants.AuthenticationMethods.External, user.Provider); var result = new AuthenticateResult(p); return(Task.FromResult(result)); }
public virtual async Task <AuthenticateResult> AuthenticateExternalAsync(ExternalIdentity externalUser, SignInMessage message) { if (externalUser == null) { throw new ArgumentNullException("externalUser"); } try { var tenant = String.IsNullOrWhiteSpace(message.Tenant) ? userAccountService.Configuration.DefaultTenant : message.Tenant; var acct = this.userAccountService.GetByLinkedAccount(tenant, externalUser.Provider, externalUser.ProviderId); if (acct == null) { return(await ProcessNewExternalAccountAsync(tenant, externalUser.Provider, externalUser.ProviderId, externalUser.Claims)); } else { return(await ProcessExistingExternalAccountAsync(acct.ID, externalUser.Provider, externalUser.ProviderId, externalUser.Claims)); } } catch (ValidationException ex) { return(new AuthenticateResult(ex.Message)); } }
private AuthenticateResult CreateNewUserAndAuthenticate(ExternalIdentity externalIdentity) { var newUser = ConfigureNewUser(externalIdentity); _userRepository.SaveUser(newUser); return(CreateSuccesFullAuthentication(externalIdentity, newUser)); }
private async Task <IActionResult> externalSignUpAsync( ExternalIdentity firebaseIdentity, string roleParam, string returnUrl ) { IdentityResult identityResult = null; int roleIndex = rolesArray.FindIndex(n => n == roleParam); if (roleIndex != -1) { Roles role = (Roles)roleIndex; ApplicationUser user = сreateRoleBasedInstance(role, firebaseIdentity); identityResult = await userManager.CreateAsync(user); if (identityResult.Succeeded) { user.EmailConfirmed = firebaseIdentity.EmailConfirmed; identityResult = await userManager.AddToRoleAsync(user, role.ToString()); identityResult = identityResult.Succeeded ? await userManager.AddLoginAsync( user, new UserLoginInfo( firebaseIdentity.SignInProvider, firebaseIdentity.ProviderKey, firebaseIdentity.SignInProvider ) ) : identityResult; if (identityResult.Succeeded) { await notifyHub.NotifyOfNewUser(user, role); return(SignResult( await signInManager.ExternalLoginSignInAsync( firebaseIdentity.SignInProvider, firebaseIdentity.ProviderKey, true ), returnUrl )); } } AddErrors(identityResult); return(BadRequest(new ApiError(ModelState))); } else { return(BadRequest(new ValidationError( ErrorType.UnexpectedError, "Ivalid user role provided!" ))); } }
private static AuthenticateResult CreateSuccesFullAuthentication(ExternalIdentity externalIdentity, User authenticatedUser) { return(new AuthenticateResult( authenticatedUser.Subject, authenticatedUser.UserClaims.First(c => c.ClaimType == Constants.ClaimTypes.GivenName).ClaimValue, authenticatedUser.UserClaims.Select(uc => new Claim(uc.ClaimType, uc.ClaimValue)), authenticationMethod: Constants.AuthenticationMethods.External, identityProvider: externalIdentity.Provider)); }
private ExternalIdentity MapToExternalIdentity(IEnumerable <Claim> claims) { var externalId = ExternalIdentity.FromClaims(claims); if (externalId != null && _externalClaimsFilter != null) { externalId.Claims = _externalClaimsFilter.Filter(externalId.Provider, externalId.Claims); } return(externalId); }
public async Task <IHttpActionResult> LoginExternalCallback() { Logger.Info("Callback invoked from external identity provider "); var signInId = await GetSignInIdFromExternalProvider(); if (signInId.IsMissing()) { Logger.Error("No signin id passed"); return(RenderErrorPage()); } var cookie = new MessageCookie <SignInMessage>(Request.GetOwinContext(), this._options); var signInMessage = cookie.Read(signInId); if (signInMessage == null) { Logger.Error("No cookie matching signin id found"); return(RenderErrorPage()); } var user = await GetIdentityFromExternalProvider(); if (user == null) { Logger.Error("no identity from external identity provider"); return(await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount)); } var externalIdentity = ExternalIdentity.FromClaims(user.Claims); if (externalIdentity == null) { Logger.Error("no subject or unique identifier claims from external identity provider"); return(await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount)); } Logger.InfoFormat("external user provider: {0}, provider ID: {1}", externalIdentity.Provider, externalIdentity.ProviderId); var authResult = await _userService.AuthenticateExternalAsync(externalIdentity); if (authResult == null) { Logger.Warn("user service failed to authenticate external identity"); return(await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount)); } if (authResult.IsError) { Logger.WarnFormat("user service returned error message: {0}", authResult.ErrorMessage); return(await RenderLoginPage(signInMessage, signInId, authResult.ErrorMessage)); } return(SignInAndRedirect(signInMessage, signInId, authResult)); }
private async Task <AuthenticateResult> AuthenticateExistingUserWithNewExternalProvider( ExternalIdentity externalIdentity, User userWithMatchingEmailClaim) { await _userRepository.AddUserLoginAsync( userWithMatchingEmailClaim.Subject, externalIdentity.Provider, externalIdentity.ProviderId); return(CreateSuccesFullAuthentication(externalIdentity, userWithMatchingEmailClaim)); }
public Task LogExportedExternalIdentity(ExternalIdentity externalIdentity, Guid externalApplicationId) { var externalSession = new ExternalSession { CorrelationId = externalIdentity.CorrelationId, Created = DateTimeOffset.Now, ExternalApplicationId = externalApplicationId, IdentityId = externalIdentity.IdentityId }; return(_externalSessionStorage.Create(externalSession)); }
public async Task LogInToIdSrv(ExternalIdentity externalIdentity) { // Now ask the user service to check if the user exist or potentially create a new user // The InMemoryStore will automatically create users // You will almost certainly want a custom user store that knows your rules for handling external logins // and mapping them to "local" users ... though I guess that is not unique to IdP-initiated var userService = this.GetUserService(); var p = await userService.AuthenticateExternalAsync(externalIdentity, new SignInMessage()); // TODO: Check if the userservice was happy and do some sensible error handling // Get IdentityServer to set an authentication cookie this.SetTheIdSrvAuthCookie(p); }
public Task <AuthenticateResult> AuthenticateExternalAsync(ExternalIdentity externalUser) { // look for the user in our local identity system from the external identifiers var user = Users.SingleOrDefault(x => x.Provider == externalUser.Provider.Name && x.ProviderID == externalUser.ProviderId); string name = "Unknown"; if (user == null) { // new user, so add them here var nameClaim = externalUser.Claims.First(x => x.Type == Constants.ClaimTypes.Name); if (nameClaim != null) { name = nameClaim.Value; } user = new CustomUser { Subject = Guid.NewGuid().ToString(), Provider = externalUser.Provider.Name, ProviderID = externalUser.ProviderId, Claims = new List <Claim> { new Claim(Constants.ClaimTypes.Name, name) } }; Users.Add(user); } name = user.Claims.First(x => x.Type == Constants.ClaimTypes.Name).Value; if (user.IsRegistered) { // user is registered so continue var p = IdentityServerPrincipal.Create( user.Subject, name, Thinktecture.IdentityServer.Core.Constants.AuthenticationMethods.External, user.Provider ); return(Task.FromResult <AuthenticateResult>(new AuthenticateResult(p))); } else { // user not registered so we will issue a partial login and redirect them to our registration page var p = IdentityServerPrincipal.Create( user.Subject, name, Thinktecture.IdentityServer.Core.Constants.AuthenticationMethods.External, user.Provider ); return(Task.FromResult <AuthenticateResult>(new AuthenticateResult("/core/externalregistration", p))); } }
public Task <AuthenticateResult> AuthenticateExternalAsync(ExternalIdentity externalUser) { // look for the user in our local identity system from the external identifiers var user = Users.SingleOrDefault(x => x.Provider == externalUser.Provider && x.ProviderID == externalUser.ProviderId); if (user == null) { // user is not registered so redirect return(Task.FromResult <AuthenticateResult>(new AuthenticateResult("/core/registerfirstexternalregistration", externalUser))); } // user is registered so continue var name = user.Claims.First(x => x.Type == Constants.ClaimTypes.Name).Value; return(Task.FromResult <AuthenticateResult>(new AuthenticateResult(user.Subject, name, identityProvider: user.Provider))); }
private static IEnumerable <UserClaim> GetProfileClaimsFromIdentity(ExternalIdentity externalIdentity, User newUser) { return(externalIdentity .Claims.Where(c => c.Type.ToLowerInvariant() == Constants.ClaimTypes.GivenName || c.Type.ToLowerInvariant() == Constants.ClaimTypes.FamilyName || c.Type.ToLowerInvariant() == Constants.ClaimTypes.Email) .Select(c => new UserClaim { Id = Guid.NewGuid().ToString(), Subject = newUser.Subject, ClaimType = c.Type.ToLowerInvariant(), ClaimValue = c.Value })); }
public static void RaiseExternalLoginFailureEvent(this IEventService events, ExternalIdentity externalIdentity, string signInMessageId, SignInMessage signInMessage, string details) { var evt = new Event <ExternalLoginDetails>( EventConstants.Categories.Authentication, Resources.Events.ExternalLoginFailure, EventTypes.Failure, EventConstants.Ids.ExternalLoginFailure, new ExternalLoginDetails { SignInId = signInMessageId, SignInMessage = signInMessage, Provider = externalIdentity.Provider, ProviderId = externalIdentity.ProviderId, }); events.RaiseEvent(evt); }
protected void Page_Load(object sender, EventArgs e) { LabelError.Text = ""; LabelChars.Visible = false; LabelBadPw.Visible = false; LabelMatch.Visible = false; LabelOccupied.Visible = false; if (!IsPostBack) { ExternalIdentity extID = null; try { extID = ExternalIdentity.FromPersonIdAndType(_currentUser.Identity, ExternalIdentityType.PPXMPPAccount); TextBoxJabberID.Text = extID.UserID.Split('@')[0]; } catch { } } }
public virtual async Task <AuthenticateResult> AuthenticateExternalAsync(ExternalIdentity externalUser, SignInMessage message) { if (externalUser == null) { throw new ArgumentNullException("externalUser"); } var user = await userManager.FindAsync(new UserLoginInfo(externalUser.Provider, externalUser.ProviderId)); if (user == null) { return(await ProcessNewExternalAccountAsync(externalUser.Provider, externalUser.ProviderId, externalUser.Claims)); } else { return(await ProcessExistingExternalAccountAsync(user.Id, externalUser.Provider, externalUser.ProviderId, externalUser.Claims)); } }
public static async Task RaiseExternalLoginFailureEventAsync(this IEventService events, ExternalIdentity externalIdentity, string signInMessageId, SignInRequest signInRequest, string error) { var evt = new Event <ExternalLoginDetails>( EventConstants.Categories.Authentication, "External Login Failure", EventTypes.Failure, EventConstants.Ids.ExternalLoginFailure, new ExternalLoginDetails { SignInId = signInMessageId, SignInRequest = signInRequest, Provider = externalIdentity.Provider, ProviderId = externalIdentity.ProviderId, }, error); await events.RaiseEventAsync(evt); }
/// <summary> /// External: The user has logged in on some other site /// Either we are supplied a new identity, in which case we add it to our user store /// Or we are supplied an existing identity, in which case we return the claims for this user /// </summary> /// <param name="identity"></param> /// <param name="signInData"></param> /// <returns></returns> public async Task <AuthenticationResult> AuthenticateExternalAsync(ExternalIdentity identity, SignInData signInData) { //There must be an identity for this to make sense if (identity == null) { throw new ArgumentNullException("identity"); } //The user manager tries to find a matching user var user = await manager.FindAsync(new Microsoft.AspNet.Identity.UserLoginInfo(identity.Provider, identity.ProviderId)); if (user == null) { //Create a new account return(await ProcessNewExternalAccountAsync(identity.Provider, identity.ProviderId, identity.Claims)); } else { return(await ProcessExistingExternalAccountAsync(user.Id, identity.Provider, identity.ProviderId, identity.Claims)); } }
public static async Task RaiseExternalLoginSuccessEventAsync(this IEventService events, ExternalIdentity externalIdentity, string signInMessageId, SignInMessage signInMessage, AuthenticateResult authResult) { var evt = new Event <ExternalLoginDetails>( EventConstants.Categories.Authentication, Resources.Events.ExternalLoginSuccess, EventTypes.Success, EventConstants.Ids.ExternalLoginSuccess, new ExternalLoginDetails { SubjectId = authResult.HasSubject ? authResult.User.GetSubjectId() : null, Name = authResult.User.Identity.Name, SignInId = signInMessageId, SignInMessage = signInMessage, PartialLogin = authResult.IsPartialSignIn, Provider = externalIdentity.Provider, ProviderId = externalIdentity.ProviderId, }); await events.RaiseEventAsync(evt); }
public static ExternalIdentity CreateIdentity(this FirebaseToken payload) { if (payload == null) { throw new ArgumentNullException(nameof(FirebaseToken)); } var claims = payload.Claims; var nameParts = (payload.Claims["name"] as string).Split(' '); var identity = new ExternalIdentity() { FirstName = nameParts[0], LastName = nameParts[1], ProviderKey = payload.Subject, Email = claims["email"] as string, EmailConfirmed = (bool)claims["email_verified"], SignInProvider = (claims["firebase"] as JToken)["sign_in_provider"].Value <string>() }; return(identity); }
public async Task <IActionResult> Login([FromQuery] string returnUrl = null) { var context = await interaction.GetAuthorizationContextAsync(returnUrl); if (context != null) { string idToken = context.Parameters.Get("id_token"); FirebaseToken payload = await isGoogleIdTokenValid(idToken); if (payload != null) { ExternalIdentity firebaseIdentity = payload.CreateIdentity(); ApplicationUser user = await userManager.FindByNameAsync(firebaseIdentity.Email); if (user == null) { return(await externalSignUpAsync( firebaseIdentity, context.Parameters.Get("role").ToLower(), returnUrl )); } else { return(await externalSignInAsync( user, firebaseIdentity, returnUrl )); } } return(BadRequest(new ValidationError( ErrorType.UnexpectedError, "The account has not yet been confirmied or invalid id_token provided!" ))); } return(LocalRedirect("~/")); }
private static ExternalIdentity BuildExternalIdentity(Saml2Response token) { var claimsIdentities = SamlTokenHandling.GetClaimsIdentities(token); // This will trigger the validation of the token // Very unsafe - this is POC code!! var nameIdClaim = claimsIdentities.First() .Claims.First(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"); var externalIdentity = new ExternalIdentity() { Provider = token.Issuer.Id, ProviderId = nameIdClaim.Value, Claims = new List <Claim>() { new Claim(Constants.ClaimTypes.Name, "Billy Bob"), new Claim(Constants.ClaimTypes.Role, "Boss") } }; return(externalIdentity); }
private async Task <IActionResult> externalSignInAsync( ApplicationUser user, ExternalIdentity firebaseIdentity, string returnUrl ) { IEnumerable <UserLoginInfo> logins = await userManager.GetLoginsAsync(user); IdentityResult identityResult = null; if (!logins.Any(ui => ui.ProviderKey == firebaseIdentity.ProviderKey)) { identityResult = await userManager.AddLoginAsync( user, new UserLoginInfo( firebaseIdentity.SignInProvider, firebaseIdentity.ProviderKey, firebaseIdentity.SignInProvider ) ); } if (identityResult == null || identityResult.Succeeded) { return(SignResult( await signInManager.ExternalLoginSignInAsync( firebaseIdentity.SignInProvider, firebaseIdentity.ProviderKey, true ), returnUrl )); } AddErrors(identityResult); return(BadRequest(new ApiError(ModelState))); }
public AuthenticateResult(string redirectPath, ExternalIdentity externalId) { if (redirectPath.IsMissing()) { throw new ArgumentNullException("redirectPath"); } if (!redirectPath.StartsWith("~/") && !redirectPath.StartsWith("/")) { throw new ArgumentException("redirectPath must start with / or ~/"); } if (externalId == null) { throw new ArgumentNullException("externalId"); } this.PartialSignInRedirectPath = redirectPath; var id = new ClaimsIdentity(externalId.Claims, Constants.PartialSignInAuthenticationType); // we're keeping the external provider info for the partial signin so we can re-execute AuthenticateExternalAsync // once the user is re-directed back into identityserver from the external redirect id.AddClaim(new Claim(Constants.ClaimTypes.ExternalProviderUserId, externalId.ProviderId, ClaimValueTypes.String, externalId.Provider.Name)); User = new ClaimsPrincipal(id); }
public virtual async Task <AuthenticateResult> AuthenticateExternalAsync(ExternalIdentity externalUser) { if (externalUser == null) { throw new ArgumentNullException("externalUser"); } try { var acct = this.userAccountService.GetByLinkedAccount(externalUser.Provider.Name, externalUser.ProviderId); if (acct == null) { return(await ProcessNewExternalAccountAsync(externalUser.Provider.Name, externalUser.ProviderId, externalUser.Claims)); } else { return(await ProcessExistingExternalAccountAsync(acct.ID, externalUser.Provider.Name, externalUser.ProviderId, externalUser.Claims)); } } catch (ValidationException ex) { return(new AuthenticateResult(ex.Message)); } }
private static User ConfigureNewUser(ExternalIdentity externalIdentity) { var newUser = new User { Subject = Guid.NewGuid().ToString(), IsActive = true }; var userLogin = new UserLogin { Subject = newUser.Subject, LoginProvider = externalIdentity.Provider, ProviderKey = externalIdentity.ProviderId }; newUser.UserLogins.Add(userLogin); GetProfileClaimsFromIdentity(externalIdentity, newUser) .Union(CreateBasicPrivilegeForNewUser(newUser)) .ToList() .ForEach(newUser.UserClaims.Add); return(newUser); }