从ASP.NET到.NET Core的DelegateHandler [英] DelegateHandler from ASP.NET to .NET Core
问题描述
在一个旧的asp.net项目中,我有一个实现 DelegatingHandler
的类,该类已设置为每个路由:
In an old asp.net project I have a class that implements DelegatingHandler
that I set to each route:
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,但遇到了一些麻烦尝试注册时。
我可以注册这样的简单路线:
I need to move the project to .NET Core, and I have some troubles when trying to register them. I can register simple routes like this:
app.UseMvc(routes => { routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}"); });
所以问题是我应该如何实现并设置 DelegatingHandler 我在.NET Core中注册路由时是否从ASP.NET获得code>? (为每个路由设置不同的处理程序)
So the question is how should I implement and set something like DelegatingHandler
from ASP.NET when I register routes in .NET Core? (Set different handler per route)
在ASP.NET中的工作方式:
在 WebApiConfig
类。
How it works in ASP.NET:
Register method in WebApiConfig
class.
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
中的c $ c> DelegateHandlers ,您可以尝试创建自定义的中间件
。请参见简化的中间件
,您可以使用它来满足您的要求:
Since there is no DelegateHandlers
in Asp.Net Core
you can try to create a custom middleware
. See the simplified middleware
that you can use to meet your requirements:
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);
}
}
然后在启动
中的> mvc 中间件
:
Then add it to pipeline before mvc
middleware
in Startup
:
app.UseMiddleware<AdminSecurityMiddleware>();
app.UseMvc(routes =>
{
...
}
在此处
这篇关于从ASP.NET到.NET Core的DelegateHandler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!