public void Execute(AuthFilterContext authContext)
        {
            var session     = authContext.Session;
            var authService = authContext.AuthService;

            var shouldReturnTokens = authContext.DidAuthenticate;

            if (shouldReturnTokens && SetBearerTokenOnAuthenticateResponse && authContext.AuthResponse.BearerToken == null && session.IsAuthenticated)
            {
                if (!RequireSecureConnection || authService.Request.IsSecureConnection)
                {
                    IEnumerable <string> roles = null, perms = null;
                    if (HostContext.AppHost.GetAuthRepository(authService.Request) is IManageRoles authRepo && session.UserAuthId != null)
                    {
                        roles = authRepo.GetRoles(session.UserAuthId);
                        perms = authRepo.GetPermissions(session.UserAuthId);
                    }

                    authContext.AuthResponse.BearerToken  = CreateJwtBearerToken(authContext.AuthService.Request, session, roles, perms);
                    authContext.AuthResponse.RefreshToken = EnableRefreshToken()
                        ? CreateJwtRefreshToken(authService.Request, session.UserAuthId, ExpireRefreshTokensIn)
                        : null;
                }
            }
        }
        public async Task ExecuteAsync(AuthFilterContext authContext)
        {
            var session     = authContext.Session;
            var authService = authContext.AuthService;

            var shouldReturnTokens = authContext.DidAuthenticate;

            if (shouldReturnTokens && SetBearerTokenOnAuthenticateResponse && authContext.AuthResponse.BearerToken == null && session.IsAuthenticated)
            {
                if (!RequireSecureConnection || authService.Request.IsSecureConnection)
                {
                    IEnumerable <string> roles = null, perms = null;
                    var userRepo = HostContext.AppHost.GetAuthRepositoryAsync(authService.Request);
                    await using (userRepo as IAsyncDisposable)
                    {
                        if (userRepo is IManageRolesAsync manageRoles)
                        {
                            var tuple = await manageRoles.GetRolesAndPermissionsAsync(session.UserAuthId).ConfigAwait();

                            roles = tuple.Item1;
                            perms = tuple.Item2;
                        }
                    }

                    authContext.AuthResponse.BearerToken  = CreateJwtBearerToken(authContext.AuthService.Request, session, roles, perms);
                    authContext.AuthResponse.RefreshToken = EnableRefreshToken()
                        ? CreateJwtRefreshToken(authService.Request, session.UserAuthId, ExpireRefreshTokensIn)
                        : null;
                }
            }
        }
        public void Execute(AuthFilterContext authContext)
        {
            var session     = authContext.Session;
            var authService = authContext.AuthService;

            if (SetBearerTokenOnAuthenticateResponse && authContext.AuthResponse.BearerToken == null && session.IsAuthenticated)
            {
                if (!RequireSecureConnection || authService.Request.IsSecureConnection)
                {
                    IEnumerable <string> roles = null, perms = null;
                    var authRepo = HostContext.AppHost.GetAuthRepository(authService.Request) as IManageRoles;
                    if (authRepo != null && session.UserAuthId != null)
                    {
                        roles = authRepo.GetRoles(session.UserAuthId);
                        perms = authRepo.GetPermissions(session.UserAuthId);
                    }

                    authContext.AuthResponse.BearerToken = CreateJwtBearerToken(session, roles, perms);
                }
            }
        }
        public object AuthenticateResponseDecorator(AuthFilterContext authCtx)
        {
            if (authCtx.AuthResponse.BearerToken == null || authCtx.AuthRequest.UseTokenCookie != true)
            {
                return(authCtx.AuthResponse);
            }

            authCtx.AuthService.Request.RemoveSession(authCtx.AuthService.GetSessionId());

            return(new HttpResult(authCtx.AuthResponse)
            {
                Cookies =
                {
                    new Cookie(Keywords.TokenCookie, authCtx.AuthResponse.BearerToken, Cookies.RootPath)
                    {
                        HttpOnly = true,
                        Secure = authCtx.AuthService.Request.IsSecureConnection,
                        Expires = DateTime.UtcNow.Add(ExpireTokensIn),
                    }
                }
            });
        }
        public object Post(Authenticate request)
        {
            AssertAuthProviders();

            if (ValidateFn != null)
            {
                var validationResponse = ValidateFn(this, Request.Verb, request);
                if (validationResponse != null)
                {
                    return(validationResponse);
                }
            }

            if (request.RememberMe.HasValue)
            {
                var opt = request.RememberMe.GetValueOrDefault(false)
                    ? SessionOptions.Permanent
                    : SessionOptions.Temporary;

                base.Request.AddSessionOptions(opt);
            }

            var provider = request.provider ?? AuthProviders[0].Provider;

            if (provider == CredentialsAliasProvider)
            {
                provider = CredentialsProvider;
            }

            var authProvider = GetAuthProvider(provider);

            if (authProvider == null)
            {
                throw HttpError.NotFound(ErrorMessages.UnknownAuthProviderFmt.Fmt(provider.SafeInput()));
            }

            if (LogoutAction.EqualsIgnoreCase(request.provider))
            {
                return(authProvider.Logout(this, request));
            }

            if (authProvider is IAuthWithRequest && !base.Request.IsInProcessRequest())
            {
                //IAuthWithRequest normally doesn't call Authenticate directly, but they can to return Auth Info
                //But as AuthenticateService doesn't have [Authenticate] we need to call it manually
                new AuthenticateAttribute().ExecuteAsync(base.Request, base.Response, request).Wait();
                if (base.Response.IsClosed)
                {
                    return(null);
                }
            }

            var session = this.GetSession();

            var isHtml = base.Request.ResponseContentType.MatchesContentType(MimeTypes.Html);

            try
            {
                var response = Authenticate(request, provider, session, authProvider);

                // The above Authenticate call may end an existing session and create a new one so we need
                // to refresh the current session reference.
                session = this.GetSession();

                if (request.provider == null && !session.IsAuthenticated)
                {
                    throw HttpError.Unauthorized(ErrorMessages.NotAuthenticated.Localize(Request));
                }

                var referrerUrl = request.Continue
                                  ?? session.ReferrerUrl
                                  ?? this.Request.GetHeader(HttpHeaders.Referer)
                                  ?? authProvider.CallbackUrl;

                var alreadyAuthenticated = response == null;
                response = response ?? new AuthenticateResponse {
                    UserId      = session.UserAuthId,
                    UserName    = session.UserAuthName,
                    DisplayName = session.DisplayName
                                  ?? session.UserName
                                  ?? $"{session.FirstName} {session.LastName}".Trim(),
                    SessionId   = session.Id,
                    ReferrerUrl = referrerUrl,
                };

                if (response is AuthenticateResponse authResponse)
                {
                    var authCtx = new AuthFilterContext {
                        AuthService          = this,
                        AuthProvider         = authProvider,
                        AuthRequest          = request,
                        AuthResponse         = authResponse,
                        Session              = session,
                        AlreadyAuthenticated = alreadyAuthenticated,
                        DidAuthenticate      = Request.Items.ContainsKey(Keywords.DidAuthenticate),
                    };

                    foreach (var responseFilter in AuthResponseFilters)
                    {
                        responseFilter.Execute(authCtx);
                    }

                    if (AuthResponseDecorator != null)
                    {
                        return(AuthResponseDecorator(authCtx));
                    }
                }

                if (isHtml && request.provider != null)
                {
                    if (alreadyAuthenticated)
                    {
                        return(this.Redirect(referrerUrl.SetParam("s", "0")));
                    }

                    if (!(response is IHttpResult) && !string.IsNullOrEmpty(referrerUrl))
                    {
                        return(new HttpResult(response)
                        {
                            Location = referrerUrl
                        });
                    }
                }

                return(response);
            }
            catch (HttpError ex)
            {
                var errorReferrerUrl = this.Request.GetHeader(HttpHeaders.Referer);
                if (isHtml && errorReferrerUrl != null)
                {
                    errorReferrerUrl = errorReferrerUrl.SetParam("f", ex.Message.Localize(Request));
                    return(HttpResult.Redirect(errorReferrerUrl));
                }

                throw;
            }
        }
        public object Post(Authenticate request)
        {
            AssertAuthProviders();

            if (ValidateFn != null)
            {
                var validationResponse = ValidateFn(this, Request.Verb, request);
                if (validationResponse != null)
                {
                    return(validationResponse);
                }
            }

            var authFeature = GetPlugin <AuthFeature>();

            if (request.RememberMe.HasValue)
            {
                var opt = request.RememberMe.GetValueOrDefault(false)
                    ? SessionOptions.Permanent
                    : SessionOptions.Temporary;

                base.Request.AddSessionOptions(opt);
            }

            var provider = request.provider ?? AuthProviders[0].Provider;

            if (provider == CredentialsAliasProvider)
            {
                provider = CredentialsProvider;
            }

            var authProvider = GetAuthProvider(provider);

            if (authProvider == null)
            {
                throw HttpError.NotFound(ErrorMessages.UnknownAuthProviderFmt.Fmt(provider.SafeInput()));
            }

            if (LogoutAction.EqualsIgnoreCase(request.provider))
            {
                return(authProvider.Logout(this, request));
            }

            if (authProvider is IAuthWithRequest && !base.Request.IsInProcessRequest())
            {
                //IAuthWithRequest normally doesn't call Authenticate directly, but they can to return Auth Info
                //But as AuthenticateService doesn't have [Authenticate] we need to call it manually
                new AuthenticateAttribute().ExecuteAsync(base.Request, base.Response, request).Wait();
                if (base.Response.IsClosed)
                {
                    return(null);
                }
            }

            var session = this.GetSession();

            var isHtml = base.Request.ResponseContentType.MatchesContentType(MimeTypes.Html);

            try
            {
                var response = Authenticate(request, provider, session, authProvider);

                // The above Authenticate call may end an existing session and create a new one so we need
                // to refresh the current session reference.
                session = this.GetSession();

                if (request.provider == null && !session.IsAuthenticated)
                {
                    throw HttpError.Unauthorized(ErrorMessages.NotAuthenticated.Localize(Request));
                }

                var returnUrl   = Request.GetReturnUrl();
                var referrerUrl = returnUrl
                                  ?? session.ReferrerUrl
                                  ?? base.Request.GetQueryStringOrForm(Keywords.ReturnUrl)
                                  ?? this.Request.GetHeader(HttpHeaders.Referer)
                                  ?? authProvider.CallbackUrl;

                if (authFeature != null)
                {
                    if (!string.IsNullOrEmpty(returnUrl))
                    {
                        authFeature.ValidateRedirectLinks(Request, referrerUrl);
                    }
                }

                var manageRoles = AuthRepository as IManageRoles;

                var alreadyAuthenticated = response == null;
                response ??= new AuthenticateResponse {
                    UserId      = session.UserAuthId,
                    UserName    = session.UserAuthName,
                    DisplayName = session.DisplayName
                                  ?? session.UserName
                                  ?? $"{session.FirstName} {session.LastName}".Trim(),
                    SessionId   = session.Id,
                    ReferrerUrl = referrerUrl,
                };

                if (response is AuthenticateResponse authResponse)
                {
                    authResponse.ProfileUrl ??= session.GetProfileUrl();

                    if (session.UserAuthId != null && authFeature != null)
                    {
                        if (authFeature.IncludeRolesInAuthenticateResponse)
                        {
                            var authSession = authFeature.AuthSecretSession;
                            if (authSession != null && session.UserAuthName == authSession.UserAuthName && session.UserAuthId == authSession.UserAuthId)
                            {
                                authResponse.Roles       = session.Roles;
                                authResponse.Permissions = session.Permissions;
                            }

                            authResponse.Roles ??= (manageRoles != null
                                ? manageRoles.GetRoles(session.UserAuthId)?.ToList()
                                : session.Roles);
                            authResponse.Permissions ??= (manageRoles != null
                                ? manageRoles.GetPermissions(session.UserAuthId)?.ToList()
                                : session.Permissions);
                        }
                        if (authFeature.IncludeOAuthTokensInAuthenticateResponse && AuthRepository != null)
                        {
                            var authDetails = AuthRepository.GetUserAuthDetails(session.UserAuthId);
                            if (authDetails?.Count > 0)
                            {
                                authResponse.Meta ??= new Dictionary <string, string>();
                                foreach (var authDetail in authDetails.Where(x => x.AccessTokenSecret != null))
                                {
                                    authResponse.Meta[authDetail.Provider + "-tokens"] = authDetail.AccessTokenSecret +
                                                                                         (authDetail.AccessToken != null ? ':' + authDetail.AccessToken : "");
                                }
                            }
                        }
                    }

                    var authCtx = new AuthFilterContext {
                        AuthService          = this,
                        AuthProvider         = authProvider,
                        AuthRequest          = request,
                        AuthResponse         = authResponse,
                        ReferrerUrl          = referrerUrl,
                        Session              = session,
                        AlreadyAuthenticated = alreadyAuthenticated,
                        DidAuthenticate      = Request.Items.ContainsKey(Keywords.DidAuthenticate),
                    };

                    foreach (var responseFilter in AuthResponseFilters)
                    {
                        responseFilter.Execute(authCtx);
                    }

                    if (AuthResponseDecorator != null)
                    {
                        var authDecoratorResponse = AuthResponseDecorator(authCtx);
                        if (authDecoratorResponse != response)
                        {
                            return(authDecoratorResponse);
                        }
                    }
                }

                if (isHtml && request.provider != null)
                {
                    if (alreadyAuthenticated)
                    {
                        return(this.Redirect(referrerUrl.SetParam("s", "0")));
                    }

                    if (!(response is IHttpResult) && !string.IsNullOrEmpty(referrerUrl))
                    {
                        return(new HttpResult(response)
                        {
                            Location = referrerUrl
                        });
                    }
                }

                return(response);
            }
            catch (Exception ex)
            {
                if (isHtml && Request.GetErrorView() != null)
                {
                    return(ex);
                }

                if (ex is HttpError)
                {
                    var errorReferrerUrl = this.Request.GetReturnUrl() ?? this.Request.GetHeader(HttpHeaders.Referer);
                    if (isHtml && errorReferrerUrl != null && Request.GetParam(Keywords.NoRedirect) == null)
                    {
                        errorReferrerUrl = errorReferrerUrl.SetParam("f", ex.Message.Localize(Request));
                        return(HttpResult.Redirect(errorReferrerUrl));
                    }
                }

                throw;
            }
        }