コード例 #1
0
        async Task <Outcome <AuthorizedClient> > GetAuthorizedClientAsync(
            bool allowCached = true,
            CancellationToken?cancellationToken = null)
        {
            ActorToken token         = null;
            var        isTokenCached = false;

            if (allowCached)
            {
                var cachedOutcome = await _cache.GetHelloWorldToken();

                token         = cachedOutcome ? cachedOutcome.Value : null;
                isTokenCached = token is {};
            }

            if (token is null)
            {
                var tokenOutcome = await _credentialsService.AcquireTokenAsync(cancellationToken ?? new CancellationToken());

                if (!tokenOutcome)
                {
                    return(Outcome <AuthorizedClient> .Fail(tokenOutcome.Exception));
                }

                token = tokenOutcome.Value.Token;
            }

            var client = new HttpClient();

            client.DefaultRequestHeaders.Add(HeaderNames.Authorization, token);
            return(Outcome <AuthorizedClient> .Success(new AuthorizedClient(client, isTokenCached)));
        }
        async Task <Outcome <ActorToken> > getCachedIdentityTokenAsync(ActorToken accessToken)
        {
            if (AmbientData.Cache is null)
            {
                return(Outcome <ActorToken> .Fail(new Exception("Caching is not supported")));
            }

            return(await AmbientData.Cache.GetAsync <ActorToken>(IdentityTokenCache, accessToken));
        }
コード例 #3
0
ファイル: TokenService.cs プロジェクト: Harkole/FocusBoard
        /// <summary>
        /// Takes the Actor object, validates the properties and then retrieves
        /// the Authentication values from the repository, turning them in to a
        /// JWT token
        /// </summary>
        /// <param name="actor">The Actor object to validate</param>
        /// <param name="cancellationToken"></param>
        /// <returns>An <code>object</code> containing the token and expires_in values</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public async Task <ActorToken> GetClaimsIdentityAsync(ActorLogin actor, CancellationToken cancellationToken = default(CancellationToken))
        {
            ActorToken token = null;

            // Validate the Model, the results will be collected in the ICollection, but if everything is OK then isValid = true
            ICollection <ValidationResult> validationResults = new List <ValidationResult>();
            bool isValid = Validator.TryValidateObject(actor, new ValidationContext(actor), validationResults, true);

            if (isValid)
            {
                Authentication auth = await repository.GetClaimsValuesAsync(actor, cancellationToken);

                try
                {
                    if (null == auth)
                    {
                        // Get the generated token and encode it, then set as the return value
                        string encodedJwt = GenerateEncodedToken(auth);
                        token = new ActorToken {
                            Token = encodedJwt, ExpiresIn = (int)jwtOptions.ValidFor.TotalSeconds
                        };
                    }
                }
                catch (ArgumentException argEx) // Catches ArgumentNullException too
                {
                    // Reset the token response to null, any error is considered a security failure
                    token = null;

                    Trace.WriteLine(argEx.Message);
#if DEBUG
                    Trace.WriteLine(argEx.StackTrace);
#endif
                }
                catch (Microsoft.IdentityModel.Tokens.SecurityTokenCompressionFailedException tokenFailedEx)
                {
                    // The token may have been valid, but something went wrong so ensure the security fails
                    token = null;

                    Trace.WriteLine(tokenFailedEx.Message);
#if DEBUG
                    Trace.WriteLine(tokenFailedEx.StackTrace);
#endif
                }
            }
            else
            {
                // As each validation error will aggregated, loop over the results
                foreach (ValidationResult vr in validationResults)
                {
                    // Throw an exception for the first error, ignoring any others that are present
                    throw new ArgumentNullException(((string[])vr.MemberNames)[0], vr.ErrorMessage);
                }
            }

            // Return the Token object
            return(token);
        }
        protected override async Task <Outcome <ActorToken> > OnGetAccessTokenAsync(CancellationToken cancellationToken)
        {
            try
            {
                var accessTokenOutcome = await base.OnGetAccessTokenAsync(cancellationToken);

                if (!accessTokenOutcome)
                {
                    return(accessTokenOutcome);
                }

                // try getting a cached exchanged token ...
                var accessToken   = accessTokenOutcome.Value;
                var cachedOutcome = await getCachedIdentityTokenAsync(accessToken);

                if (cachedOutcome)
                {
                    return(cachedOutcome);
                }

                // exchange token for
                var clientCredentials = await OnGetClientCredentials();

                var credentials = new BasicAuthCredentials(clientCredentials.Identity, clientCredentials.Secret);

                var bearerToken   = accessTokenOutcome.Value as BearerToken;
                var isBearerToken = bearerToken is { };
                var subjectToken  = isBearerToken
                    ? bearerToken.Value
                    : accessTokenOutcome.Value.ToString();
                var txOutcome = await _tokenExchangeService.ExchangeAccessTokenAsync(
                    credentials,
                    subjectToken,
                    cancellationToken);

                if (!txOutcome || !ActorToken.TryParse(txOutcome.Value.AccessToken, out var actorToken))
                {
                    return(Outcome <ActorToken> .Fail(txOutcome.Exception));
                }

                var exchangedToken = isBearerToken
                    ? new BearerToken(actorToken.Identity, false)
                    : actorToken;

                // cache exchanged token and return it ...
                await cacheTokenExchangeAsync(accessToken, exchangedToken);

                return(Outcome <ActorToken> .Success(exchangedToken));
            }
            catch (Exception ex)
            {
                Logger.Error(new Exception($"Claims transformation failure: {ex.Message}", ex));
                throw;
            }
        }
