/// <summary> /// Gets the <see cref="AuthenticationSchemeOptions"/> configured for an /// authentication handler, if the handler is a descendent of the /// <see cref="AuthenticationHandler{TOptions}"/> class. /// </summary> /// <param name="handler">The authentication handler to get options from.</param> /// <param name="handlerType">Optional. The authentication handler type, e.g. the value of <see cref="AuthenticationScheme.HandlerType"/>. If <see langword="null"/> or omitted, the result of calling <see cref="object.GetType"/> on <paramref name="handler"/> is used.</param> /// <returns> /// The value of the <see cref="AuthenticationHandler{TOptions}.Options"/> property when <paramref name="handler"/> is casted to /// a specific instance of <see cref="AuthenticationHandler{TOptions}"/>. /// If <paramref name="handler"/> does not derive from <see cref="AuthenticationHandler{TOptions}"/> or if <paramref name="handler"/> is <see langword="null"/>, /// <see langword="null"/> is returned. /// </returns> /// <remarks> /// The method determines the implementation of the <see cref="AuthenticationHandler{TOptions}"/> /// class and queries assembly metadata for the specific generic parameter used in the <paramref name="handlerType"/>. /// Then reflection is used to construct a specific delegate to access the <see cref="AuthenticationHandler{TOptions}.Options"/> /// property of the authentication handler. The constructed delegate is cached for subsequent calls using the same type. /// </remarks> public static AuthenticationSchemeOptions GetHandlerOptions(IAuthenticationHandler handler, Type handlerType = null) { if (handler is null) { return(null); } else if (handlerType is null) { handlerType = handler.GetType(); } bool found = false; HandlerGetOptionsFunc getOptionsFunc; lock (HandlerGetOptionsFuncs) { found = HandlerGetOptionsFuncs.TryGetValue(handlerType, out getOptionsFunc); } if (!found) { getOptionsFunc = CreateHandlerGetOptionsFunc(handlerType); lock (HandlerGetOptionsFuncs) { HandlerGetOptionsFuncs[handlerType] = getOptionsFunc; } } return(getOptionsFunc?.Invoke(handler)); }
public async Task GetTokenProvider(WebhookConfig config, IAuthenticationHandler expectedHandler) { var factory = new AuthenticationHandlerFactory(new HttpClientFactory(), new Mock <IBigBrother>().Object); var handler = await factory.GetAsync(config, CancellationToken.None); Assert.Equal(expectedHandler.GetType(), handler.GetType()); }
public async Task RefereshAuthenticationAsync() { _httpClient.DefaultRequestHeaders.Remove("Authorization"); if (!string.IsNullOrEmpty(_tokenHolder.RefreshToken.ToInsecureString())) { try { _logger.LogInformation($"Getting a new access token using refresh token"); var scopes = _tokenHolder.Scopes; var tokenInfoResponse = await RefreshOpenIdTokenAsync(_tokenHolder.RefreshToken, scopes); _logger.LogInformation($"Obtained a new access token using refresh token"); var tokens = new TokenHolder(tokenInfoResponse, scopes); SetTokens(tokens); // fire the 'token updated' event TokenUpdated?.Invoke(tokens); return; } catch (Exception ex) { _logger.LogInformation(ex, "Could not refersh access token using the refresh_token"); } } // authenticate again (using credentials or whatever the handler can do for us) if (_authHandler != null) { _logger.LogInformation($"Getting a new access token using {_authHandler.GetType()}"); var tokens = await _authHandler.AuthenticateAsync(); _logger.LogInformation($"Obtained a new access token using {_authHandler.GetType()}"); SetTokens(tokens); // fire the 'token updated' event TokenUpdated?.Invoke(tokens); } else { throw new AuthenticationException( "Unable to refresh access token and there is no way to re-authenticate."); } }
private async Task <Exception> CreateMismatchedSignOutHandlerException(string scheme, IAuthenticationHandler handler) { var schemes = await GetAllSignOutSchemeNames(); var mismatchError = $"The authentication handler registered for scheme '{scheme}' is '{handler.GetType().Name}' which cannot be used for {nameof(SignOutAsync)}. "; if (string.IsNullOrEmpty(schemes)) { // CookieAuth is the most common implementation of sign-out, but OpenIdConnect and WsFederation also support it. return(new InvalidOperationException(mismatchError + $"Did you forget to call AddAuthentication().AddCookie(\"Cookies\") and {nameof(SignOutAsync)}(\"Cookies\",...)?")); } return(new InvalidOperationException(mismatchError + $"The registered sign-out schemes are: {schemes}.")); }
private async Task <Exception> CreateMismatchedSignInHandlerException(string scheme, IAuthenticationHandler handler) { var schemes = await GetAllSignInSchemeNames(); var mismatchError = $"The authentication handler registered for scheme '{scheme}' is '{handler.GetType().Name}' which cannot be used for SignInAsync. "; if (string.IsNullOrEmpty(schemes)) { // CookieAuth is the only implementation of sign-in. return(new InvalidOperationException(mismatchError + $"Did you forget to call AddAuthentication().AddCookie(\"Cookies\") and SignInAsync(\"Cookies\",...)?")); } return(new InvalidOperationException(mismatchError + $"The registered sign-in schemes are: {schemes}.")); }