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权限。

2.注解方法:

开启controller类aop支持

在springmvc.xml中配置:  

<!-- 开启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页面添加:

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

 

标签名称

标签条件(均是显示标签内容)

<shiro:authenticated>

登录之后

<shiro:notAuthenticated>

不在登录状态时

<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 οnclick="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";
        }

 

转载于:https://www.cnblogs.com/qlqwjy/p/7257616.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值