在本文中, 使用了基于组的权限管理, 并在Spring框架下利用HandlerInterceptorAdapter和Hibernate进行实现。
User的结构是:
1public 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的类来做:
1import 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。
