private IHttpActionResult SignInAndRedirect(SignInMessage signInMessage, string signInMessageId, AuthenticateResult authResult, bool?rememberMe = null) { IssueAuthenticationCookie(signInMessage, signInMessageId, authResult, rememberMe); var redirectUrl = GetRedirectUrl(signInMessage, authResult); Logger.InfoFormat("redirecting to: {0}", redirectUrl); return(Redirect(redirectUrl)); }
private void IssueAuthenticationCookie(SignInMessage signInMessage, string signInMessageId, AuthenticateResult authResult, bool?rememberMe = null) { if (signInMessage == null) { throw new ArgumentNullException("signInId"); } if (authResult == null) { throw new ArgumentNullException("authResult"); } Logger.InfoFormat("issuing cookie{0}", authResult.IsPartialSignIn ? " (partial login)" : ""); var props = new Microsoft.Owin.Security.AuthenticationProperties(); var id = authResult.User.Identities.First(); if (authResult.IsPartialSignIn) { // add claim so partial redirect can return here to continue login // we need a random ID to resume, and this will be the query string // to match a claim added. the claim added will be the original // signIn ID. var resumeId = Guid.NewGuid().ToString("N"); var resumeLoginUrl = Url.Link(Constants.RouteNames.ResumeLoginFromRedirect, new { resume = resumeId }); var resumeLoginClaim = new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, resumeLoginUrl); id.AddClaim(resumeLoginClaim); id.AddClaim(new Claim(GetClaimTypeForResumeId(resumeId), signInMessageId)); } else { ClearSignInCookie(signInMessageId); } if (!authResult.IsPartialSignIn) { // don't issue persistnt cookie if it's a partial signin if (rememberMe == true || (rememberMe != false && this._options.AuthenticationOptions.CookieOptions.IsPersistent)) { // only issue persistent cookie if user consents (rememberMe == true) or // if server is configured to issue persistent cookies and user has not explicitly // denied the rememberMe (false) // if rememberMe is null, then user was not prompted for rememberMe props.IsPersistent = true; if (rememberMe == true) { var expires = DateTime.UtcNow.Add(_options.AuthenticationOptions.CookieOptions.RememberMeDuration); props.ExpiresUtc = new DateTimeOffset(expires); } } } ClearAuthenticationCookies(); var ctx = Request.GetOwinContext(); ctx.Authentication.SignIn(props, id); }
public async Task <IHttpActionResult> ResumeLoginFromRedirect(string resume) { Logger.Info("Callback requested to resume login from partial login"); if (resume.IsMissing()) { Logger.Error("no resumeId passed"); return(RenderErrorPage()); } var user = await GetIdentityFromPartialSignIn(); if (user == null) { Logger.Error("no identity from partial login"); return(RenderErrorPage()); } var type = GetClaimTypeForResumeId(resume); var resumeClaim = user.FindFirst(type); if (resumeClaim == null) { Logger.Error("no claim matching resumeId"); return(RenderErrorPage()); } var signInId = resumeClaim.Value; if (signInId.IsMissing()) { Logger.Error("No signin id found in resume claim"); 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()); } AuthenticateResult result = null; var externalProviderClaim = user.FindFirst(Constants.ClaimTypes.ExternalProviderUserId); if (externalProviderClaim == null) { // the user/subject was known, so pass thru (without the redirect claims) user.RemoveClaim(user.FindFirst(Constants.ClaimTypes.PartialLoginReturnUrl)); user.RemoveClaim(user.FindFirst(GetClaimTypeForResumeId(resume))); result = new AuthenticateResult(new ClaimsPrincipal(user)); } else { // the user was not known, we need to re-execute AuthenticateExternalAsync // to obtain a subject to proceed var provider = externalProviderClaim.Issuer; var providerId = externalProviderClaim.Value; var externalId = new ExternalIdentity() { Provider = new IdentityProvider { Name = provider }, ProviderId = providerId, Claims = user.Claims }; result = await _userService.AuthenticateExternalAsync(externalId); if (result == null) { Logger.Warn("user service failed to authenticate external identity"); return(await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount)); } if (result.IsError) { Logger.WarnFormat("user service returned error message: {0}", result.ErrorMessage); return(await RenderLoginPage(signInMessage, signInId, result.ErrorMessage)); } } return(SignInAndRedirect(signInMessage, signInId, result)); }