Shiro過濾器


Shiro內置過濾器

認證相關過濾器:

anon(不需要任何認證直接可以訪問),authBasic(也就是httpBasic),authc(需要認證之后才可以訪問),user(需要當前存在用戶才可以訪問),logout(退出)

授權相關的過濾器:

perms(后面跟[ ] 里面加參數,表示具備一些權限才可以訪問),roles(與前者相似),ssl(要求是安全的協議才可以訪問,比如https),port(后面跟[ ] 里面放端口,必須是指定端口的才可以訪問)

(ps:ssl與port用的比較少)


 

 測試一下以上部分過濾器:

    @RequestMapping(value = "/testRole",method = RequestMethod.GET)
    @ResponseBody
    public String testRole(){
        return "test Role success";
    }
@RequestMapping(value = "/testRole1",method = RequestMethod.GET) @ResponseBody public String testRole1(){ return "test Role success"; }
   @RequestMapping(value
= "/testPerms",method = RequestMethod.GET) @ResponseBody public String testPerms(){ return "testPerms success"; } @RequestMapping(value = "/testPerms1",method = RequestMethod.GET) @ResponseBody public String testPerms1(){ return "testPerms1 success"; }

在spring.xml中配置一下:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <!--登錄頁的url-->
        <property name="loginUrl" value="login.html"/>
        <!--未認證的跳轉頁面-->
        <property name="unauthorizedUrl" value="403.html" />
        <!--過濾器鏈//從上往下匹配攔截認證,-->
        <property name="filterChainDefinitions">
            <value>
                <!--登錄頁面不需要攔截-->
                /login.html = anon
                <!--提交登錄請求的url也不許要攔截-->
                /subLogin = anon
                /testRole = roles["admin"]
                /testRole1 = roles["admind","admin1"]
                /testPerms = perms["user:delete"]
                /testPerms1 = perms["user:delete","user:update"]
                <!--登錄頁面以外的需要攔截認證-->
                /* = authc


            </value>
        </property>

    </bean>

我的權限表如下:

1.先是訪問testRole:

說明登錄賬戶具備角色admin

2.訪問testRole1

跳轉

 

3.訪問testPerms  與一個相同

 

 4.testPerms1也一樣

都ok。

 

這里配置的攔截

 /testRole1 = roles["admind","admin1"]
必須同時擁有兩種角色才有權限訪問,那么如何讓登錄用戶擁有其中一個角色就可以訪問呢,這就需要自定義Filter了,
這之前需要先導入Servlet相關的依賴,不然方法會報紅:
     <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.4</version>
            <scope>provided</scope>
        </dependency>
自定義Filter:
public class RolesOrFilter extends AuthorizationFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest,
              ServletResponse servletResponse, Object o) throws Exception {
        //先或得到主體
        Subject subject = getSubject(servletRequest, servletResponse);
        //強轉String類型數組
        String[] roles = (String[])o;
        if (roles == null || roles.length == 0){
            return true;
        }
        //若不為空,遍歷一下數組
        for (String role : roles) {
            //如果一經發現數組里有指定角色時,立即返回true
            if (subject.hasRole(role)){
                return true;
            }
        }
        return false;
    }
}

接着要去spring.xml配置注入自定義Filter:

   <!--創建注入自定義Filter-->
    <bean class="com.yunyun.filter.RolesOrFilter" id="rolesOrFilter"/>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <!--登錄頁的url-->
    <property name="loginUrl" value="login.html"/>
    <!--未認證的跳轉頁面-->
    <property name="unauthorizedUrl" value="403.html" />
    <!--過濾器鏈//從上往下匹配攔截認證,-->
    <property name="filterChainDefinitions">
        <value>
            <!--登錄頁面不需要攔截-->
            /login.html = anon
            <!--提交登錄請求的url也不許要攔截-->
            /subLogin = anon
            <!--/testRole = roles["admin"]-->
            /testRole2 = rolesOr["admin","admin1"]
            <!--/testPerms = perms["user:delete"]-->
            <!--/testPerms1 = perms["user:delete","user:update"]-->
            <!--登錄頁面以外的需要攔截認證-->
            /* = authc
        </value>
    </property>
    <property name="filters">
        <util:map>
            <entry key="rolesOr" value-ref="rolesOrFilter"/>
        </util:map>
    </property>
</bean>

    <!--創建注入自定義Filter-->
    <bean class="com.yunyun.filter.RolesOrFilter" id="rolesOrFilter"/>

在controller中添加:

@RequestMapping(value = "/testRole2",method = RequestMethod.GET)
    @ResponseBody
    public String testRole2(){
        return "test Role2 success";
    }

這里Controller層要注意,我發現加了@RequiresRoles("admin1")注解的方法,優先級要高於你自定義的攔截器,也就是說,只能用一個,不能都用= =。不知道這么理解有沒有問題,但是之前就沒注意,倆個一起用在同一個方法上,一直報錯

Subject does not have role [admin1]

,后來重寫了一個方法,不加注解,只用自定義的filter,就完全沒有問題了。

運行效果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM