I have an issue with an ASP.NET C# API application.
It uses the AuthApiAttribute class to check authorization, using 2 HTTP header to authenticate the query.
Once I have validated the credentials, I put some configuration linked to those credentials in a class with static attributes. That class is named ApiKeyConfig. That parts works correctly.
My problem is when the ApiController handles the response, the value of the attributes of ApiKeyConfig are the values of the previous API call.
So if I call the API 4 time with userA, userB, userC and userA again, the result will be:
- Call for userA: Has no info if server is fresh, last call if not
- Call for userB: Will have info of userA
- Call for userC: Will have info of userB
- Call for userA: Will have info of userC
I was expecting the static values of the ApiKeyConfig class not to survive from one query to another. I thought it would be static for the query API call only.
And from that behaviour, I suppose that the AuthApiAttribute class call is done AFTER the controller method has executed ?
In my controller, I have defined [AuthApi] above my public class CustomerController : ApiController.
So what would be the best way to pass to my controller configuration that are specific to the API-key for the current call ?
Also, is there a way to prevent values to be kept from API call to API call ? Like in this case, what would I do to make sure ApiKeyConfig don't have the value of the previous request?
Edit:
My AuthApiAttribute class:
public class AuthApiAttribute : Attribute, IAuthorizationFilter
{
public bool AllowMultiple => true;
public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
// I have the logic to check if user is valid
// [...]
List<ApiKey> keys; // Is assigned the valid API keys, skip that code below to avoid long comment
// I have some logic here to stock the valid keys in "keys"
// [...]
foreach (ApiKey apikey in keys)
{
if (key == apikey.key && auth == apikey.auth)
{
// FIXME: Would need to do somehting here to assign that key to something for me to be able to use that value once I'm in the controller's method
return response;
}
}
response.Result.StatusCode = System.Net.HttpStatusCode.Forbidden;
response.Result.Content = new StringContent("Access forbidden. Make sure your credentials are valid.");
return response;
}
}
The class ApiKeyConfig is just a class with attributes representing the settings of the API key in use (somewhat like a user's profile)
Here, an example of a Controller in which I want to refer to the ApiKey for the current request.
[AuthApi]
public class CustomerController : ApiController
{
public Models.Response Get(string id)
{
// FIXME: Here, I want to access the value of ApiKey for the current session.
try
{
// I have some logic here to get the Customer requested
// [...]
return new Models.Response
{
Status = "Success",
Data = Customer
};
}
catch (Exception e)
{
return new Models.Response
{
Status = "Error",
Message = e.Message,
Stack = e.StackTrace
};
}
}
}
Solution:
Based on Athanasios Kataras answer, in AuthApiAttribute:
actionContext.ControllerContext.Configuration.Properties.TryAdd("apikey", apikey);
And then, in my Controller's Method accessing this value with:
Configuration.Properties.TryGetValue("apikey", out object config);
ApiKeyConfig keyConfig = (ApiKeyConfig)config;
if (keyConfig.value.Equals(""))
{
// Handle session undefined
}
AuthApiAttributeandApiKeyConfigsome custom classes in your project? Can you share them with us please?