Shiro的三種受權(十二)

 

前提就是在Realm的受權方法中查詢出權限並返回List<String>形式

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        // 從 principals獲取主身份信息
        // 將getPrimaryPrincipal方法返回值轉爲真實身份類型(在上邊的doGetAuthenticationInfo認證經過填充到SimpleAuthenticationInfo中身份類型),
        ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal();

        // 根據身份信息獲取權限信息
        // 從數據庫獲取到權限數據
        List<SysPermission> permissionList = null;
        try {
            permissionList = sysService.findPermissionListByUserId(activeUser.getUserid());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 單獨定一個集合對象
        List<String> permissions = new ArrayList<String>();
        if (permissionList != null) {
            for (SysPermission sysPermission : permissionList) {
                // 將數據庫中的權限標籤 符放入集合
                permissions.add(sysPermission.getPercode());
            }
        }

        // 查到權限數據,返回受權信息(要包括 上邊的permissions)
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 將上邊查詢到受權信息填充到simpleAuthorizationInfo對象中
        simpleAuthorizationInfo.addStringPermissions(permissions);

        return simpleAuthorizationInfo;
    }

 

1.applicationContext-shiro.xml配置

解釋:訪問上面這個須要有item:edit權限。html

2.註解方法:

開啓controller類aop支持

在springmvc.xml中配置:  java

<!-- 開啓aop,對類代理 -->
    <aop:config proxy-target-class="true"></aop:config>
    <!-- 開啓shiro註解支持 -->
    <bean
        class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

 

  在controller方法中添加註解

 

3.JSP受權(頁面上根據權限設置菜單顯示與否)

Jsp頁面添加:spring

<%@ tagliburi="http://shiro.apache.org/tags" prefix="shiro" %>數據庫

 

標籤名稱apache

標籤條件(均是顯示標籤內容)session

<shiro:authenticated>mvc

登陸以後app

<shiro:notAuthenticated>jsp

不在登陸狀態時ide

<shiro:guest>

用戶在沒有RememberMe時

<shiro:user>

用戶在RememberMe時

<shiro:hasAnyRoles name="abc,123" >

在有abc或者123角色時

<shiro:hasRole name="abc">

擁有角色abc

<shiro:lacksRole name="abc">

沒有角色abc

<shiro:hasPermission name="abc">

擁有權限資源abc

<shiro:lacksPermission name="abc">

沒有abc權限資源

<shiro:principal>

顯示用戶身份名稱

                         <shiro:principal property="username"/>     顯示用戶身份中的屬性值

 

總結:

當調用controller的一個方法,因爲該 方法加了@RequiresPermissions("item:query") ,shiro調用realm獲取數據庫中的權限信息,看"item:query"是否在權限數據中存在,若是不存在就拒絕訪問,若是存在就受權經過。

 

當展現一個jsp頁面時,頁面中若是遇到<shiro:hasPermission name="item:update">,shiro調用realm獲取數據庫中的權限信息,看item:update是否在權限數據中存在,若是不存在就拒絕訪問,若是存在就受權經過。

 

 

 

還有一種狀況是有時候鏈接是在Ajax請求以後拼接到頁面的,有時候也須要根據權限進行判斷,項目中也遇到這種狀況:

思路:在頁面中定義一個JS全局變量,在shiro權限標籤裏面,若是有權限修改全局變量的值,在JS中根據全局變量的值判斷是否有權限

(1)頁面定義全局變量

<script>

var hasOperatingDepart=false;

<script>

(2)頁面用shiro標籤判斷是否有權限:(有權限會執行JS腳本改變全局變量的值)

<shiro:hasPermission name="department:operating">
<script>
hasOperatingDepart = true;
</script>
</shiro:hasPermission>

(3)JS拼接的時候根據全局變量判斷是否有權限:

		// 有刪除修改權限就顯示鏈接
		if (hasOperatingDepart) {
			str += '<a onclick="updateDepartment(this)" class="el_delButton">修改</a> ';
		} else {
			str += "-";
		}

  

 

 

有時候咱們須要在代碼中判斷用戶是否有某些權限;

        // 獲取用戶信息
        Subject currentUser = SecurityUtils.getSubject();
        boolean permitted = currentUser.isPermitted("exammanager:factory");// 判斷是否有全廠管理的權限,有就不添加部門ID,沒有就設爲當前Session中的部門ID
        String departmentId = permitted ? null : departmentIdSession;

 有時候咱們須要在代碼中判斷用戶是否有某些角色:

        // 獲取用戶信息
        Subject currentUser = SecurityUtils.getSubject();
        boolean hasRole = currentUser.hasRole("教研室");
        boolean hasRole2 = currentUser.hasRole("院長")

 

 

 

 

 

上面獲取的主體的權限碼是咱們在受權的時候塞進去的,固然咱們也能夠將角色碼也塞進去:

package cn.xm.jwxt.shiro;


import cn.xm.jwxt.bean.system.Permission;
import cn.xm.jwxt.bean.system.User;
import cn.xm.jwxt.service.system.UserService;
import cn.xm.jwxt.utils.ValidateCheck;
import org.apache.shiro.SecurityUtils;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

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

/**
 * @Author: qlq
 * @Description 自定義realm。根據上面傳下來的token去數據庫查信息,查到返回一個SimpleAuthenticationInfo,查不到返回null(用於shiro認證)
 * @Date: 21:56 2018/5/6
 */
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    // 設置realm的名稱
    @Override
    public void setName(String name) {
        super.setName("customRealm");
    }

    // realm的認證方法,從數據庫查詢用戶信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userCode=(String)token.getPrincipal();//獲取token的主身份(登陸的username
        User user = null;
        try {
            user =  userService.getUserByUserCode(userCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
        AuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
        return authenticationInfo;
    }
    // 用於受權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //0.下面方法principals.getPrimaryPrincipal()獲取的是在上面認證的時候裝進AuthenticationInfo的對象
        String userId=((User)(principals.getPrimaryPrincipal())).getUserid();
        SimpleAuthorizationInfo simpleAuthorizationInfo=null;
        try {
            simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            //1.設置全部的權限(注意權限是以字符串的形式保存的權限碼)
            List<Permission> permissions1 = userService.selectPermissionsByUserId(userId);//獲取全部權限碼
            Set<String> permissions = new HashSet<>();
            for(Permission permission:permissions1){
                if(ValidateCheck.isNotNull(permission.getPermissioncode())){
                    permissions.add(permission.getPermissioncode());
                }
            }
            if (permissions != null && permissions.size()>0) {
                simpleAuthorizationInfo.setStringPermissions(permissions);
            }
            //2.設置角色,角色也是以字符串的形式表示(這裏存的是角色名字)
            Set<String> userRoleNames = userService.getUserRoleNameByUserId(userId);
            if(userRoleNames != null && userRoleNames.size()>0){
                simpleAuthorizationInfo.setRoles(userRoleNames);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return simpleAuthorizationInfo;
    }

}

 

 

 

 

獲取用戶信息

@RequestMapping("/first.action")
        public String first(Model model)throws Exception{
            
            //從shiro的session中取activeUser
            Subject subject = SecurityUtils.getSubject();
            //取身份信息
            ActiveUser activeUser = (ActiveUser) subject.getPrincipal();
            //經過model傳到頁面
            model.addAttribute("activeUser", activeUser);
            
            return "/first";
        }
相關文章
相關標籤/搜索