shiro

權限控制

  常見的權限控制

    1\URL 攔截權限控制

通過攔截器或者過濾器攔截客戶端發送的請求,在攔截器或者過濾器中判斷當前用戶是否具有訪問權限有就放行,沒有權限 跳轉到權限不足的提示頁面

2\方法註解權限控制

基於代理技術實現 有代理對象進行權限校驗

  權限數據模型

1\權限表

2\角色表

就是權限的集合

3\用戶表

4\角色權限關係表

5\用戶角色關係表

shrio

核心功能

1\認證

2\授權

3\會話管理

4\加密

Authentication:身份認證 / 登錄,驗證用戶是不是擁有相應的身份;


Authorization:授權,即權限驗證,驗證某個已認證的用戶是否擁有某個權限;即判斷用戶是否能做事情,常見的如:驗證某個用戶是否擁有某個角色。或者細粒度的驗證某個用戶對某個資源是否具有某個權限;

maven 引用:

   

   <!-- shiro依賴包 --> 
        <dependency>  
            <groupId>org.apache.shiro</groupId>  
            <artifactId>shiro-core</artifactId>  
            <version>1.2.3</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.shiro</groupId>  
            <artifactId>shiro-spring</artifactId>  
            <version>1.2.3</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.shiro</groupId>  
            <artifactId>shiro-cas</artifactId>  
            <version>1.2.3</version>  
            <exclusions>  
                <exclusion>  
                    <groupId>commons-logging</groupId>  
                    <artifactId>commons-logging</artifactId>  
                </exclusion>  
            </exclusions>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.shiro</groupId>  
            <artifactId>shiro-web</artifactId>  
            <version>1.2.3</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.shiro</groupId>  
            <artifactId>shiro-ehcache</artifactId>  
            <version>1.2.3</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.shiro</groupId>  
            <artifactId>shiro-quartz</artifactId>  
            <version>1.2.3</version>  
        </dependency> 
        <!-- shiro end -->

Application Code

應用程序代碼 開發人員開發

Subject

框架提供的接口 代表當前用戶對象

SecurityManager

框架提供的接口 代表安全管理器對象 ***********

Realm

開發人員可以編寫,框架也提供一些 類似DAO 用於訪問權限數據

使用 

1\在項目中引入maven 依賴

2\在web.xml 配置一個過濾器

<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3\在spring 配置文件中配置beanid和上面的過濾器的名稱一樣

<!-- 配置shiro 框架的過濾器工廠對象  -->

