在几乎所有的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映射文件是:
| <hibernate-mapping auto-import="true" default-lazy="false"> <class name="net.ideawu.user" table="user"> <cache usage="read-write" /> <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="save-update" lazy="false"> <key column="user" /> <element column="`group`" type="string" /> </set> </class> </hibernate-mapping> |
一切的身份验证交给一个继承handlerinterceptoradapter的类来做:
| import org.springframework.web.servlet.handler.handlerinterceptoradapter; import org.springframework.web.util.urlpathhelper; import org.springframework.util.antpathmatcher; import org.springframework.util.pathmatcher; ... 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) { this.groupmappings = groupmappings; } public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { string url = urlpathhelper.getlookuppathforrequest(request); string group = lookupgroup(url); // 找出资源所需要的权限, 即组名 if(group == null){ // 所请求的资源不需要保护. return true; } // 如果已经登录, 一个user实例被保存在session中. user loginuser = (user)request.getsession().getattribute("loginuser"); modelandview mav = new modelandview("system/authorizeerror"); if(loginuser == null){ mav.addobject("errormsg", "你还没有登录!"); throw new modelandviewdefiningexception(mav); }else{ if(!loginuser.getgroups().contains(group)){ mav.addobject("errormsg", "授权失败! 你不在 <b>" + group + "</b> 组!"); throw new modelandviewdefiningexception(mav); } return true; } } /* * 查看 org.springframework.web.servlet.handler.abstracturlhandlermapping.lookuphandler() * ant模式的最长子串匹配法. */ private string lookupgroup(string url){ string group = groupmappings.getproperty(url); if (group == null) { string bestpathmatch = null; for (iterator it = this.groupmappings.keyset().iterator();it.hasnext();) { string registeredpath = (string) it.next(); if (this.pathmatcher.match(registeredpath, url) && (bestpathmatch == null || bestpathmatch.length() <= registeredpath.length())) { group = this.groupmappings.getproperty(registeredpath); bestpathmatch = registeredpath; } } } return group; } } |
下面我们需要在spring的应用上下文配置文件中设置:
| <bean id="authorizeinterceptor" class="net.ideawu.authorizeinterceptor"> <property name="groupmappings"> <value> <!-- attach url paths to group --> /admin/*=admin </value> </property> </bean> <bean id="simpleurlhandlermapping" class="org.springframework.web.servlet.handler.simpleurlhandlermapping"> <property name="interceptors"> <list> <ref bean="authorizeinterceptor" /> </list> </property> <property name="mappings"> <value> /index.do=indexcontroller /browse.do=browsecontroller /admin/removearticle.do=removearticlecontroller </value> </property> </bean> |
注意到"/admin/*=admin", 所以/admin目录下的所有资源只有在admin组的用户才能访问, 这样就不用担心普通访客删除文章了。使用这种方法, 你不需要在removearticlecontroller中作身份验证和权限管理, 一切都交给authorizeinterceptor。
闽公网安备 35060202000074号