在几乎所有的web应用中都需要对访问者(用户)进行权限管理
因为我们希望某些页面只对特定的用户开放
以及某些操作只有符合身份的用户才能进行
这之中涉及到了身份验证和权限管理
只有单用户系统和多用户单权限系统才不需要权限管理
在本文中 使用了基于组的权限管理 并在Spring框架下利用HandlerInterceptorAdapter和Hibernate进行实现
User的结构是:
public class User {
private int id;
private String name;
private String password;
private Set<String> groups = new HashSet<String>();
}
UserGroup表:
user:intgroup:String使用联合主键 在Java中没有对应的类
Hibernate映射文件是:
<hibernatemapping autoimport=true defaultlazy=false>
<class name=netideawuUser table=User>
<cache usage=readwrite />
<id name=id column=id>
<generator class=native/>
</id>
<property name=name column=name/>
<property name=password column=password/>
<set name=groups table=UserGroup cascade=saveupdate lazy=false>
<key column=user />
<element column=`group` type=string />
</set>
</class>
</hibernatemapping>
一切的身份验证交给一个继承HandlerInterceptorAdapter的类来做:
import orgspringframeworkwebservlethandlerHandlerInterceptorAdapter;
import orgspringframeworkwebutilUrlPathHelper;
import orgspringframeworkutilAntPathMatcher;
import orgspringframeworkutilPathMatcher;
public class AuthorizeInterceptor extends HandlerInterceptorAdapter {
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private Properties groupMappings;
/** * Attach URL paths to group */
public void setGroupMappings(Properties groupMappings) {
thisgroupMappings = groupMappings;
}
public boolean preHandle(HttpServletRequest request HttpServletResponse response Object handler) throws Exception {
String url = urlPathHelpergetLookupPathForRequest(request);
String group = lookupGroup(url);
// 找出资源所需要的权限 即组名
if(group == null){
// 所请求的资源不需要保护
return true;
}
// 如果已经登录 一个User实例被保存在session中
User loginUser = (User)requestgetSession()getAttribute(loginUser);
ModelAndView mav = new ModelAndView(system/authorizeError);
if(loginUser == null){
mavaddObject(errorMsg 你还没有登录!);
throw new ModelAndViewDefiningException(mav);
}else{
if(!loginUsergetGroups(ntains(group)){
mavaddObject(errorMsg 授权失败! 你不在 <b> + group + </b> 组!);
throw new ModelAndViewDefiningException(mav);
} return true;
}
}
/* * 查看
orgspringframeworkwebservlethandlerAbstractUrlHandlerMappinglookupHandler()
* Ant模式的最长子串匹配法
*/
private String lookupGroup(String url){
String group = groupMappingsgetProperty(url);
if (group == null) {
String bestPathMatch = null;
for (Iterator it = thisgroupMappingskeySet(erator();ithasNext();) {
String registeredPath = (String) itnext();
if (thispathMatchermatch(registeredPath url) && (bestPathMatch == null || bestPathMatchlength() <= registeredPathlength())) {
group = thisgroupMappingsgetProperty(registeredPath);
bestPathMatch = registeredPath;
}
}
}
return group;
}
}
下面我们需要在Spring的应用上下文配置文件中设置:
<bean id=authorizeInterceptor class=netideawuAuthorizeInterceptor>
<property name=groupMappings>
<value>
<! Attach URL paths to group >
/admin/*=admin
</value>
</property>
</bean>
<bean id=simpleUrlHandlerMapping class=orgspringframeworkwebservlethandlerSimpleUrlHandlerMapping>
<property name=interceptors>
<list>
<ref bean=authorizeInterceptor /> </list>
</property>
<property name=mappings>
<value>
/indexdo=indexController /browsedo=browseController /admin/removeArticledo=removeArticleController
</value>
</property>
</bean>
注意到/admin/*=admin 所以/admin目录下的所有资源只有在admin组的用户才能访问 这样就不用担心普通访客删除文章了使用这种方法 你不需要在removeArticleController中作身份验证和权限管理 一切都交给AuthorizeInterceptor