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

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

            if (signin.Length > MaxInputParamLength)
            {
                Logger.Error("Signin parameter passed was larger than max length");
                return(RenderErrorPage());
            }

            var signInMessage = signInMessageCookie.Read(signin);

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

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

            var authResult = await userService.PreAuthenticateAsync(signInMessage);

            if (authResult != null)
            {
                if (authResult.IsError)
                {
                    Logger.WarnFormat("user service returned an error message: {0}", authResult.ErrorMessage);

                    eventService.RaisePreLoginFailureEvent(signin, signInMessage, authResult.ErrorMessage);

                    return(RenderErrorPage(authResult.ErrorMessage));
                }

                Logger.Info("user service returned a login result");

                eventService.RaisePreLoginSuccessEvent(signin, signInMessage, authResult);

                return(SignInAndRedirect(signInMessage, signin, authResult));
            }

            if (signInMessage.IdP.IsPresent())
            {
                Logger.InfoFormat("identity provider requested, redirecting to: {0}", signInMessage.IdP);
                return(Redirect(context.GetExternalProviderLoginUrl(signInMessage.IdP, signin)));
            }

            return(await RenderLoginPage(signInMessage, signin));
        }
        internal static IEnumerable <LoginPageLink> GetLinksFromProviders(this IOwinContext context, IEnumerable <AuthenticationDescription> types, string signInMessageId)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (types != null)
            {
                return(types.Select(p => new LoginPageLink
                {
                    Text = p.Caption,
                    Href = context.GetExternalProviderLoginUrl(p.AuthenticationType, signInMessageId)
                }));
            }

            return(Enumerable.Empty <LoginPageLink>());
        }