private async Task <HttpResponseMessage> SendAuthenticatedRequest(HttpRequestMessage request, CancellationToken cancellationToken) { await EnsureValidAccessTokenAsync(cancellationToken); request.Headers.Authorization = new AuthenticationHeaderValue(AccessTokenTypeParser.ToString(_accessToken.Type), _accessToken.Value); return(await base.SendAsync(request, cancellationToken)); }
private AccessTokenType ParseAccessTokenType(string str) { var type = AccessTokenTypeParser.FromString(str); if (!type.HasValue) { throw new InvalidOperationException($"Unknown access token type '{str}'"); } return(type.Value); }
private async Task WriteAccessTokenAsync(IOwinResponse response, string accessToken, AccessTokenType accessTokenType, TimeSpan expiresIn) { response.ContentType = "application/json; charset=UTF-8"; var tokenObj = new JObject( new JProperty("access_token", accessToken), new JProperty("token_type", AccessTokenTypeParser.ToString(accessTokenType)), new JProperty("expires_in", (int)expiresIn.TotalSeconds)); await response.WriteAsync(tokenObj.ToString()); }
public static void SetAuthenticationFailed( this IOwinResponse response, AccessTokenType type, string error, string errorDescription = null, string requiredScope = null) { if (error == null) { throw new ArgumentNullException(nameof(error)); } if (error == AuthenticationErrorCodes.InvalidRequest) { response.StatusCode = 400; } if (error == AuthenticationErrorCodes.InvalidToken) { response.StatusCode = 401; } if (error == AuthenticationErrorCodes.InsufficentScope) { response.StatusCode = 403; } response.OnSendingHeaders(rsp => { var sb = new StringBuilder($@"{AccessTokenTypeParser.ToString(type)} error=""{error}"""); if (!string.IsNullOrEmpty(errorDescription)) { sb.Append($@",error_description=""{errorDescription}"""); } if (!string.IsNullOrEmpty(requiredScope)) { sb.Append($@",scope=""{requiredScope}"""); } ((IOwinResponse)rsp).Headers.Set( "WWW-Authenticate", sb.ToString() ); }, response); }
private static bool IsInvalidToken(HttpResponseMessage response) { return(response.Headers.WwwAuthenticate.Any(x => AccessTokenTypeParser.FromString(x.Scheme).HasValue&& HttpHeaderUtils.ParseOAuthSchemeParameter(x.Parameter)["error"].Equals(AuthenticationErrorCodes.InvalidToken, StringComparison.OrdinalIgnoreCase))); }
public async Task <AccessToken> GetTokenAsync(GenericXmlSecurityToken securityToken, CancellationToken cancellationToken) { if (securityToken == null) { throw new ArgumentNullException(nameof(securityToken)); } string samlToken; using (var stream = new MemoryStream()) { using (var writer = XmlWriter.Create(stream)) { securityToken.TokenXml.WriteTo(writer); } samlToken = Convert.ToBase64String(stream.ToArray()); } var requestHandler = new WebRequestHandler { ClientCertificates = { _settings.ClientCertificate } }; var formFields = new Dictionary <string, string> { { "saml-token", samlToken } }; if (_settings.DesiredAccessTokenExpiry.HasValue) { formFields["should-expire-in"] = ((int)_settings.DesiredAccessTokenExpiry.Value.TotalSeconds).ToString(); } var client = new HttpClient(requestHandler); var response = await client.PostAsync( _settings.AccessTokenIssuerEndpoint, new FormUrlEncodedContent(formFields), cancellationToken); if (!response.IsSuccessStatusCode) { //just find the first valid authenticate header we recognize var challenge = response.Headers.WwwAuthenticate .Select(x => new { Type = AccessTokenTypeParser.FromString(x.Scheme), x.Parameter }) .FirstOrDefault(x => x.Type.HasValue); if (challenge != null) { var parms = HttpHeaderUtils.ParseOAuthSchemeParameter(challenge.Parameter); throw new OioIdwsChallengeException( challenge.Type.Value, parms["error"], parms["error_description"], $@"Got unexpected challenge while issuing access token from '{ _settings.AccessTokenIssuerEndpoint }' ({response.StatusCode})': {parms["error"]} - {parms["error_description"]}"); } throw new InvalidOperationException( $@"Got unexpected response while issuing access token from '{_settings.AccessTokenIssuerEndpoint}' {response.StatusCode}: {await response.Content.ReadAsStringAsync()}"); } var json = await response.Content.ReadAsStringAsync(); var jsonValue = JObject.Parse(json); var accessToken = new Rest.Client.AccessToken.AccessToken { Value = (string)jsonValue["access_token"], ExpiresIn = TimeSpan.FromSeconds((int)jsonValue["expires_in"]), RetrievedAtUtc = DateTime.UtcNow, Type = ParseAccessTokenType((string)jsonValue["token_type"]) }; return(accessToken); }
protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { try { AuthenticationHeaderValue authHeader; if (AuthenticationHeaderValue.TryParse(Context.Request.Headers["Authorization"], out authHeader)) { var requestAccessTokenType = AccessTokenTypeParser.FromString(authHeader.Scheme); if (!requestAccessTokenType.HasValue) { _logger.WriteVerbose($"Ignoring unhandled authorization scheme '{authHeader.Scheme}'"); return(null); } var accessToken = authHeader.Parameter; _logger.WriteEntry(Log.ProcessingToken(accessToken)); //The token provider validates that the token is known and not expired. var tokenRetrievalResult = await Options.TokenProvider.RetrieveTokenAsync(accessToken); if (tokenRetrievalResult.Success) { var token = tokenRetrievalResult.Result; if (requestAccessTokenType != token.Type) { StoreAuthenticationFailed(AuthenticationErrorCodes.InvalidToken, "Authentication scheme was not valid", token.Type); _logger.WriteEntry(Log.InvalidTokenType(authHeader.Scheme)); return(null); } if (token.Type == AccessTokenType.HolderOfKey) { var cert = Context.Get <X509Certificate2>("ssl.ClientCertificate"); if (cert?.Thumbprint == null || !cert.Thumbprint.Equals(token.CertificateThumbprint, StringComparison.OrdinalIgnoreCase)) { StoreAuthenticationFailed(AuthenticationErrorCodes.InvalidToken, "A valid certificate must be presented when presenting a Holder-of-key token", requestAccessTokenType.Value); _logger.WriteEntry(Log.HolderOfKeyNoCertificatePresented(accessToken, cert?.Thumbprint)); return(null); } } var identity = await Options.IdentityBuilder.BuildIdentityAsync(token); _logger.WriteEntry(Log.TokenValidatedAndRequestAuthenticated(accessToken)); return(new AuthenticationTicket(identity, new AuthenticationProperties())); } if (tokenRetrievalResult.Expired) { _logger.WriteEntry(Log.TokenExpired(accessToken)); StoreAuthenticationFailed(AuthenticationErrorCodes.InvalidToken, "Token was expired", AccessTokenTypeParser.FromString(authHeader.Scheme) ?? AccessTokenType.Bearer); } else { _logger.WriteEntry(Log.TokenWasNotRetrievedFromAuthorizationServer(accessToken)); StoreAuthenticationFailed(AuthenticationErrorCodes.InvalidToken, "Token information could not be retrieved from the Authorization Server. The access token might be unknown or expired", requestAccessTokenType.Value); } return(null); } } catch (Exception ex) { _logger.WriteError("Unhandled exception", ex); } return(null); }