使用ASP .NET Core验证服务描述符时错误
我正在尝试在帐户控制器中的注销操作方法中创建注销机制。为此,我需要停用我的JWT令牌。我遵循本教程停用JWT令牌。在我的项目中应用此代码后,我的项目在运行该项目时显示错误。
我的代码如下。
startup.cs
public void ConfigureServices(IServiceCollection services)
{
// New
services.AddTransient<TokenManagerMiddleware>();
services.AddTransient<ITokenManager, TokenManager>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var authPol = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(
new string[] {
JwtBearerDefaults.AuthenticationScheme })
.RequireAuthenticatedUser()
.Build();
services.AddControllers(
config =>
{
config.Filters.Add(new AuthorizeFilter(authPol));
}).AddXmlSerializerFormatters()
.AddXmlDataContractSerializerFormatters();
services.AddDbContext<BikeStoresContext>();
// JWT Token code is there below this...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "BikeStoreAPI v1"));
}
app.UseMiddleware<TokenManagerMiddleware>();
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
tokenmanagermiddleware.cs
public class TokenManagerMiddleware : IMiddleware
{
private readonly ITokenManager _tokenManager;
public TokenManagerMiddleware(ITokenManager tokenManager)
{
_tokenManager = tokenManager;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (await _tokenManager.IsCurrentActiveToken())
{
await next(context);
return;
}
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
}
itokenmanager.cs
public interface ITokenManager
{
Task<bool> IsCurrentActiveToken();
Task DeactivateCurrentAsync();
Task<bool> IsActiveAsync(string token);
Task DeactivateAsync(string token);
Task SetToken(string token);
}
tokenmanager.cs
public class TokenManager : ITokenManager
{
private readonly IDistributedCache _cache;
private readonly IHttpContextAccessor _httpContextAccessor;
public TokenManager(IDistributedCache cache, IHttpContextAccessor httpContextAccessor)
{
_cache = cache;
_httpContextAccessor = httpContextAccessor;
}
public async Task SetToken(string token)
{
await _cache.SetStringAsync(token, token);
}
public async Task<bool> IsCurrentActiveToken()
=> await IsActiveAsync(GetCurrentAsync());
public async Task DeactivateCurrentAsync()
=> await DeactivateAsync(GetCurrentAsync());
public async Task<bool> IsActiveAsync(string token)
=> await _cache.GetStringAsync(GetKey(token)) == null;
public async Task DeactivateAsync(string token)
=> await _cache.SetStringAsync(GetKey(token),
" ", new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow =
TimeSpan.FromMinutes(720)
});
private string GetCurrentAsync()
{
var authorizationHeader = _httpContextAccessor
.HttpContext.Request.Headers["authorization"];
return authorizationHeader == StringValues.Empty
? string.Empty
: authorizationHeader.Single().Split(" ").Last();
}
private static string GetKey(string token)
=> $"tokens:{token}:deactivated";
}
accountscontroller.cs
UserManager<IdentityUser> userManager;
SignInManager<IdentityUser> signInManager;
RoleManager<IdentityRole> roleManager;
private readonly ITokenManager tokenManager;
public AccountsController(UserManager<IdentityUser> _userManager, SignInManager<IdentityUser> _signInManager,
RoleManager<IdentityRole> _roleManager, ITokenManager _tokenManager)
{
userManager = _userManager;
signInManager = _signInManager;
roleManager = _roleManager;
tokenManager = _tokenManager;
}
[HttpPost("logout")]
public async Task<IActionResult> Logout()
{
await tokenManager.DeactivateCurrentAsync();
return NoContent();
}
当我尝试运行该项目时,我会遇到此错误:
system.AggregateException hresult = 0x80131500消息=某些服务 无法构造(验证服务时出错 描述符的服务类型: bikestoreapi.middleware.tokenmanagermiddleware生命周期:瞬态 bikestoreapi.middleware.tokenmanagermiddleware': 无法解析类型的服务 'Microsoft.extensions.caching.distributed.IdistributedCache' 试图激活 'Bikestoreapi.Services.TokenManagerService.TokenManager')(错误 同时验证服务描述符的服务类型: Bikestoreapi.Services.TokenManagerService.ItokenManager Lifetime: 瞬态实现类型: Bikestoreapi.Services.TokenManagerService.TokenManager':无法 解决类型的服务 'Microsoft.extensions.caching.distributed.IdistributedCache' 试图激活 'Bikestoreapi.Services.TokenManagerService.TokenManager'。)
source = microsoft.extensions.ipendentencyindoction stacktrace:at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable1 serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options) at Microsoft.extensions.dependentiondoction.defaultserviceProviderFactory.CreateserviceProvider(iserviceCollection ContarerBuilder)at microsoft.extensions.hosting.hosting.internal.servicefactoryadapter
1.CreateserviceProvider(CreateserviceProvider) 集装箱) microsoft.extensions.hosting.hostbuilder.createserviceprovider()at microsoft.extensions.hosting.hostbuilder.build()at bikestoreapi.program.main(string [] args)in C:\ users \ abhishek \ source \ repos \ bikestore \ bikestoreapi \ program.cs:line 16这个例外最初是在此通话堆栈中抛出的: [外部代码]
内部异常1:InvalidOperationException:验证时错误 服务描述符的ServiceType: bikestoreapi.middleware.tokenmanagermiddleware生命周期:瞬态 bikestoreapi.middleware.tokenmanagermiddleware': 无法解析类型的服务 'Microsoft.extensions.caching.distributed.IdistributedCache' 试图激活 'Bikestoreapi.Services.TokenManagerService.TokenManager'。
内部异常2:InvalidOperationException:无法解析 类型的服务 'Microsoft.extensions.caching.distributed.IdistributedCache' 试图激活 'Bikestoreapi.Services.TokenManagerService.TokenManager'。
我经历了多次的每个步骤和编码,但我不知道出了什么问题。你能帮我吗
编辑 我在startup.cs中添加了下面的给定代码,但是当调用登录API生成JWT令牌时,遇到此错误。
services.AddDistributedRedisCache(r => { r.Configuration = Configuration["redis:connectionString"]; });
I am trying to create a logout mechanism in logout action method in Accounts Controller. For that, I need to deactivate my JWT token. I followed this tutorial to deactivate JWT token. My project is showing error when I run the project after applying this code in my project.
Canceling JWT tokens in .NET Core
My code is as follows.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// New
services.AddTransient<TokenManagerMiddleware>();
services.AddTransient<ITokenManager, TokenManager>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var authPol = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(
new string[] {
JwtBearerDefaults.AuthenticationScheme })
.RequireAuthenticatedUser()
.Build();
services.AddControllers(
config =>
{
config.Filters.Add(new AuthorizeFilter(authPol));
}).AddXmlSerializerFormatters()
.AddXmlDataContractSerializerFormatters();
services.AddDbContext<BikeStoresContext>();
// JWT Token code is there below this...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "BikeStoreAPI v1"));
}
app.UseMiddleware<TokenManagerMiddleware>();
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
TokenManagerMiddleware.cs
public class TokenManagerMiddleware : IMiddleware
{
private readonly ITokenManager _tokenManager;
public TokenManagerMiddleware(ITokenManager tokenManager)
{
_tokenManager = tokenManager;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (await _tokenManager.IsCurrentActiveToken())
{
await next(context);
return;
}
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
}
ITokenManager.cs
public interface ITokenManager
{
Task<bool> IsCurrentActiveToken();
Task DeactivateCurrentAsync();
Task<bool> IsActiveAsync(string token);
Task DeactivateAsync(string token);
Task SetToken(string token);
}
TokenManager.cs
public class TokenManager : ITokenManager
{
private readonly IDistributedCache _cache;
private readonly IHttpContextAccessor _httpContextAccessor;
public TokenManager(IDistributedCache cache, IHttpContextAccessor httpContextAccessor)
{
_cache = cache;
_httpContextAccessor = httpContextAccessor;
}
public async Task SetToken(string token)
{
await _cache.SetStringAsync(token, token);
}
public async Task<bool> IsCurrentActiveToken()
=> await IsActiveAsync(GetCurrentAsync());
public async Task DeactivateCurrentAsync()
=> await DeactivateAsync(GetCurrentAsync());
public async Task<bool> IsActiveAsync(string token)
=> await _cache.GetStringAsync(GetKey(token)) == null;
public async Task DeactivateAsync(string token)
=> await _cache.SetStringAsync(GetKey(token),
" ", new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow =
TimeSpan.FromMinutes(720)
});
private string GetCurrentAsync()
{
var authorizationHeader = _httpContextAccessor
.HttpContext.Request.Headers["authorization"];
return authorizationHeader == StringValues.Empty
? string.Empty
: authorizationHeader.Single().Split(" ").Last();
}
private static string GetKey(string token)
=> quot;tokens:{token}:deactivated";
}
AccountsController.cs
UserManager<IdentityUser> userManager;
SignInManager<IdentityUser> signInManager;
RoleManager<IdentityRole> roleManager;
private readonly ITokenManager tokenManager;
public AccountsController(UserManager<IdentityUser> _userManager, SignInManager<IdentityUser> _signInManager,
RoleManager<IdentityRole> _roleManager, ITokenManager _tokenManager)
{
userManager = _userManager;
signInManager = _signInManager;
roleManager = _roleManager;
tokenManager = _tokenManager;
}
[HttpPost("logout")]
public async Task<IActionResult> Logout()
{
await tokenManager.DeactivateCurrentAsync();
return NoContent();
}
When I tried to run the project, I am getting this error:
System.AggregateException HResult=0x80131500 Message=Some services
are not able to be constructed (Error while validating the service
descriptor 'ServiceType:
BikeStoreAPI.Middleware.TokenManagerMiddleware Lifetime: Transient
ImplementationType: BikeStoreAPI.Middleware.TokenManagerMiddleware':
Unable to resolve service for type
'Microsoft.Extensions.Caching.Distributed.IDistributedCache' while
attempting to activate
'BikeStoreAPI.Services.TokenManagerService.TokenManager'.) (Error
while validating the service descriptor 'ServiceType:
BikeStoreAPI.Services.TokenManagerService.ITokenManager Lifetime:
Transient ImplementationType:
BikeStoreAPI.Services.TokenManagerService.TokenManager': Unable to
resolve service for type
'Microsoft.Extensions.Caching.Distributed.IDistributedCache' while
attempting to activate
'BikeStoreAPI.Services.TokenManagerService.TokenManager'.)
Source=Microsoft.Extensions.DependencyInjection StackTrace: at
Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable1 serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder) at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter
1.CreateServiceProvider(Object
containerBuilder) at
Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider() at
Microsoft.Extensions.Hosting.HostBuilder.Build() at
BikeStoreAPI.Program.Main(String[] args) in
C:\Users\Abhishek\source\repos\BikeStore\BikeStoreAPI\Program.cs:line
16This exception was originally thrown at this call stack:
[External Code]Inner Exception 1: InvalidOperationException: Error while validating
the service descriptor 'ServiceType:
BikeStoreAPI.Middleware.TokenManagerMiddleware Lifetime: Transient
ImplementationType: BikeStoreAPI.Middleware.TokenManagerMiddleware':
Unable to resolve service for type
'Microsoft.Extensions.Caching.Distributed.IDistributedCache' while
attempting to activate
'BikeStoreAPI.Services.TokenManagerService.TokenManager'.Inner Exception 2: InvalidOperationException: Unable to resolve
service for type
'Microsoft.Extensions.Caching.Distributed.IDistributedCache' while
attempting to activate
'BikeStoreAPI.Services.TokenManagerService.TokenManager'.
I went through each step and code multiple times but I don't know what went wrong. Can you please help me.
Edit
I added below given code in startup.cs but getting this error when Login API is called to generate JWT token.
services.AddDistributedRedisCache(r => { r.Configuration = Configuration["redis:connectionString"]; });
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
仔细阅读异常消息。
。代码> TokenManager 尝试获得服务。
您需要为
iDistributedCache
取决于分布式缓存提供商您想使用的。Read the exception message carefully.
It says that you didn't register the service for
IDistributedCache
whileTokenManager
attempts to get the service.You need to register the service for
IDistributedCache
depending on the distributed cache provider that you want to use.