4

我有一个自托管的 Web API 项目,所以我不得不使用Yao 的博客文章来制作帮助页面。接下来,我必须保护我的一些方法免遭未经授权的使用。我已经实现了这个想法

现在有趣的部分。我有 3 条路线:

/help这导致帮助页面,

/authentication/authenticate用于调用身份验证方法,它需要用户凭据并在成功的情况下返回安全令牌

/transaction/{action}/{id}路线需要防止未经授权的使用。

所以基本上,我需要让所有路由,其中​​控制器 = 事务,由TokenInspector.

1.场景:如果我有这样的路由配置:

_config.Routes.MapHttpRoute(
            name: "AuthenticatedOnly",
            routeTemplate: "transaction/{action}/{id}",
            defaults: new {controller = "Transaction", action="GetNewTaskId", id=RouteParameter.Optional},
            constraints: null,
            handler: tokenInspector
            );

        _config.Routes.MapHttpRoute(
            "Default",
            "{controller}/{action}/{id}",
            defaults: new { controller="Help", action="Index", id = RouteParameter.Optional}
            );

一切正常,除了帮助页面只显示POST Authentication/Authenticate 条目

2.场景:如果我将路由配置更改为:

_config.Routes.MapHttpRoute(
            name: "AuthenticatedOnly",
            routeTemplate: "transaction/{action}/{id}",
            defaults: new {},
            constraints: null,
            handler: tokenInspector
            );

        _config.Routes.MapHttpRoute(
            "Default",
            "{controller}/{action}/{id}",
            defaults: new { controller="Help", action="Index", id = RouteParameter.Optional}
            );

帮助页面可以正常工作并显示所有方法,但/transaction不再受保护并且无需令牌即可工作。

3. 场景:

_config.Routes.MapHttpRoute(
                name: "AuthenticatedOnly",
                routeTemplate: "transaction/{action}/{id}",
                defaults: new {id=RouteParameter.Optional},
                constraints: null,
                handler: tokenInspector
                );

            _config.Routes.MapHttpRoute(
                "Default",
                "{controller}/{action}/{id}",
                defaults: new { controller="Help", action="Index", id = RouteParameter.Optional}
                );

适用于身份验证和帮助页面,但是当我/Transaction/GetNewTaskId在其标头中使用有效令牌发出请求时,我得到 404。

更新 谁能解释一下,帮助页面的生成如何依赖于注册的路线?有什么办法可以调整和执行ApiExplorer打印出控制器包含的东西?

更新 2 经过一番努力和调查,我找到了一个符合我目标的解决方案 - 保留文档和安全模式。我已经实现了一个自定义消息处理程序(基本上,我使用了我的 TokenInspector,但在它的逻辑中添加了 url 过滤)。

所以,我现在有一条路线:

_config.Routes.MapHttpRoute(
                name: "Default",
                routeTemplate: "{controller}/{action}/{id}",
                defaults: new { controller = "Help", action = "Index", id=RouteParameter.Optional }
                );

这就是我启动服务器的方式:

_config = new ExtendedHttpSelfHostConfiguration(ServiceAddress);
            TokenInspector tokenInspector = new TokenInspector() { InnerHandler = new HttpRoutingDispatcher(_config) };
            _server = new HttpSelfHostServer(_config, tokenInspector);
            ConfigureHost(_config);
            _server.OpenAsync();

可能问题本来就这样,无法回答,但无论如何,谢谢大家的努力!

问候,失眠_

4

2 回答 2

1
//This is for your public controllers
//this route will ONLY catch requests for Help and Authentication controllers only
//you will need to include any new public controller that uses the route pattern
_config.Routes.MapHttpRoute(
    name: "Public",
    routeTemplate: "{controller}/{action}/{id}",
    constraints: new  { controller = @"^(Help|Authentication)$" },
    defaults: new { controller="Help", action="Index", id = RouteParameter.Optional}
);


//Everything that is not Help or Authentication will use this route, which will check for the valid token you mention
//This route is defaulting to /Transaction/GetNewTaskId    
_config.Routes.MapHttpRoute(
     name: "AuthenticatedOnly",
     routeTemplate: "{controller}/{action}/{id}",
     defaults: new { controller = "Transaction", action="GetNewTaskId", id=RouteParameter.Optional},
     handler: tokenInspector
);
于 2013-08-27T14:27:47.983 回答
0

Use this approach for more flexible method access management

config.Routes.MapHttpRoute(
   name: "PublicMethods",
   routeTemplate: "api/{controller}/{action}",
   constraints: new {action = @"^(public)-(.)*$"},
   defaults: new {controller = "Account"}
);

config.Routes.MapHttpRoute(
   name: "PublicControllers",
   routeTemplate: "api/{controller}/{action}",
   constraints: new {controller = @"^(Environment|Account)$"},
   defaults: new {controller = "Account"}
);

config.Routes.MapHttpRoute(
   name: "AuthorizedUsersOnly",
   routeTemplate: "api/{controller}/{action}/{id}",
   defaults: new { id = RouteParameter.Optional },
   constraints: null,
   handler: tokenInspector
);

So I have few open for each user controllers and if it's necessary I make some methods accessible for not authorized users by adding 'public' prefix to action name

于 2014-11-21T20:39:28.877 回答