【问题标题】:Web Api routing troubleWeb Api 路由问题
【发布时间】:2013-08-30 06:40:43
【问题描述】:

我有一个自托管的 Web API 项目,所以我必须使用 Yao's blog post 来使帮助页面正常工作。接下来,我必须保护我的一些方法免遭未经授权的使用。我已经实现了this idea

现在是有趣的部分。我有 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();

大概是这样的问题,不能这样回答,不过还是谢谢大家的努力!

问候,失眠_

【问题讨论】:

    标签: c# routing asp.net-web-api


    【解决方案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
    );
    

    【讨论】:

    • 感谢您的回答!我尝试了您建议的变体,但它导致了 2. 场景行为。
    • Help 和 Authenticatatioon 是您仅有的公共控制器吗?
    • 所有控制器都标记为public,任何用户都应该可以使用位于帮助和身份验证的方法,如果它们包含有效的令牌,则应检查对事务控制器的请求。
    • 在上面编辑了我的答案。请注意我实际上是在这个编辑器中输入代码,如果有任何拼写错误,请多多包涵。
    • HelpControllerBase 受到限制,它仅使用帮助页面的默认路由。不在默认路由上的任何其他控制器都不会包含在您的帮助页面中。因为您在路由中指定了 tokenExplorer,所以您不能将公共控制器和受限控制器放在同一路由中;这不灵活。但是,您可以在 tokenExplorer 中填充身份,然后在您的控制器和/或您的操作上使用 [Authorize] 属性。这是内置的授权机制。
    【解决方案2】:

    使用这种方法进行更灵活的方法访问管理

    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
    );
    

    所以我几乎没有为每个用户控制器打开,如果有必要,我可以通过在操作名称中添加“公共”前缀来让非授权用户可以访问一些方法

    【讨论】:

      猜你喜欢
      • 2014-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-17
      • 2013-01-24
      相关资源
      最近更新 更多