The problem is in automatic update access token in client part. There is next state: on client (MVC) controller I added authorize attribute and it passed well because the client use session cookie for authentication, then request is sent on server (Web API app). The server validate token and says that it has been expired. How I can renew access token in client Please see MVC Startup file:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddAutoMapper(typeof(MappingProfile).Assembly);
// Added for session state
services.AddDistributedMemoryCache();
services.AddSession();
services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie("Cookies")
.AddOpenIdConnect(options =>
{
options.MetadataAddress = Configuration["oidc:metadataAddress"];
options.SignInScheme = "Cookies";
options.ClientId = Configuration["oidc:clientId"];
options.ClientSecret = Configuration["oidc:clientSecret"];
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.CallbackPath = "/oidc-callback";
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("openid");
options.Scope.Add("email");
options.Scope.Add("profile");
options.TokenValidationParameters = new TokenValidationParameters()
{
NameClaimType = "name",
ValidateAudience = false,
RoleClaimType = "role"
};
options.Events = new OpenIdConnectEvents
{
OnTokenResponseReceived = async context=>
{
var user = context.Principal;
var identity = user.Identity as ClaimsIdentity;
var claim = new Claim("access_token", context.TokenEndpointResponse.AccessToken);
identity?.AddClaim(claim);
await Task.CompletedTask;
},
};
});
services.AddHttpContextAccessor();
services.AddReportServerClient();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory logFactory)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
//app.UseExceptionHandlers();
app.UseStaticFiles();
app.UseAuthentication();
app.UseSession();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
RequireHeaderSymmetry = true,
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Main}/{action=Index}/{id?}");
//routes.MapRoute(
// name: "mainPage",
// template: "{controller=Main}/{action=Index}/{id?}");
});
}
Also tried UseTokenLifeTime for OpenIdConnectOptions, but this case doesn't work. When I remove cookie in browser and refresh the page it goes to Auth provider and give me valid token also tried
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
You can refresh an access token using multiple ways, Below I will illustrate how you can an access token using middleware in ASPNET Core.
In you startup class, in the the Configure method add the following line that will renew an access token when it is near expiration. NB add after "app.UseAuthentication()".
Create an extension method that will automatically renew the access token as it nears expiration as follows