我有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?如果我必须解析网址,那么至少有哪些工具可以让它变得简单?我希望有一种方法可以在控制器中添加一个方法,该方法可以在方法之前调用,但仍然可以使用@PathVariables等...
答案 0 :(得分: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 Controller方法中使用@PathVariable一样简单。您仍然需要自己进行转换(例如String - &gt; Integer)。
现在,我可以在访问此拦截器中的一方的所有URL上实现授权逻辑,并将该逻辑保留在各个控制器方法之外。并不像我希望的那样容易,但它完成了工作。
答案 1 :(得分:1)
您是否已在应用程序中使用某种安全库,例如: G。春季安全?
因为您要实现的逻辑类型是身份验证链中AccessDecisionVoter
的典型案例。您只需将您的API置于Spring Security的保护之下,并将自定义检查作为安全链的一部分进行实施。
如果您根本不使用安全框架,那么实现HandlerInterceptor
的想法可能是最佳选择。但它需要您(如您所述)考虑用户可能使用的各种混淆,以获取对其他URL的访问权限(例如,字母的%加密,../../
模式等。)。 p>