單點登錄cas與權限管理框架shiro集成——普通web項目方式 – JAVA編程語言程序開發技術文章

由於項目需要做權限管理的功能,最先想到的是spring security,它是個功能強大的安全管理框架,不過它的復雜性和學習曲線之曲折讓人生畏,轉而尋求其它解決方案,知道另外一個項目組的人使用shiro做權限管理後就瞭解瞭下這個框架,發現比spring security簡潔多瞭,於是就打算使用這個框架,首先嘛,當然是要和現在的系統進行集成,現在系統采用cas來做登錄驗證,所以先把cas和shiro進行集成。查看shiro官網,發現有個cas模塊,下載試用,下面是集成方法,假設你已經搭建好cas服務器(具體搭建細節自己google百度下)
我是用maven管理項目的,先引入shiro的jar包
[html] <dependency>
     <groupId>org.apache.shiro</groupId>
     <artifactId>shiro-cas</artifactId>
     <version>1.2.0</version>
 </dependency>
 <dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-cas</artifactId>
  <version>1.2.0</version>
 </dependency>
 配置web.xml,添加shiro過濾器
[html] <filter>
         <filter-name>shiroFilter</filter-name>
         <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
         <init-param>
             <param-name>configPath</param-name>
             <param-value>classpath:META-INF/shiro/shiro.ini</param-value>
         </init-param>
     </filter>
     
     <filter-mapping>
         <filter-name>shiroFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
 <filter>
   <filter-name>shiroFilter</filter-name>
   <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
   <init-param>
    <param-name>configPath</param-name>
    <param-value>classpath:META-INF/shiro/shiro.ini</param-value>
   </init-param>
  </filter>
 
  <filter-mapping>
   <filter-name>shiroFilter</filter-name>
   <url-pattern>/*</url-pattern>
  </filter-mapping>
其中shiro.ini為shiro配置文件,可以根據具體情況指定其路徑。
shiro.ini配置
[plain] [main]
 casFilter = org.apache.shiro.cas.CasFilter
 #配置驗證錯誤時的失敗頁面
 casFilter.failureUrl = /error.jsp
 
 #配置casRealm
 casRealm = org.apache.shiro.cas.CasRealm
 casRealm.defaultRoles = ROLE_USER
 casRealm.casServerUrlPrefix = https://www.cas.com
 #客戶端的回調地址設置,必須和下面的shiro-cas過濾器攔截的地址一致
 casRealm.casService = /shiro-cas
 
 #如果要實現cas的remember me的功能,需要引入下面兩個配置
 casSubjectFactory = org.apache.shiro.cas.CasSubjectFactory
 securityManager.subjectFactory = $casSubjectFactory
 
 #設定角色的登錄鏈接,這裡為cas登錄頁面的鏈接可配置回調地址
 roles.loginUrl = https://www.<span style="color:#000000;">cas</span>.com/login?service=https://shop.youboy.com:8080/cshop/shiro-cas
 
 [urls]
 #設定shiro-cas過濾器攔截的地址
 /shiro-cas = casFilter
 /admin/** = roles[ROLE_USER]
 /** = anon
 [main]
 casFilter = org.apache.shiro.cas.CasFilter
 #配置驗證錯誤時的失敗頁面
casFilter.failureUrl = /error.jsp
#配置casRealm
 casRealm = org.apache.shiro.cas.CasRealm
 casRealm.defaultRoles = ROLE_USER
 casRealm.casServerUrlPrefix = https://www.cas.com
 #客戶端的回調地址設置,必須和下面的shiro-cas過濾器攔截的地址一致
casRealm.casService = https://www.example.com/shiro-cas
#如果要實現cas的remember me的功能,需要引入下面兩個配置
casSubjectFactory = org.apache.shiro.cas.CasSubjectFactory
 securityManager.subjectFactory = $casSubjectFactory
#設定角色的登錄鏈接,這裡為cas登錄頁面的鏈接可配置回調地址
roles.loginUrl = https://www.<span style="color:#000000;">cas</span>.com/login?service=https://shop.youboy.com:8080/cshop/shiro-cas
[urls]
 #設定shiro-cas過濾器攔截的地址
/shiro-cas = casFilter
 /admin/** = roles[ROLE_USER]
 /** = anon
 這裡需要註意的是casRealm.casService設置的回調地址必須和下面casFilter的地址保持一致,否則無法驗證成功。更多有關shiro的配置可以參考官方文檔
這樣如果訪問www.example.com/admin/index.html時,如果沒登錄就會跳到cas去登錄,登錄成功後跳轉回當前頁面。
如果想獲得cas返回的更多用戶的信息,比如:用戶名,用戶id,用戶郵箱等,可以添加一個過濾器,這個過濾器必須在shiro的過濾器後面,否則獲取不到相關的信息。過濾器代碼如下:
[java] public void doFilter(ServletRequest request, ServletResponse response,
       FilterChain chain) throws IOException, ServletException {
     
     PrincipalCollection principalCollection = SecurityUtils.getSubject()
         .getPrincipals();
     
     if (principalCollection != null) {      
       List principals = principalCollection.asList();
       // 這裡獲取到的list有兩個元素, 
       //一個是cas返回來的用戶名,舉例是aaa, 
       //一個是cas返回的更多屬性的map對象,舉例是{uid:aaa,username:aaa,email:aaa} 
       //通過principals.get(1)來獲得屬性集合的map對象 
       Map<String,String> attributes = (Map<String,String>) principals.get(1);
       if (principals != null) {
         String email = attributes.get("email");
         String username = attributes.get("username");
         String uid = attributes.get("uid");
         //對獲取到的信息進行再處理 
       }
     }    
     chain.doFilter(request, response);
   }
 public void doFilter(ServletRequest request, ServletResponse response,
       FilterChain chain) throws IOException, ServletException {
   
     PrincipalCollection principalCollection = SecurityUtils.getSubject()
         .getPrincipals();
   
     if (principalCollection != null) {    
       List principals = principalCollection.asList();
       // 這裡獲取到的list有兩個元素,
      //一個是cas返回來的用戶名,舉例是aaa,
      //一個是cas返回的更多屬性的map對象,舉例是{uid:aaa,username:aaa,email:aaa}
       //通過principals.get(1)來獲得屬性集合的map對象
      Map<String,String> attributes = (Map<String,String>) principals.get(1);
       if (principals != null) {
         String email = attributes.get("email");
         String username = attributes.get("username");
         String uid = attributes.get("uid");
         //對獲取到的信息進行再處理
      }
     }  
     chain.doFilter(request, response);
   }
 獲取到信息就可以把它設置到session或怎樣由你定。
摘自laigood12345的專欄
 

發佈留言