How Ocelot validate expired JWT token and re-send HttpContext with the new header ? #1884
-
Hi, I'm currently building our api gateway using Ocelot , I have services listed below
here is the flow
please advise, below is my code, let me know if you have any questions api-gateway Startup class services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer("Bearer", x =>
{
x.SaveToken = true;
x.RequireHttpsMetadata = false;
x.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetValue<string>("SecretKey"))),
ValidateIssuer = true,
ValidIssuer = Configuration.GetValue<string>("Token:Issuer"),
ValidateAudience = true,
ValidAudience = Configuration.GetValue<string>("Token:Audience"),
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = true,
};
});
services.AddOcelot().AddCacheManager(option =>
{
option.WithDictionaryHandle();
});
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAuthorization();
app.UseAuthentication();
app.UseOcelot(new TokenHandlerMiddleware(Configuration)).GetAwaiter().GetResult();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
-----------------------------------------------------------------------------
public class TokenHandlerMiddleware : OcelotPipelineConfiguration
{
private IConfiguration _configuration { get; }
public TokenHandlerMiddleware(IConfiguration configuration)
{
_configuration = configuration;
PreAuthenticationMiddleware = async (ctx, next) =>
{
await ProcessRequestAsync(ctx, next);
};
}
public async Task ProcessRequestAsync(DownstreamContext downstream, System.Func<Task> next)
{
try
{
IEnumerable<string> headers;
var user = downstream.HttpContext.User.Identity.IsAuthenticated;
downstream.DownstreamRequest.Headers.TryGetValues("Authorization", out headers);
if (!headers.Any())
throw new UnauthorizedAccessException("Unauthorized");
var url = _configuration.GetValue<string>("Token:EndPoint") + "/api/token/refreshtoken";
var token = headers.FirstOrDefault();
if (string.IsNullOrEmpty(token))
throw new UnauthorizedAccessException("Unauthorized");
token = token.Replace("Bearer ", string.Empty);
var tokenRequest = new RefreshTokenModel
{
AccessToken = token,
RefreshToken = string.Empty
};
var jsonRequest = JsonConvert.SerializeObject(tokenRequest);
var result = await PostAsync<ApiResponse>(url, jsonRequest);
if (result.issuccessful && result.isrequirednewtoken)
{
//set new token to header and re-send request
downstream.DownstreamRequest.Headers.Remove("Authorization");
downstream.DownstreamRequest.Headers.Add("Authorization", "Bearer " + result.tokenresponse.token);
**HERE I NEED TO MAKE A CALL WITH THE NEW HEADER**
}
await next.Invoke(); // I thought this line can re-make another call, but it's not working.
}
catch (Exception ex)
{
throw new UnauthorizedAccessException();
}
}
public async Task<T> PostAsync<T>(string uri, string data)
{
var httpClient = new HttpClient();
var response = await httpClient.PostAsync(uri, new StringContent(data, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Any help ? |
Beta Was this translation helpful? Give feedback.
-
Ocelot should not renew the access-token, only validate/unvalidate it. The end-user application should be in charge of tracking almost expiring tokens and renew them, redirecting to the login page if needed (e.g. cookie also expired on identity server). There are js libraries that will help you with that. oidc-client-js for instance. In any case, since user interaction might be needed, and token renewal is relying on user cookies, the gateway is not the place to automate this. |
Beta Was this translation helpful? Give feedback.
Ocelot should not renew the access-token, only validate/unvalidate it. The end-user application should be in charge of tracking almost expiring tokens and renew them, redirecting to the login page if needed (e.g. cookie also expired on identity server). There are js libraries that will help you with that. oidc-client-js for instance. In any case, since user interaction might be needed, and token renewal is relying on user cookies, the gateway is not the place to automate this.