posts - 431,  comments - 344,  trackbacks - 0

          在幾乎所有的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:int
          group: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.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.

          posted on 2006-12-19 14:40 周銳 閱讀(523) 評論(0)  編輯  收藏 所屬分類: Spring
          主站蜘蛛池模板: 南皮县| 庐江县| 长宁县| 临澧县| 河东区| 邓州市| 修文县| 松原市| 平潭县| 崇州市| 蓬溪县| 依兰县| 孝昌县| 新田县| 集贤县| 长汀县| 辽阳市| 四川省| 县级市| 南召县| 南丰县| 长汀县| 麻阳| 杨浦区| 伊宁县| 伊金霍洛旗| 衡阳县| 黔南| 长顺县| 腾冲县| 招远市| 边坝县| 马山县| 孝感市| 红安县| 长沙市| 石狮市| 青川县| 新津县| 阳原县| 德清县|