-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ODS-4562] CallContext loses values for a previous context when the s…
…ame value is set for another context (#183)
- Loading branch information
1 parent
9d505d9
commit 4283313
Showing
16 changed files
with
429 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
Application/EdFi.Ods.Api/Services/Authentication/BearerTokenHeaderProcessor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
using System; | ||
using System.Net.Http; | ||
using System.Net.Http.Headers; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using EdFi.Ods.Api.Services.Authorization; | ||
using EdFi.Ods.Api.Services.Filters; | ||
using EdFi.Ods.Common.Configuration; | ||
using EdFi.Ods.Common.Extensions; | ||
|
||
namespace EdFi.Ods.Api.Services.Authentication | ||
{ | ||
public class BearerTokenHeaderProcessor : IBearerTokenHeaderProcessor | ||
{ | ||
private const string AuthenticationScheme = "Bearer"; | ||
|
||
private readonly Lazy<bool?> _expectedUseSandboxValue; | ||
|
||
private readonly IOAuthTokenValidator _oAuthTokenValidator; | ||
|
||
public BearerTokenHeaderProcessor(IOAuthTokenValidator oAuthTokenValidator, IConfigValueProvider configValueProvider) | ||
{ | ||
_oAuthTokenValidator = oAuthTokenValidator; | ||
|
||
const string ExpectedUseSandboxValue = "ExpectedUseSandboxValue"; | ||
|
||
_expectedUseSandboxValue = new Lazy<bool?>( | ||
() => configValueProvider.GetValue(ExpectedUseSandboxValue) == null | ||
? (bool?) null | ||
: Convert.ToBoolean(configValueProvider.GetValue(ExpectedUseSandboxValue))); | ||
} | ||
|
||
public async Task<BearerTokenProcessingResult> ProcessAsync(HttpRequestMessage request, CancellationToken cancellationToken) | ||
{ | ||
// 1. Look for credentials in the request. | ||
AuthenticationHeaderValue authorization = request.Headers.Authorization; | ||
|
||
// 2. If there are no credentials, do nothing. | ||
if (authorization == null) | ||
{ | ||
return new BearerTokenProcessingResult(new AuthenticationFailureResult("Missing credentials", request)); | ||
} | ||
|
||
// 3. If there are credentials but the filter does not recognize the | ||
// authentication scheme, do nothing. | ||
if (!authorization.Scheme.EqualsIgnoreCase(AuthenticationScheme)) | ||
{ | ||
return new BearerTokenProcessingResult(); | ||
} | ||
|
||
// 4. If there are credentials that the filter understands, try to validate them. | ||
// 5. If the credentials are bad, set the error result. | ||
if (string.IsNullOrEmpty(authorization.Parameter)) | ||
{ | ||
return new BearerTokenProcessingResult(new AuthenticationFailureResult("Missing parameter", request)); | ||
} | ||
|
||
// Validate the token and get the corresponding API key details | ||
var apiClientDetails = await _oAuthTokenValidator.GetClientDetailsForTokenAsync(authorization.Parameter); | ||
|
||
if (!apiClientDetails.IsTokenValid) | ||
{ | ||
return new BearerTokenProcessingResult(new AuthenticationFailureResult("Invalid token", request)); | ||
} | ||
|
||
if (_expectedUseSandboxValue.Value.HasValue && | ||
apiClientDetails.IsSandboxClient != _expectedUseSandboxValue.Value.Value) | ||
{ | ||
var message = apiClientDetails.IsSandboxClient | ||
? "Sandbox credentials used in call to Production API" | ||
: "Production credentials used in call to Sandbox API"; | ||
|
||
return new BearerTokenProcessingResult(new AuthenticationFailureResult(message, request)); | ||
} | ||
|
||
return new BearerTokenProcessingResult(apiClientDetails); | ||
} | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
Application/EdFi.Ods.Api/Services/Authentication/IBearerTokenHeaderProcessor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using System.Net.Http; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using System.Web.Http; | ||
using EdFi.Ods.Api.Services.Authorization; | ||
|
||
namespace EdFi.Ods.Api.Services.Authentication | ||
{ | ||
public interface IBearerTokenHeaderProcessor | ||
{ | ||
/// <summary> | ||
/// Processes the supplied HTTP request message for the authorization header containing the bearer token, | ||
/// returning the associated API client details or the recommended error response. | ||
/// </summary> | ||
/// <param name="request">The request to be processed.</param> | ||
/// <param name="cancellationToken">The cancellation token associated with the request.</param> | ||
/// <returns>The result of the processing.</returns> | ||
Task<BearerTokenProcessingResult> ProcessAsync(HttpRequestMessage request, CancellationToken cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Contains the results of bearer token processing with either API client details (when a valid token is present), | ||
/// or an error (if an error response should be given), or neither (if the processing could not be performed). | ||
/// </summary> | ||
public class BearerTokenProcessingResult | ||
{ | ||
/// <summary> | ||
/// Creates a result that indicates that the bearer token could not be processed, but | ||
/// no error response is indicated. | ||
/// </summary> | ||
public BearerTokenProcessingResult() { } | ||
|
||
/// <summary> | ||
/// Creates a result that indicates that the bearer token was valid and resolved to | ||
/// the specified API client details. | ||
/// </summary> | ||
/// <param name="apiClientDetails"></param> | ||
public BearerTokenProcessingResult(ApiClientDetails apiClientDetails) | ||
{ | ||
ApiClientDetails = apiClientDetails; | ||
} | ||
|
||
/// <summary> | ||
/// Creates a result that indicates an error occurred while processing the bearer token, | ||
/// which should be returned as the result of explicit authentication processing. | ||
/// </summary> | ||
/// <param name="error"></param> | ||
public BearerTokenProcessingResult(IHttpActionResult error) | ||
{ | ||
Error = error; | ||
} | ||
|
||
/// <summary> | ||
/// The API client details associated with the bearer token on the request. | ||
/// </summary> | ||
public ApiClientDetails ApiClientDetails { get; private set; } | ||
|
||
/// <summary> | ||
/// The error result for the response (to be used by client if relevant). | ||
/// </summary> | ||
public IHttpActionResult Error { get; private set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.