예제 #1
0
        public Task <bool> InvokeAsync(IDictionary <string, object> environment)
        {
            IOwinEnvironment context = new DefaultOwinEnvironment(environment);
            var client               = environment.Get <IClient>(OwinKeys.StormpathClient);
            var configuration        = environment.Get <StormpathConfiguration>(OwinKeys.StormpathConfiguration);
            var authenticatedUser    = environment.Get <IAccount>(OwinKeys.StormpathUser);
            var authenticationScheme = environment.Get <string>(OwinKeys.StormpathUserScheme);

            var deleteCookieAction  = new Action <WebCookieConfiguration>(cookie => Cookies.DeleteTokenCookie(context, cookie, logger));
            var setStatusCodeAction = new Action <int>(code => context.Response.StatusCode = code);
            var setHeaderAction     = new Action <string, string>((name, value) => context.Response.Headers.SetString(name, value));
            var redirectAction      = new Action <string>(location => context.Response.Headers.SetString("Location", location));

            var handler = new RouteProtector(
                client,
                configuration,
                deleteCookieAction,
                setStatusCodeAction,
                setHeaderAction,
                redirectAction,
                logger);

            if (handler.IsAuthenticated(authenticationScheme, RouteProtector.AnyScheme, authenticatedUser))
            {
                return(TaskConstants.CompletedTask); // Authentication check succeeded
            }

            logger.Info("User attempted to access a protected endpoint with invalid credentials.");

            handler.OnUnauthorized(context.Request.Headers.GetString("Accept"), context.Request.Path);
            return(Task.FromResult(false)); // Authentication check failed
        }
 private void DeleteCookies(IOwinEnvironment context, CookieParser cookieParser)
 {
     Cookies.DeleteTokenCookie(context, _configuration.Web.AccessTokenCookie, _logger);
     Cookies.DeleteTokenCookie(context, _configuration.Web.RefreshTokenCookie, _logger);
 }
        private async Task <IAccount> TryCookieAuthenticationAsync(IOwinEnvironment context, IClient client)
        {
            string[] rawCookies = null;

            if (!context.Request.Headers.TryGetValue("Cookie", out rawCookies))
            {
                logger.Trace("No cookie header found", nameof(TryCookieAuthenticationAsync));
                return(null);
            }

            var cookieParser = new CookieParser(rawCookies, logger);

            if (cookieParser.Count == 0)
            {
                logger.Trace("No cookies parsed from header", nameof(TryCookieAuthenticationAsync));
                return(null);
            }

            logger.Trace("Cookies found on request: " + cookieParser.AsEnumerable().Select(x => $"'{x.Key}'").Join(", "), nameof(TryCookieAuthenticationAsync));

            var accessToken  = cookieParser.Get(this.Configuration.Web.AccessTokenCookie.Name);
            var refreshToken = cookieParser.Get(this.Configuration.Web.RefreshTokenCookie.Name);

            // Attempt to validate incoming Access Token
            if (!string.IsNullOrEmpty(accessToken))
            {
                logger.Trace($"Found nonempty access token cookie '{this.Configuration.Web.AccessTokenCookie.Name}'", nameof(TryCookieAuthenticationAsync));

                var validAccount = await ValidateAccessTokenAsync(context, client, accessToken);

                if (validAccount != null)
                {
                    logger.Info("Request authenticated using Access Token cookie", nameof(TryCookieAuthenticationAsync));
                    return(validAccount);
                }
                else
                {
                    logger.Info("Access token cookie was not valid", nameof(TryCookieAuthenticationAsync));
                }
            }

            // Try using refresh token instead
            if (!string.IsNullOrEmpty(refreshToken))
            {
                logger.Trace($"Found nonempty refresh token cookie '{this.Configuration.Web.RefreshTokenCookie.Name}'", nameof(TryCookieAuthenticationAsync));

                var refreshedAccount = await RefreshAccessTokenAsync(context, client, refreshToken);

                if (refreshedAccount != null)
                {
                    logger.Info("Request authenticated using Refresh Token cookie", nameof(TryCookieAuthenticationAsync));
                    return(refreshedAccount);
                }
                else
                {
                    logger.Info("Refresh token cookie was not valid", nameof(TryCookieAuthenticationAsync));
                }
            }

            // Failed on both counts. Delete access and refresh token cookies if necessary
            if (cookieParser.Contains(this.Configuration.Web.AccessTokenCookie.Name))
            {
                Cookies.DeleteTokenCookie(context, this.Configuration.Web.AccessTokenCookie, logger);
            }
            if (cookieParser.Contains(this.Configuration.Web.RefreshTokenCookie.Name))
            {
                Cookies.DeleteTokenCookie(context, this.Configuration.Web.RefreshTokenCookie, logger);
            }

            logger.Info("No access or refresh token cookies found", nameof(TryCookieAuthenticationAsync));
            return(null);
        }