c# - 从 mvc 中的中间件手动调用授权流程
问题描述
我在 MVC aspnet core 2 应用程序中设置了 oauth 授权。当我使用该[Authorize]
属性时它按预期工作,但我无法让它与我的中间件一起使用RequestHandler
。
我尝试创建一个调用该context.ChallengeAsync()
方法的服务,但是从中间件调用时它失败了(调用从不重定向)。如果用户尚未登录,则永远不会显示同意页面,并且返回的令牌是null
.
如果用户已经登录,则调用返回令牌。从控制器内部调用该服务时(而不是使用[Authorize]
) ,该服务确实有效
那么我该如何让它工作呢?在继续之前,我想确保用户已获得授权(以便我可以访问令牌)...
以下是相关的代码部分:
启动.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OAuthOptionsDefaults.SchemeName;
})
.AddCookie()
.AddOAuth(OAuthOptionsDefaults.SchemeName,
options => { options.SaveTokens = true; /*other options*/ });
services.AddMvc();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IOAuthService, OAuthService>();
services.AddTransient<IRequestHandler, RequestHandler>();
}
public void Configure(IApplicationBuilder app, IRequestHandler requestHandler, ..)
{
app.UseExceptionHandler("/Home/Error");
app.UseStaticFiles();
app.UseAuthentication();
app.Map(new PathString("/myapi"), appbuilder =>
{
appbuilder.Run(async (context) =>
{
await requestHandler.Handle(context, "url to an api", "an api key");
});
});
app.UseMvcWithDefaultRoute();
}
}
请求处理程序.cs
public class RequestHandler : IRequestHandler
{
//[Authorize] doesn't work
public async Task Handle(HttpContext context, string apiUrl, string apiKey)
{
//injected IOAuthService _service;
//tried with and without context as parameter
var accessToken = await _service.GetAccesTokenAsync();
//do stuff ...
}
}
OAuthService.cs
public class OAuthService : IOAuthService
{
private async Task<string> GetAccesTokenAsyncHelper(HttpContext context)
{
var isAuthenticated = ((ClaimsIdentity)context.User.Identity)?.IsAuthenticated ?? false;
if (!isAuthenticated)
{
//tried with and without setting schemename
await context.ChallengeAsync(OAuthOptionsDefaults.SchemeName);
}
return await context.GetTokenAsync(OAuthOptionsDefaults.SchemeName, "access_token");
}
public async Task<string> GetAccesTokenAsync()
{
//injected IHttpContextAccessor _accessor;
var context = _accessor.HttpContext;
return await GetAccesTokenAsyncHelper(context);
}
public async Task<string> GetAccesTokenAsync(HttpContext context)
{
return await GetAccesTokenAsyncHelper(context);
}
}
编辑:使问题更短,更指向希望有人回答。
解决方案
您需要将 Identity 添加到 HttpContext 的用户属性
context.User.AddIdentity((ClaimsIdentity) principal.Identity);
我在这里添加了一个教程,解释了如何使用来自 URL 的 JWT 在中间件中授权 HttpContext 希望这会有所帮助:)
推荐阅读
- c++ - C ++:对同一对象的两次单独的“make_shared”调用将创建两个单独且独立的shared_ptr及其控制块?
- python - NameError: 'exit' 未在 cx_Freeze python 中定义
- python - 在 Keras 中进行预测后无法创建混淆矩阵 - 无法处理多标签指示符的混合
- node.js - 如何更新猫鼬列表中的对象(在NodeJS中)
- java - 如何始终从 MySQL 表中选择特定行并通过改造显示在 android TextView 上
- android - 我在导入 androidx.cardview.R 时出错;我该如何解决
- python - 自定义 Matplotlib 颜色图
- arrays - 使用 C 的直接 I/O:数组与指针
- c - x86-64 零标志在内联调用之间清除(和另一个问题)
- java - Android:谷歌登录需要哪些元数据标签