停止从资源服务器检索数据的过期访问令牌



我一直在摆弄IDS4,我遇到了一个小问题。我将令牌的使用寿命设置为大约15秒,即使它们已经过期,我仍然可以从资源服务器中检索日期。如果我在客户端调用的头中删除令牌,我会得到401错误。

客户端

[Authorize]
public async Task<ActionResult> Shouts()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
var tokenh = new JwtSecurityTokenHandler();
var jwtSecurityToken= tokenh.ReadJwtToken(accessToken);
var val = jwtSecurityToken.ValidTo;

using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
var rawResponse = await client.GetAsync("http://localhost:5002/api/Values/Get");
if (rawResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
var refreshSucc = await this.RefreshTokensAsync(this.HttpContext);
if (!refreshSucc)
{
var authServerInfo = await this.GetAuthenticationServerInfo();
return Redirect(authServerInfo.AuthorizeEndpoint);
}
}
var response = await (rawResponse).Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<List<String>>(response);
return View("Shouts", data);
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{                
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";                
})
.AddCookie("Cookies",o=>o.LogoutPath="/home/logout")
.AddOpenIdConnect("oidc", opt => 
{
opt.SignInScheme = "Cookies";
opt.Authority = "http://localhost:5000";
opt.RequireHttpsMetadata = false;
opt.ClientId = "AuthTest_Code";
opt.ClientSecret = "secret";
opt.ResponseType = "id_token code";
opt.Scope.Add("TestAPI");
opt.Scope.Add("offline_access");
opt.Scope.Add("email");
opt.GetClaimsFromUserInfoEndpoint = true;
opt.SaveTokens = true;                    
});
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}

身份验证服务器

public static IEnumerable<Client> GetClients()
{
return new List<Client>
{              
new Client
{
ClientId = "AuthTest_Code",
ClientSecrets=new []{new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Hybrid,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,                        
"TestAPI"
},
AllowAccessTokensViaBrowser=true,
AllowOfflineAccess=true,
RedirectUris = new [] { "http://localhost:5001/signin-oidc" },
PostLogoutRedirectUris={ "http://localhost:5001/signout-callback-odic"},
RequireConsent=false,
AccessTokenLifetime=15,
AbsoluteRefreshTokenLifetime=15
}
};
}
public class Startup
{
public IHostingEnvironment Environment { get; }
public Startup(IHostingEnvironment environment)
{
Environment = environment;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
var isServer = services.AddIdentityServer()                
.AddSigningCredential(new X509Certificate2(@"C:OpenSSLCertsAuthenticate.pfx", "Password1"))
.AddInMemoryApiResources(TestConfig.GetApis())
.AddInMemoryClients(TestConfig.GetClients())
.AddInMemoryIdentityResources(TestConfig.GetIdentityResources())
.AddTestUsers(TestConfig.GetUsers());

services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseIdentityServer();
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
}

资源服务器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace ResourceAPI
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")                
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;                    
options.ApiName = "TestAPI";                    
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMvc();
}
}
}

[Route("api/[controller]")]
public class ValuesController:ControllerBase
{
[HttpGet]
[Route("Get")]
[Authorize]
public async Task<IActionResult> Get()
{
var username = User.Claims.FirstOrDefault(t => t.Type == "email")?.Value;
return Ok(new string[] { "value1", "value2" });
}      
}

访问令牌:eyJhbGciOiJSUzi1NiIsImtpZCI6IjQ0Q0Q4NjFEQjA0MzdEMUM4NUY2REU0MTIyMkFDOEIwMTE3M0Q2MTAiLCJ0eAiOiJKV1QiLCJ4NXQiOiJSTTJHSGJCRGZSeUY5dDVCSWlySXNCRnoxaEEifQ.eyJuYmYiOjE1NDIxMjc4OTQsImV4cCI6MTU0MjEyNzkwOSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIyYxVkIjpbimh 0dHA6Ly9sb2NhbGhvc3Q6NTAwMC9yZXNvdXJjZXMiLCJUZXN0QVBJIl0sImNsaWVudF9pZCI6IkF1dGhUZXN0X0NvZGUILCzdWIiOiIxIxIjIxIyXV0aF90aW1lIjoxNTQyMTi3DkzLCJpZHAiOiJsb2NhbCIsImVtYWillsIjoiRGF2aWRAQUJldHRlckxpZmUuY28uemEiLCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIwiZW1haWwiLCJUZXN0QVBJIiwib2ZmbGluZV9hY2Nlc3MiXSwiYW1yjpbInb3ZCJdfQ.hNskjZz3IBqPg_5T0xVwYEP5RukcMt3l019PRp74vNBkiEr6LvBADA_eyhNGA8qDd7SwyDq6APaKxaNt0 YybAChZvFW6pzLlfkNVHM1vuN7PDOX9PNGhFK9kSONBypXo6JqV3epactsmJvhr3FZxBSufUDRyV4j_YY3O8TCjJf_5UORc_3ox9clNdjt-Vx-BlcDjVbpBw2P76F3pq2IPDM139H4qYcyaTzSlEbFd3EdVwO6O85bWM1G8yQ9zQAUk23It29oHxTtwsi5Wg4Zpmt7K7AlvKjKxKoxw_Y32QdBkGY9xU_KXOn4h0WJV3LG-InZc7BveLGHq6ncaQ

尝试设置选项。JwtValidationClockSkew属性在您的web api(资源服务器(中为零

services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.JwtValidationClockSkew = TimeSpan.Zero;
options.Authority = "https://localhost:44323";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});

Microsoft JWT验证中间件中存在时钟偏移。默认情况下设置为5分钟。建议将其保留为默认值(300秒/5分钟(。

这很可能是由于默认的5分钟(如果内存可用(时钟偏移允许。然而,可以在IDS4和承载令牌中间件中覆盖该设置。

最新更新