public async Task <IHttpActionResult> Login(string signin)
        {
            Logger.Info("Login page requested");

            if (signin.IsMissing())
            {
                Logger.Error("No signin id passed");
                return(RenderErrorPage());
            }

            var cookie        = new SignInMessageCookie(Request.GetOwinContext(), this._options);
            var signInMessage = cookie.Read(signin);

            if (signInMessage == null)
            {
                Logger.Error("No cookie matching signin id found");
                return(RenderErrorPage());
            }

            Logger.DebugFormat("signin message passed to login: {0}", JsonConvert.SerializeObject(signInMessage, Formatting.Indented));

            if (signInMessage.IdP.IsPresent())
            {
                Logger.InfoFormat("identity provider requested, redirecting to: {0}", signInMessage.IdP);
                return(Redirect(Url.Link(Constants.RouteNames.LoginExternal, new { provider = signInMessage.IdP, signin })));
            }

            return(await RenderLoginPage(signInMessage));
        }
        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 SignInMessageCookie(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, Messages.NoMatchingExternalAccount));
            }

            var externalIdentity = MapToExternalIdentity(user.Claims);

            if (externalIdentity == null)
            {
                Logger.Error("no subject or unique identifier claims from external identity provider");
                return(await RenderLoginPage(signInMessage, 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, Messages.NoMatchingExternalAccount));
            }

            if (authResult.IsError)
            {
                Logger.WarnFormat("user service returned error message: {0}", authResult.ErrorMessage);
                return(await RenderLoginPage(signInMessage, authResult.ErrorMessage));
            }

            return(SignInAndRedirect(signInMessage, authResult));
        }
Exemplo n.º 3
0
        private HttpResponseMessage Execute()
        {
            Logger.Info("Redirecting to login page");

            var cookie = new SignInMessageCookie(this.env, this.options);

            message.Id = Guid.NewGuid().ToString("N");
            cookie.Write(this.message);

            var url = env.GetIdentityServerBaseUrl() + Constants.RoutePaths.Login;

            url += "?signin=" + this.message.Id;

            var uri = new Uri(url);

            var response = new HttpResponseMessage(HttpStatusCode.Redirect);

            response.Headers.Location = uri;
            return(response);
        }
        public IHttpActionResult LoginExternal(string signin, string provider)
        {
            Logger.InfoFormat("External login requested for provider: {0}", provider);

            if (provider.IsMissing())
            {
                Logger.Error("No provider passed");
                return(RenderErrorPage());
            }

            if (signin.IsMissing())
            {
                Logger.Error("No signin id passed");
                return(RenderErrorPage());
            }

            var cookie        = new SignInMessageCookie(Request.GetOwinContext(), this._options);
            var signInMessage = cookie.Read(signin);

            if (signInMessage == null)
            {
                Logger.Error("No cookie matching signin id found");
                return(RenderErrorPage());
            }

            var ctx      = Request.GetOwinContext();
            var authProp = new Microsoft.Owin.Security.AuthenticationProperties
            {
                RedirectUri = Url.Route(Constants.RouteNames.LoginExternalCallback, null)
            };

            // add the id to the dictionary so we can recall the cookie id on the callback
            authProp.Dictionary.Add("signin", signin);
            Request.GetOwinContext().Authentication.Challenge(authProp, provider);
            return(Unauthorized());
        }
        public async Task <IHttpActionResult> LoginLocal(string signin, LoginCredentials model)
        {
            Logger.Info("Login page submitted");

            if (this._options.AuthenticationOptions.EnableLocalLogin == false)
            {
                Logger.Warn("EnableLocalLogin disabled -- returning 405 MethodNotAllowed");
                return(StatusCode(HttpStatusCode.MethodNotAllowed));
            }

            if (signin.IsMissing())
            {
                Logger.Error("No signin id passed");
                return(RenderErrorPage());
            }

            var cookie        = new SignInMessageCookie(Request.GetOwinContext(), this._options);
            var signInMessage = cookie.Read(signin);

            if (signInMessage == null)
            {
                Logger.Error("No cookie matching signin id found");
                return(RenderErrorPage());
            }

            if (model == null)
            {
                Logger.Error("no data submitted");
                return(await RenderLoginPage(signInMessage, Messages.InvalidUsernameOrPassword));
            }

            // the browser will only send 'true' if ther user has checked the checkbox
            // it will pass nothing if the user does not check the checkbox
            // this check here is to establish if the user deliberatly did not check the checkbox
            // or if the checkbox was not presented as an option (and thus AllowRememberMe is not allowed)
            // true means they did check it, false means they did not, null means they were not presented with the choice
            if (_options.AuthenticationOptions.CookieOptions.AllowRememberMe)
            {
                if (model.RememberMe != true)
                {
                    model.RememberMe = false;
                }
            }
            else
            {
                model.RememberMe = null;
            }

            if (!ModelState.IsValid)
            {
                Logger.Warn("validation error: username or password missing");
                return(await RenderLoginPage(signInMessage, ModelState.GetError(), model.Username, model.RememberMe == true));
            }

            var authResult = await _userService.AuthenticateLocalAsync(model.Username, model.Password, signInMessage);

            if (authResult == null)
            {
                Logger.WarnFormat("user service indicated incorrect username or password for username: {0}", model.Username);
                return(await RenderLoginPage(signInMessage, Messages.InvalidUsernameOrPassword, model.Username, model.RememberMe == true));
            }

            if (authResult.IsError)
            {
                Logger.WarnFormat("user service returned an error message: {0}", authResult.ErrorMessage);
                return(await RenderLoginPage(signInMessage, authResult.ErrorMessage, model.Username, model.RememberMe == true));
            }

            return(SignInAndRedirect(signInMessage, authResult, model.RememberMe));
        }
        private void ClearSignInCookie(string signin)
        {
            var cookie = new SignInMessageCookie(Request.GetOwinContext(), this._options);

            cookie.Clear(signin);
        }
        private void ClearSignInCookies()
        {
            var cookie = new SignInMessageCookie(Request.GetOwinContext(), this._options);

            cookie.ClearAll();
        }
        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 SignInMessageCookie(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, Messages.NoMatchingExternalAccount));
                }

                if (result.IsError)
                {
                    Logger.WarnFormat("user service returned error message: {0}", result.ErrorMessage);
                    return(await RenderLoginPage(signInMessage, result.ErrorMessage));
                }
            }

            return(SignInAndRedirect(signInMessage, result));
        }