0

我有用于访问“派对”的 REST api,URL 如下所示:

/parties
/parties/{partyId}

使用 Spring 控制器和 @PathVariable 我能够实现这个接口。但是为了防止用户访问他们无权访问的各方,我必须为每个方法调用添加检查,这有点重复我自己,我可能会忘记在任何地方添加它:

@RequestMapping(value="/parties/{partyId}", method=RequestMethod.GET)
public @ResponseBody Party getParty(@PathVariable Integer partyId){
    authorizeForParty(partyId);
    ...

现在我想做的是创建一个检查,每次用户输入这样的 url 时都会调用它:

/parties/{partyId}/**

我该怎么做这样的事情?我是否必须创建一些 servlet 过滤器并自己解析 url?如果我必须解析 url,那么是否有至少可以简化它的工具?我希望有一种方法可以将方法添加到控制器,该方法将在方法之前调用,但仍可以使用 @PathVariables 等...

4

2 回答 2

2

我最终得到的是使用 Spring MVC 拦截器并以与 Spring 相同的方式解析路径变量。所以我为 REST url 定义了一个拦截器:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/parties/*/**" />
        <bean class="PartyAuthorizationInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

PartyAuthorizationInterceptor 必须实现 HandlerInterceptor,我们必须在其中实现 preHandle。它具有 HttpServletRequest 作为参数,因此我们可以获取请求 URL,但我们仍然必须从 url 中解析 partyId。在阅读了 Spring MVC 是如何做到的之后,我发现他们有一个名为 org.springframework.util.AntPathMatcher 的类。它可以从 URL 中读取路径变量并将值放在地图中。该方法称为 extractUriTemplateVariables。

所以结果看起来像这样:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String partyIdStr = new AntPathMatcher().extractUriTemplateVariables("/parties/{partyId}/**", request.getPathInfo()).get("partyId");
    ...

这使得解析几乎与在 MVC 控制器方法中使用 @PathVariable 一样简单。您仍然需要自己进行转换(例如 String -> Integer)。

现在,我可以在访问此拦截器中的一方的所有 url 上实现授权逻辑,并将该逻辑排除在各个控制器方法之外。没有我希望的那么容易,但它完成了工作。

于 2012-12-30T13:07:43.457 回答
1

您是否已经在应用程序中使用某种安全库,例如 Spring Security?

因为您要实现的逻辑类型是AccessDecisionVoter身份验证链中的经典案例。您只需将 API 置于 Spring Security 的保护之下,并将自定义检查作为安全链的一部分来实现。

但是,如果您根本不使用安全框架,那么实现 a 的想法HandlerInterceptor可能是最好的选择。但这将要求您(如您所提到的)考虑用户可能使用的各种混淆以获取对其他 URL 的访问权(例如,字母、../../模式等的 % 编码)。

于 2012-12-30T16:13:52.083 回答