gpt4 book ai didi

c# - 从 ASP.NET 到 .NET Core 的 DelegateHandler

转载 作者:行者123 更新时间:2023-11-30 16:40:02 25 4
gpt4 key购买 nike

在一个旧的 asp.net 项目中,我有一个类实现了我为每个路由设置的 DelegatingHandler:

public class AdminSecurityMessageHandler : DelegatingHandler
{
private readonly HttpConfiguration _config;

public AdminSecurityMessageHandler(HttpConfiguration config)
{
if (config == null)
{
throw new ArgumentNullException("config");
}
_config = config;
}

protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var repository = (IUserRepository)_config.DependencyResolver.GetService(typeof(IUserRepository));
var accessTokener = (IAccessTokener)_config.DependencyResolver.GetService(typeof(IAccessTokener));

if (!request.Headers.Contains(AccessTokener.CallerId))
{
return Unauthorized(String.Empty);
}

var guid = request.Headers.GetValues(AccessTokener.CallerId).FirstOrDefault();
var user = repository.GetByGuid(guid);

if (user == null)
{
return Unauthorized(String.Empty);
}

var result = accessTokener.CheckAccessTokenHash(user.Guid, request.Headers.Authorization.Parameter);
switch (result)
{
case AccessTokenCheckerResult.Invalid:
return Unauthorized(String.Empty);
case AccessTokenCheckerResult.Expired:
return Unauthorized("AccessToken.Expired");
}

if (!user.IsAdmin)
{
return Unauthorized("No admin rights");
}

var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, user.Id.ToString()));
var identity = new ClaimsIdentity(claims, "custom");
var principal = new UserPrincipal(identity, user);
request.GetRequestContext().Principal = principal;

return base.SendAsync(request, cancellationToken);
}

我需要将项目移动到 .NET Core,但在尝试注册它们时遇到了一些麻烦。我可以像这样注册简单的路线:

app.UseMvc(routes => { routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}"); });

所以问题是,当我在 .NET Core 中注册路由时,我应该如何从 ASP.NET 实现和设置类似 DelegatingHandler 的东西? (每个路由设置不同的处理程序)

它在 ASP.NET 中的工作原理:在 WebApiConfig 类中注册方法。

public static void RegisterRoutes(HttpConfiguration config, HttpMessageHandler routeHandlers, HttpMessageHandler adminRouteHandlers)
{
.......................

config.Routes.MapHttpRoute(
name: "FriendsAPI",
routeTemplate: "api/users/{id}/friends/{friendId}",
defaults: new { controller = "Friends", friendId = RouteParameter.Optional },
constraints: null,
handler: routeHandlers
);


config.Routes.MapHttpRoute(
name: "AdminUserBlocksApi",
routeTemplate:
"api/admin/user-blocks/{userId}",
defaults: new { controller = "AdminUserBlocks", userId = RouteParameter.Optional },
constraints: null,
handler: adminRouteHandlers
.......................
);
}

最佳答案

由于Asp.Net Core 中没有DelegateHandlers,您可以尝试创建自定义中间件。查看可用于满足您的要求的简化中间件:

public class AdminSecurityMiddleware
{
private readonly RequestDelegate _next;
IUserRepository userRepository; // IUserRepository should be registered for dependency injection in Startup.ConfigureServices

public AdminSecurityMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task Invoke(HttpContext context)
{
bool isAdminUserBlocksApiRoute;
//check for route here. As I know there is no elegant way to get name of the route since context.GetRouteData() returns null until mvc middleware is called.
// probably you can check like this context.Request.Path.StartsWithSegments("/api/admin")

if (isAdminUserBlocksApiRoute)
{
_userRepository = context.RequestServices.GetService<IUserRepository>();
bool isUserAuthorized;
// check here for Authorization
if (!isUserAuthorized)
{
context.Response.Clear();
context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
await context.Response.WriteAsync("Unauthorized");
return;
}

// adding custom claims
var identity = new ClaimsIdentity(new GenericIdentity("user.Id"), new[] { new Claim("user_id", "id") });
context.User.AddIdentity(identity);
}
await _next.Invoke(context);
}
}

然后在Startup中的mvcmiddleware之前添加到pipeline中:

app.UseMiddleware<AdminSecurityMiddleware>();
app.UseMvc(routes =>
{
...
}

阅读更多关于中间件的信息 here

关于c# - 从 ASP.NET 到 .NET Core 的 DelegateHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52101026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com