protected async override Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            var options    = _optionsMonitor.Get(GithubAccessTokenDefaults.GITHUB_TOKEN_SCHEME);
            var headers    = Request.Headers;
            var authHeader = headers.FirstOrDefault(h => h.Key == "Authorization").Value.ToString();

            if (String.IsNullOrWhiteSpace(authHeader))
            {
                return(AuthenticateResult.Fail("Authentication header is null"));
            }
            var token       = authHeader.Split(' ')[1];
            var cacheTicket = null as AuthenticationTicket;

            if (_cache != null)
            {
                cacheTicket = _cache.GetTicket(token);
            }
            if (cacheTicket != null)
            {
                return(AuthenticateResult.Success(cacheTicket));
            }

            var tokenInfo = null as GithubTokenInfo;

            try
            {
                tokenInfo = await _githubClient.GetTokenInfo(options.ClientId, options.ClientSecret, options.AppName, token);

                if (options.RequiredScopes != null)
                {
                    if (!(tokenInfo.Scopes.Intersect(options.RequiredScopes).Count() == options.RequiredScopes.Count()))
                    {
                        return(AuthenticateResult.Fail("Token does not have all required scopes"));
                    }
                }
            }
            catch (TokenInfoException ex)
            {
                return(AuthenticateResult.Fail(ex.Message));
            }

            var identity = MapIdentity(tokenInfo, this.Scheme.Name);
            var ticket   = new AuthenticationTicket(new ClaimsPrincipal(identity), this.Scheme.Name);

            if (_cache != null)
            {
                _cache.SetTicket(token, ticket, DateTimeOffset.Now.AddMinutes(options.CacheMinutes));
            }
            return(AuthenticateResult.Success(ticket));
        }
Пример #2
0
        protected async override Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            var options    = _optionsMonitor.Get(GoogleAccessTokenDefaults.GOOGLE_TOKEN_SCHEME);
            var headers    = Request.Headers;
            var authHeader = headers.FirstOrDefault(h => h.Key == "Authorization").Value.ToString();

            if (String.IsNullOrWhiteSpace(authHeader))
            {
                return(AuthenticateResult.Fail("Authentication header is null"));
            }
            var token       = authHeader.Split(' ')[1];
            var cacheTicket = null as AuthenticationTicket;

            if (_cache != null)
            {
                cacheTicket = _cache.GetTicket(token);
            }
            if (cacheTicket != null)
            {
                var exp = long.Parse(cacheTicket.Principal.Claims.FirstOrDefault(c => c.Type == "exp_epoc").Value);
                if (exp < DateTimeOffset.Now.ToUnixTimeSeconds())
                {
                    return(AuthenticateResult.Fail("Token is expired"));
                }
                return(AuthenticateResult.Success(cacheTicket));
            }

            var            tokenInfo = null as GoogleTokenInfo;
            DateTimeOffset expires;
            var            expiresEpoc = null as long?;

            try
            {
                tokenInfo = await _googleClient.GetTokenInfo(token);

                expires     = DateTimeOffset.Now.AddSeconds(tokenInfo.ExpiresInSeconds - options.ExpieryWindowSeconds);
                expiresEpoc = expires.ToUnixTimeSeconds();
                if (expiresEpoc < DateTimeOffset.Now.ToUnixTimeSeconds())
                {
                    return(AuthenticateResult.Fail("Token is expired"));
                }
                if (options.OnlyAllowOfflineTokens && tokenInfo.AccessType != "offline")
                {
                    return(AuthenticateResult.Fail("AccessToken does not have offline access type"));
                }
                if (options.RequireCorrectClientId && tokenInfo.Aud != options.ClientId)
                {
                    return(AuthenticateResult.Fail("Audience in the token does not match the ClientId in the options"));
                }
                if (options.RequiredScopes != null)
                {
                    var scopes = tokenInfo.Scopes.Split(' ');
                    if (!(scopes.Intersect(options.RequiredScopes).Count() == options.RequiredScopes.Count()))
                    {
                        return(AuthenticateResult.Fail("Token does not have all required scopes"));
                    }
                }
                if (options.RequireVerifiedEmail == true)
                {
                    if (!tokenInfo.EmailVerified)
                    {
                        return(AuthenticateResult.Fail("Only verified emails are allowed"));
                    }
                }
            }
            catch (TokenInfoException ex)
            {
                return(AuthenticateResult.Fail(ex.Message));
            }

            var userInfo = null as GooglePeople;

            try
            {
                userInfo = await _googleClient.GetMe(token);
            }
            catch (UserInfoException ex)
            {
                return(AuthenticateResult.Fail(ex.Message));
            }

            var identity = MapIdentity(tokenInfo, userInfo, this.Scheme.Name, expiresEpoc);
            var ticket   = new AuthenticationTicket(new ClaimsPrincipal(identity), this.Scheme.Name);

            if (_cache != null)
            {
                _cache.SetTicket(token, ticket, expires);
            }
            return(AuthenticateResult.Success(ticket));
        }