/// <summary> /// Attempts to post-authenticate a request given an unauthorized response using /// the Bearer challenge cache and the application supplied AuthenticationCallback. /// </summary> /// <param name="url">The unauthorized response</param> /// <returns>The access token to use for the request</returns> protected string PostAuthenticate(HttpResponseMessage response) { // An HTTP 401 Not Authorized error; handle if an authentication callback has been supplied if (OnAuthenticate != null) { // Extract the WWW-Authenticate header and determine if it represents an OAuth2 Bearer challenge var authenticateHeader = response.Headers.WwwAuthenticate.ElementAt(0).ToString(); if (HttpBearerChallenge.IsBearerChallenge(authenticateHeader)) { var challenge = new HttpBearerChallenge(response.RequestMessage.RequestUri, authenticateHeader); if (challenge != null) { // Update challenge cache HttpBearerChallengeCache.GetInstance().SetChallengeForURL(response.RequestMessage.RequestUri, challenge); // We have an authentication challenge, use it to get a new authorization token return(OnAuthenticate(challenge.AuthorizationServer, challenge.Resource, challenge.Scope)); } } } return(null); }
/// <summary> /// Attempts to pre-authenticate a request to the specified vault or key URL using /// the Bearer challenge cache and the application supplied AuthenticationCallback. /// </summary> /// <param name="url">The vault or key URL</param> /// <returns>The access token to use for the request</returns> protected string PreAuthenticate(Uri url) { if (OnAuthenticate != null) { var challenge = HttpBearerChallengeCache.GetInstance().GetChallengeForURL(url); if (challenge != null) { return(OnAuthenticate(challenge.AuthorizationServer, challenge.Resource, challenge.Scope)); } } return(null); }
/// <summary> /// Updates the <see cref="HttpBearerChallengeCache"/> when the specified response has a return code of 401 /// </summary> /// <param name="response">The response to evaluate</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns></returns> protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, CancellationToken cancellationToken) { // if the response came back as 401 and the response contains a bearer challenge update the challenge cache if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) { HttpBearerChallenge challenge = HttpBearerChallenge.GetBearerChallengeFromResponse(response); if (challenge != null) { // Update challenge cache HttpBearerChallengeCache.GetInstance().SetChallengeForURL(response.RequestMessage.RequestUri, challenge); } } return(response); }
private static void AssertChallengeCacheEntry(string requestUrl, MockChallenge expChallenge) { var actChallenge = HttpBearerChallengeCache.GetInstance().GetChallengeForURL(new Uri(requestUrl)); if (expChallenge == null) { Assert.Null(actChallenge); } else { Assert.NotNull(actChallenge); Assert.Equal(expChallenge.AuthorizationServer, actChallenge.AuthorizationServer); Assert.Equal(expChallenge.Scope, actChallenge.Scope); Assert.Equal(expChallenge.Resource, actChallenge.Resource); } }
public async Task CacheUpdateOn401Async() { string requestUrlBase = CreateMockUrl(); string requestUrl1 = CreateMockUrl(requestUrlBase, 2); HttpBearerChallengeCache.GetInstance().SetChallengeForURL(new Uri(requestUrl1), MockChallenge.Create().ToHttpBearerChallenge(requestUrl1)); string requestUrl2 = CreateMockUrl(requestUrlBase, 2); var handler = new ChallengeCacheHandler(); var expChallenge = MockChallenge.Create(); handler.InnerHandler = new StaticChallengeResponseHandler(HttpStatusCode.Unauthorized, expChallenge.ToString()); var client = new HttpClient(handler); var _ = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, requestUrl2)); AssertChallengeCacheEntry(requestUrl1, expChallenge); AssertChallengeCacheEntry(requestUrl2, expChallenge); }