Example #1
0
        /// <summary>
        /// Completes the Sign in process based on the authentication state and the received query string.
        /// </summary>
        /// <param name="authenticationState"></param>
        /// <param name="queryString"></param>
        protected virtual async Task CompleteSignIn(TRemoteAuthenticationState authenticationState, string queryString)
        {
            if (authenticationState is null)
            {
                throw new ArgumentNullException(nameof(authenticationState));
            }

            if (string.IsNullOrEmpty(queryString))
            {
                throw new ArgumentException($"'{nameof(queryString)}' cannot be null or empty", nameof(queryString));
            }

            var internalState = new AuthorizeState()
            {
                CodeVerifier = authenticationState.CodeVerifier,
                Nonce        = authenticationState.Nonce,
                RedirectUri  = authenticationState.RedirectUrl,
                StartUrl     = authenticationState.StartUrl,
                State        = authenticationState.State,
            };

            var loginResult = await Client.ProcessResponseAsync(queryString, internalState);

            if (loginResult.IdentityToken != null)
            {
                await TokenCache.Add(IdTokenKey, new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(loginResult.IdentityToken));
            }
            if (loginResult.RefreshToken != null)
            {
                await _protectedStorage.SetAsync(RefreshTokenKey, loginResult.RefreshToken);
            }
            if (loginResult.AccessToken != null)
            {
                await TokenCache.Add(AccessTokenKey, new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(loginResult.AccessToken));
            }
        }
Example #2
0
        /// <inheritdoc />
        public virtual async Task <AccessTokenResult> RequestAccessToken()
        {
            await EnsureAuthService();

            if (await TokenCache.TryGet(AccessTokenKey, out var accessToken))
            {
                return(new AccessTokenResult(this, AccessTokenResultStatus.Success, new AccessToken()
                {
                    Expires = accessToken.ValidTo.ToLocalTime(),
                    GrantedScopes = accessToken.Claims.Where(x => x.Type.Equals(Options.UserOptions.ScopeClaim, StringComparison.Ordinal)).Select(x => x.Value).ToList(),
                    Value = accessToken.RawData,
                }));
            }

            Task <Task <AccessTokenResult> > requestAccessTokenTask = null;

            // make sure we execute this method only once. We await the task otherwise.
            // With multiple components requesting the authentication state during reload, this happens. Multiple requests would be sent to the authentication
            // service with possible loss of the last refresh/or auth token.
            if ((requestAccessTokenTask = Interlocked.CompareExchange(ref _requestAccessTokenTask, new Task <Task <AccessTokenResult> >(InternalRequestAccessToken), null)) == null)
            {
                requestAccessTokenTask = _requestAccessTokenTask;
                requestAccessTokenTask.Start();
            }

            return(await requestAccessTokenTask.Unwrap());

            async Task <AccessTokenResult> InternalRequestAccessToken()
            {
                try
                {
                    string refreshToken = null;

                    if (!string.IsNullOrEmpty(refreshToken = await _protectedStorage.GetAsync <string>(RefreshTokenKey)))
                    {
                        var refreshTokenResult = await Client.RefreshTokenAsync(refreshToken);

                        if (refreshTokenResult.IdentityToken != null)
                        {
                            await TokenCache.Add(IdTokenKey, new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(refreshTokenResult.IdentityToken));
                        }
                        if (refreshTokenResult.RefreshToken != null)
                        {
                            await _protectedStorage.SetAsync(RefreshTokenKey, refreshTokenResult.RefreshToken);
                        }
                        if (refreshTokenResult.AccessToken != null)
                        {
                            accessToken = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(refreshTokenResult.AccessToken);
                            await TokenCache.Add(AccessTokenKey, accessToken);

                            var grantedScopes = accessToken.Claims.Where(x => x.Type.Equals(Options.UserOptions.ScopeClaim, StringComparison.Ordinal)).Select(x => x.Value).ToList();

                            return(new AccessTokenResult(this, AccessTokenResultStatus.Success, new AccessToken()
                            {
                                Expires = accessToken.ValidTo.ToLocalTime(),
                                GrantedScopes = grantedScopes,
                                Value = accessToken.RawData,
                            }));
                        }
                    }

                    return(new AccessTokenResult(this, AccessTokenResultStatus.RequiresRedirect, null));
                }
                finally
                {
                    _requestAccessTokenTask = null;
                }
            }
        }