<bean name="shiroFilter"  class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
    <!-- 注入安全管理器對象 -->
    <property name="securityManager" ref="securityManager"></property>
    <!-- 注入登錄頁面 -->
    <property name="loginUrl" value="/index.jsp"></property>
    <!-- 注入登錄成功頁面 -->
    <!-- <property name="successUrl" value="/index.jsp"></property> -->
    <!-- 注入無權限頁面 -->
    <property name="unauthorizedUrl" value="/error.jsp"></property>
    <!-- 注入URL攔截規則 -->
    <property name="filterChainDefinitions">
        <value>
        /css/** = anon<!--css 放行 -->
        /js/** = authc<!-- js放行 -->
        /images/** = anon<!-- 圖片放行 -->
        /validatecode.jsp* = anon<!-- 驗證碼放行 -->
        /index.jsp = anon<!-- 主頁放行 -->
        /toLogin.do = anon<!-- 去登錄頁面請求 -->
        /user/login.do = anon<!-- 登錄請求 -->
        /user/** = perms["user-list"]<!-- staff的一切請求 -->
        /page.do = perms["page-list"]<!-- staff的一切請求 -->
        /* = authc <!-- 其他的一切請求 -->
        </value>
    </property>
</bean>
<!-- 註冊安全管理器對象 -->
<bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!-- 注入realm -->
    <property name="realm" ref="bosRealm"></property>
</bean>
<!-- 註冊realm -->
<bean name="bosRealm" class="com.stevezong.bos.realm.BosRealm"></bean>

過濾器名稱過濾器類描述

anonorg.apache.shiro.web.filter.authc.AnonymousFilter匿名過濾器

authcorg.apache.shiro.web.filter.authc.FormAuthenticationFilter當前用戶是否已經登錄

authcBasicorg.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter基本http驗證過濾,如果不通過,跳轉屋登錄頁面

logoutorg.apache.shiro.web.filter.authc.LogoutFilter登錄退出過濾器

noSessionCreationorg.apache.shiro.web.filter.session.NoSessionCreationFilter沒有session創建過濾器

permsorg.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter權限過濾器

portorg.apache.shiro.web.filter.authz.PortFilter端口過濾器,可以設置是否是指定端口如果不是跳轉到登錄頁面

restorg.apache.shiro.web.filter.authz.HttpMethodPermissionFilterhttp方法過濾器,可以指定如post不能進行訪問等

rolesorg.apache.shiro.web.filter.authz.RolesAuthorizationFilter角色過濾器,判斷當前用戶是否指定角色

sslorg.apache.shiro.web.filter.authz.SslFilter請求需要通過ssl,如果不是跳轉回登錄頁

userorg.apache.shiro.web.filter.authc.UserFilter如果訪問一個已知用戶,比如記住我功能,走這個過濾器


4\登錄Controller

//使用shiro 框架提供的方式進行認證操作
Subject subject = SecurityUtils.getSubject();//獲取當前用戶對象,狀態爲:未認證
AuthenticationToken token = new UsernamePasswordToken(username, MD5Utils.md5(password));
try {
    subject.login(token);
} catch (Exception e) {
    e.printStackTrace();
    result = "login";
}
user = (User) subject.getPrincipal();
session.setAttribute("user", user);
session.setMaxInactiveInterval(60*60*24);
result = "redirect:../pages_common_index.do";


5\寫Realm

                Exception 類型:

沒有這個用戶名

UnknownAccountException

密碼錯誤

IncorrectCredentialsException

package com.stevezong.bos.realm;
import javax.annotation.Resource;
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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import com.stevezong.bos.dao.UserMapper;
import com.stevezong.bos.entity.User;
public class BosRealm  extends  AuthorizingRealm{
    @Resource
    UserMapper userMapper; 
    //認證方法
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    System.out.println("自定義Realm");
    //根據用戶名查詢數據庫中的密碼
    //將AuthenticationToken 強轉爲  UsernamePasswordToken 方便使用
    UsernamePasswordToken passwordToken  = (UsernamePasswordToken) token; 
    //根據用戶名查詢數據中的User對象
    User user = userMapper.findByUsername(passwordToken.getUsername());
    if(user == null) {
        //頁面輸入的用戶名不存在
        return null;
    }else {
        //簡單認證信息對象(user對象,數據庫中的密碼,任意字符串)
        AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
        //框架負責對比數據庫中的密碼和頁面輸入的密碼是否一致
        return info;
    }
}
//授權方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
    // TODO  後期需要修改爲根據當前登錄永固查詢數據庫獲取實際對應的權限
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    info.addStringPermission("staff-list");
    return info;
    }
}

shiro 註解

  1\      

    <!-- 開啓shiro的註解支持 -->
<bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
    <!-- 必須改爲true,即使用cglib方式爲Action創建代理對象。默認值爲false,使用JDK創建代理對象,會造成問題 -->
    <property name="proxyTargetClass" value="true"></property>
</bean>
<!-- 使用shiro框架提供的切面類,用於創建代理對象 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></bean>


  2\在對應的方法上加上註解

@RequiresPermissions("權限名稱")

package com.stevezong.bos.controller;
import javax.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.stevezong.bos.service.StaffService;
import com.stevezong.bos.utils.BosResult;
@Controller
@RequestMapping("/staff")
public class StaffDelController {
    @Resource(name = "staffService")
    StaffService staffService;
    @RequestMapping("/del.do")
    @ResponseBody
    @RequiresPermissions("staff-delete")
    public BosResult<Object> del(String ids){
        BosResult<Object> result = new BosResult<Object>();
        String[] idsArr = ids.split(",");
        int[] resultArr = new int[idsArr.length];
        for(int i = 0; i<idsArr.length;i++) {
            resultArr[i] = staffService.updateDeltagById(idsArr[i]);
        }
        result.setStatus(0);
        result.setMsg("修改完成");
        result.setData(resultArr);
        return result;
    }
}

  3\在ssm 框架中捕獲shiro 的權限不足異常

shiro jsp 標籤庫

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
用戶是否有這個權限
<shiro:hasPermission name="權限名">js,jsp,html 都可以</shiro:hasPermission>
<shiro:hasPermission name="staff-list">
{
id : 'button-delete',
text : '作廢',
iconCls : 'icon-cancel',
handler : doDelete
}, 
</shiro:hasPermission>

權限數據管理

曾刪改查

初始化權限數據

添加權限數據

權限分頁查詢


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章