1. 程式人生 > >shiro springmvc整合第一步

shiro springmvc整合第一步

shiro 做為一個輕量級的安全認證,許可權框架,與spring有很好的相容性 具體shiro是什麼這裡不在多說 直接上程式碼

<filter>  
        <filter-name>shiroFilter</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
        <init-param>  
            <param-name>targetFilterLifecycle</param-name>  
            <param-value>true</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>shiroFilter</filter-name> 
        <url-pattern>/</url-pattern>  
    </filter-mapping> 

上面實在web.xml中配置shiro 的過濾器 這裡需要注意的是filter-name 標籤 裡面的名字必須和之後用到shiro 的bean 名字保持一致

既然用到這當然少不了 spring 的配置

  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
spring.xml 檔案配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="  
           http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
           http://www.springframework.org/schema/aop  
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">


  
<import resource="spring-shiro.xml"/>
</beans>

這裡是將spring.xml 和spring-shiro.xml 配置檔案寫在src 目錄下

spring-shiro.xml 配置

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"  
    default-lazy-init="true">  
  
 
    <!-- shiro安全管理器  設定cacheManage,下列屬性有實現CacheManagerAware介面的,都會自動注入快取管理器--> 
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
        <property name="realm" ref="myRealm" />  
        <property name="cacheManager" ref="cacheManager" />  
    </bean>  
  
    <!-- 專案自定義的Realm -->  
    <bean id="myShiroRealm" class="com.zyc.shiro.realm.MyRealm">  
        <property name="cacheManager" ref="cacheManager" />  
    </bean>  
  
    <!-- Shiro Filter -->  
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
        <property name="securityManager" ref="securityManager" />  //此屬性必須存在
        <property name="loginUrl" value="/login.do" />    //如果不存在預設呼叫web-inf 檔案下的login.jsp
        <property name="successUrl" value="/loginsuccess.do" />  //登入成功跳轉路徑
        <property name="unauthorizedUrl" value="/error.html" />  //沒有許可權跳轉路徑
       <property name="filters"> //此屬性可以省略 這裡配置主要可以通過直接提交表單驗證,就可以不用subject.login(token)手動呼叫了
<map>
<!-- 將自定義 的FormAuthenticationFilter注入shiroFilter中 -->
<entry key="authc" value-ref="formAuthenticationFilter" />
</map>
</property>
        <property name="filterChainDefinitions">  
            <value>  
                //這裡你可以設定是否需要認證
               /js/*=anon
                /logout = logout  
                /** = authc  
            </value>  
        </property>  
    </bean>  
  
    <!-- 使用者授權資訊Cache -->  
    <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />  
  
    <!-- 保證實現了Shiro內部lifecycle函式的bean執行 -->  
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />  
  
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
        <property name="securityManager" ref="securityManager" />  
    </bean>  
    
</beans>  
如果上面配置了filter 自定義的屬性那麼就需要實現一個bean
<bean id="formAuthenticationFilter"
class="com.zyc.interceptor.shiro.CustomFormAuthenticationFilter "> //自己實現的filter 需要繼承其他類FormAuthenticationFilter

<!-- 表單中賬號的input名稱 -->
<property name="usernameParam" value="loginname" /> //這裡的value 需要和登入的表單中的名稱儲存一直
<!-- 表單中密碼的input名稱 -->
<property name="passwordParam" value="password" />
<!-- 記住我input的名稱 -->
<property name="rememberMeParam" value="saveid" />
</bean>

下面看myRelam 類package com.zyc.shiro.realm;


import java.util.HashSet;
import java.util.Set;


import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;



public class MyRealm extends AuthorizingRealm {



/* 
 * 授權
 */
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 
        Set<String> roleNames = new HashSet<String>();  
        Set<String> permissions = new HashSet<String>();  
        roleNames.add("administrator");//新增角色
        permissions.add("user:all");  //新增許可權
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);  
        info.setStringPermissions(permissions);  
        return info;  
}


/* 
 * 登入驗證
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
 //連線資料庫從後臺獲取使用者資訊這裡就不連線資料庫了if(token.getUsername().equals("使用者名稱")){
return new SimpleAuthenticationInfo("使用者名稱", "密碼"(此密碼是從資料庫中獲得的), getName());  //如果驗證通過則返回資訊
}else{
throw new AuthenticationException();  
}
}


}

這裡就不在配置
"com.zyc.interceptor.shiro.CustomFormAuthenticationFilter類了 我們才用手動登入

及subject.login(token) 的方式登入

如在你要登入的地方呼叫

UsernamePasswordToken token = new UsernamePasswordToken(username, DecriptUtil.MD5(password));  //這裡需要將密碼進行加密 如果你在配置檔案中配置了加密則這裡就不 用瞭如果沒有 就需要加密
            Subject currentShiro= SecurityUtils.getSubject();  
            if (!currentShiro.isAuthenticated()){
            //使用shiro來驗證  
                currentShiro.login(token);//驗證角色和許可權  
            } 

最後在說一句退出的方法 currentShiro.logout(); 即可