コード例 #5
0
        /// <summary>
        ///   Tries obtaining an access token from the request.
        /// </summary>
        /// <returns>
        ///   An <see cref="Outcome{T}"/> instance indicating success/failure. On success the outcome
        ///   holds the access token in its <see cref="Outcome{T}.Value"/> property. On failure the outcome
        ///   declares the problem via its <see cref="Outcome.Exception"/> property.
        /// </returns>
        /// <seealso cref="GetAccessToken(Microsoft.AspNetCore.Http.HttpContext, TetraPakAuthConfig)"/>
        /// <see cref="GetAccessTokenAsync(Microsoft.AspNetCore.Http.HttpRequest, TetraPakAuthConfig)"/>
        public static Task <Outcome <ActorToken> > GetAccessTokenAsync(this HttpContext self, TetraPakAuthConfig authConfig)
        {
            if (self.Items.TryGetValue(AmbientData.Keys.AccessToken, out var o) && o is string s &&
                ActorToken.TryParse(s, out var actorToken))
            {
                return(Task.FromResult(Outcome <ActorToken> .Success(actorToken)));
            }

            var headerIdent = authConfig?.AuthorizationHeader ?? HeaderNames.Authorization;

            s = self.Request.Headers[headerIdent].FirstOrDefault();
            if (s is {} && ActorToken.TryParse(s, out actorToken))
コード例 #6
0
ファイル: TokenService.cs プロジェクト: Harkole/FocusBoard
        /// <summary>
        /// Provides a new token to replace an old or expiring one. Passing
        /// Claims to this method will generate a new Token so only call
        /// form Authenticated Controllers/Endpoints
        /// </summary>
        /// <param name="claims">A list of claims required to populate the new Token</param>
        /// <returns></returns>
        /// <remarks>Only call from authenticated end points</remarks>
        public ActorToken RenewClaimsIdentity(ClaimsPrincipal claims)
        {
            ActorToken token;

            try
            {
                Authentication auth = new Authentication
                {
                    Email          = claims.FindFirst(ClaimTypes.Email)?.Value,
                    PrimaryId      = claims.FindFirst(ClaimTypes.PrimarySid)?.Value,
                    PrimaryGroupId = claims.FindFirst(ClaimTypes.PrimaryGroupSid)?.Value,
                    RoleId         = claims.FindFirst(ClaimTypes.Role)?.Value,
                    Alias          = claims.FindFirst(ClaimTypes.Actor)?.Value,
                    Hidden         = bool.Parse(claims.FindFirst(ClaimTypes.Anonymous)?.Value),
                };

                // Generate and assign the new token values
                string encodedToken = GenerateEncodedToken(auth);
                token = new ActorToken {
                    Token = encodedToken, ExpiresIn = (int)jwtOptions.ValidFor.TotalSeconds
                };
            }
            catch (ArgumentException argEx) // Catches ArgumentNullException
            {
                token = null;

                Trace.WriteLine($"{argEx.ParamName} threw an ArgumentException: {argEx.Message}");
            }
            catch (Microsoft.IdentityModel.Tokens.SecurityTokenCompressionFailedException tokenFailedEx)
            {
                token = null;

                Trace.WriteLine(tokenFailedEx.Message);
            }
            catch (FormatException formatEx)
            {
                token = null;

                Trace.WriteLine(formatEx.Message);
            }

            return(token);
        }
 async Task cacheTokenExchangeAsync(ActorToken accessToken, ActorToken exchangedToken)
 {
     if (AmbientData.Cache is { })
コード例 #8
0
 public DetailsModel(IIdentity identity, ActorToken accessToken)
     : base(identity)
 {
     AccessToken = accessToken;
 }