Well, I have a WebApi using Asp Net Core 2.1 that have some security endpoints, so I have the following:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = configuration["Authorization:Domain"];
options.Audience = configuration["Authorization:ApiIdentifier"];
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateLifetime = configuration["Authorization:ValidateLifetime"] == null ? true :
Boolean.Parse(configuration["Authorization:ValidateLifetime"])
};
options.RequireHttpsMetadata = configuration["Authorization:RequireHttpsMetadata"] == null ?
true : Boolean.Parse(configuration["Authorization:RequireHttpsMetadata"]);
});
This works very well when someone calls my API, the validation is OK. I'm using http://auth0.com/ as an authorization provider.
Now I need to call other APIs that have security endpoints too, using Authorization Bearer Token (JWT). The flow that I should use in this case is Client Credentials. So, I have the steps:
- Someone calls my API
- My API validates Jwt Token using auth0.com as authorization provider
- I need to call other API, so I'm using Refit Library
My Refit interface:
public interface IUserInfoApi
{
[Get("/api/v2/users/{userId}")]
[Headers("Authorization: Bearer")]
Task<UserInfoDto> GetUserInfoAsync(string userId);
}
And I created I handler to add Bearer token to my request:
//refit apis
services.AddRefitClient<IUserInfoApi>()
.AddHttpMessageHandler<AuthorizationMessageHandler>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri(configuration["Api:UserInfo"]));
And my handler:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancelToken)
{
HttpRequestHeaders headers = request.Headers;
AuthenticationHeaderValue authHeader = headers.Authorization;
if (authHeader != null)
headers.Authorization = new AuthenticationHeaderValue(authHeader.Scheme, JWT_TOKEN);
return await base.SendAsync(request, cancelToken);
}
This works, but I think is too much manually and error-prone:
- There is a lot of OAuth2 flows to implement manually, to generate a token (client credentials, implicit flow, authorization code flow and others).
- I have to implement refresh token logic.
- I have to implement some logic to reuse token if the expiration time is valid yet, instead generate a new token every time (hit /token endpoint every time without needed).
I worked a lot with Spring Security framework, and I can just say: "Spring, I'm using OAuth here, so insert Bearer token in every HTTP requests, please". Spring, intercepts all requests that I set in configuration and OAuth flow is respected (Client Credentials, Authorization COde Flow, and others), it's transparent for me, I don't need wast my time with it.
There is any way to do it in Asp Net Core 2.1 or I need to implement manually the token generate flow?