【IT168技术文档】几乎所有的web应用中都需要对访问者(用户)进行权限管理, 因为我们希望某些页面只对特定的用户开放, 以及某些操作只有符合身份的用户才能进行。这之中涉及到了身份验证和权限管理. 只有单用户系统和多用户单权限系统才不需要权限管理。
在本文中, 使用了基于组的权限管理, 并在Spring框架下利用HandlerInterceptorAdapter和Hibernate进行实现。
User的结构是:
1
public class User ...{
2
private int id;
3
private String name;
4
private String password;
5
private Set<String> groups = new HashSet<String>();
6
}
7
UserGroup表:
user:intgroup:String使用联合主键, 在Java中没有对应的类。
Hibernate映射文件是:
一切的身份验证交给一个继承HandlerInterceptorAdapter的类来做:
1
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
2
import org.springframework.web.util.UrlPathHelper;
3
import org.springframework.util.AntPathMatcher;
4
import org.springframework.util.PathMatcher;
5
...
6
public class AuthorizeInterceptor extends HandlerInterceptorAdapter ...{
7
private UrlPathHelper urlPathHelper = new UrlPathHelper();
8
private PathMatcher pathMatcher = new AntPathMatcher();
9
private Properties groupMappings;
10
/**//** * Attach URL paths to group. */
11
public void setGroupMappings(Properties groupMappings) ...{
12
this.groupMappings = groupMappings;
13
}
14
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception ...{
15
String url = urlPathHelper.getLookupPathForRequest(request);
16
String group = lookupGroup(url);
17
// 找出资源所需要的权限, 即组名
18
if(group == null)...{
19
// 所请求的资源不需要保护.
20
return true;
21
}
22
// 如果已经登录, 一个User实例被保存在session中.
23
User loginUser = (User)request.getSession().getAttribute("loginUser");
24
ModelAndView mav = new ModelAndView("system/authorizeError");
25
if(loginUser == null)...{
26
mav.addObject("errorMsg", "你还没有登录!");
27
throw new ModelAndViewDefiningException(mav);
28
}else...{
29
if(!loginUser.getGroups().contains(group))...{
30
mav.addObject("errorMsg", "授权失败! 你不在 <b>" + group + "</b> 组!");
31
throw new ModelAndViewDefiningException(mav);
32
} return true;
33
}
34
}
35
/**//* * 查看
36
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.lookupHandler()
37
* Ant模式的最长子串匹配法.
38
*/
39
private String lookupGroup(String url)...{
40
String group = groupMappings.getProperty(url);
41
if (group == null) ...{
42
String bestPathMatch = null;
43
for (Iterator it = this.groupMappings.keySet().iterator();it.hasNext();) ...{
44
String registeredPath = (String) it.next();
45
if (this.pathMatcher.match(registeredPath, url) && (bestPathMatch == null || bestPathMatch.length() <= registeredPath.length())) ...{
46
group = this.groupMappings.getProperty(registeredPath);
47
bestPathMatch = registeredPath;
48
}
49
}
50
}
51
return group;
52
}
53
}
54
下面我们需要在Spring的应用上下文配置文件中设置:
1
<bean id="authorizeInterceptor" class="net.ideawu.AuthorizeInterceptor">
2
<property name="groupMappings">
3
<value>
4
<!-- Attach URL paths to group -->
5
/admin/**//*=admin
6
</value>
7
</property>
8
</bean>
9
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
10
<property name="interceptors">
11
<list>
12
<ref bean="authorizeInterceptor" /> </list>
13
</property>
14
<property name="mappings">
15
<value>
16
/index.do=indexController /browse.do=browseController /admin/removeArticle.do=removeArticleController
17
</value>
18
</property>
19
</bean>
20
注意到"/admin/*=admin", 所以/admin目录下的所有资源只有在admin组的用户才能访问, 这样就不用担心普通访客删除文章了。使用这种方法, 你不需要在removeArticleController中作身份验证和权限管理, 一切都交给AuthorizeInterceptor。