Shiro之授权管理与授权的三种方式(1、编程方式,2、注解方式,3、jsp标签)-yellowcong

授权管理,三种方式,其中注解和jsp的方式在开发中用得比较的多,但是对于编程的方式完成注解,在实际开发中,用得不是特别多。这一节,讲解shiro如何完成授权的,授权操作,需要在Reaml中,实现doGetAuthorizationInfo 方法,多Reaml的情况下, 只要一个Reaml中满足条件,就会执行

源码地址

https://gitee.com/yellowcong/shior-dmeo/tree/master/test

Shiro的授权三种方式

1、编程方式
2、注解方式
3、jsp标签

授权

授权的时候,需要实现doGetAuthorizationInfo 这个方法,需要根据用户名来获取用户所属的权限和角色。

package com.yellowcong.shiro.realm;

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.UnknownAccountException;
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;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.yellowcong.service.RolePermissionService;
import com.yellowcong.service.UserRoleService;
import com.yellowcong.service.UserService;
import com.yellowcong.shiro.model.User;

/**
 * 创建日期:2017年9月23日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:用于授权操作
 */
public class SampleRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RolePermissionService rolePermissionService;

    /**
     * 用户授权,当用户访问需要有权限的页面的情况,需要访问这个方法来获取权限列表
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) {

        //用户名称
        Object username = paramPrincipalCollection.getPrimaryPrincipal();

        SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
        // 根据用户ID查询角色(role),放入到Authorization里。
        Set<String> roles = userRoleService.getRoleByName(username.toString());
        info.setRoles(roles);

        // 根据用户ID查询权限(permission),放入到Authorization里。
        Set<String> permissions = this.rolePermissionService.getPermissionByRole(roles);
        info.setStringPermissions(permissions);
        return info;
    }

    /**
     * 认证,用户登录
     * 登陆的时候,会调用这个
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) paramAuthenticationToken;

        //数据库中,查询用户的信息
        User user = userService.login(token.getUsername());

        // token返回的是一个数组,将char类型转化为String类型
        //这个是web前台传递过来的值
        //这个密码的比对是通过Shiro自己给我们完成的
        //密码是通过AuthenticatingRealm.getCredentialsMatcher 的方式来进行比对的
        String pswDate = new String(token.getPassword());

        //当用户为空的情况
        if(user == null){
            // 当没有用户的时候,抛出异常
            throw new UnknownAccountException();
        }

        //第一个参数:用户名/用户对象
        String username =token.getUsername();
        //第二个参数:用户的密码
        String password = user.getPassword();

        //第三个参数:盐值(这个盐是 username)
        ByteSource solt = null;

        //第四个参数:获取这个Realm的信息
        String realmName =this.getName();

        //他们拿到密码web的密码,同数据库获取到的密码进行比对操作
        return new SimpleAuthenticationInfo(username, password, solt,realmName);
    }

}

权限控制

1、基于代码实现权限管理

   Subject currentUser = SecurityUtils.getSubject();    
   if (currentUser.hasRole("administrator")) {    
       //拥有角色administrator  
   } else {    
       //没有角色处理  
   }    

2、jsp端,权限的处理

通过jsp的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> 默认显示用户名称
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%--shiro 标签 --%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>  
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>后台管理 - yellowcong</title>
  <script src="<%=request.getContextPath() %>/resources/plugins/jquery/jquery.min.js"></script>
</head>
<body class="layui-layout-body"  >

<shiro:hasRole name="admin">
<a href="<%=request.getContextPath() %>/user/admin">管理员</a><br/>
</shiro:hasRole>

<shiro:hasRole name="user">
<a href="<%=request.getContextPath() %>/user/user">普通用户</a><br/>
</shiro:hasRole>

<a href="<%=request.getContextPath() %>/user/loginOut">退出</a>
</body>
</html>

普通用户登录
这里写图片描述

管理员用户登录
这里写图片描述

3、基于注解的方式

注解 意义 案例
@RequiresAuthentication 验证用户是否登录
@RequiresUser 当前用户已经验证过了或则记住我了
@RequiresGuest 是否是游客身份
@RequiresRoles 判断subject中有aRoleName角色才可以访问方法someMethod @RequiresRoles({“admin”})
@RequiresPermissions 需要拥有权限 @RequiresPermissions({“file:read”, “write:aFile.txt”} )

案例

控制层

//只有管理员,才能执行这个方法
@RequestMapping("/admin/test")
public String adminTest(){
    shiroService.test();
    return "user/admin_test";
}

只能在 service 层添加权限的注解 如果放到Controller层,就不生效。

package com.yellowcong.service;

import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.stereotype.Service;

/**
 * 创建日期:2017/12/20<br/>
 * 创建时间:17:21:33<br/>
 * 创建用户:yellowcong<br/>
 * 机能概要:
 */
@Service("shiroService")
public class ShiroService {


    @RequiresRoles({"admin"})
    public void test() {
        System.out.println("执行了程序");
    }
}

普通用户访问
这里写图片描述

管理人员正常执行
这里写图片描述

@RequiresRoles({“admin”})不生效的问题

1、注解需要写在Service层

会遇到打死都不执行注解的问题,后来发现,如果把Shiro的注解写在SpringMvc的Controller层就不好用,需要写在Service层

2、需要将shiro生命周期配置在Spring-mvc.xml的配置文件中

 <!-- Shiro生命周期处理器-->
   <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

    <!-- AOP式方法级权限检查 -->  
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
        depends-on="lifecycleBeanPostProcessor">  
        <property name="proxyTargetClass" value="true" />  
    </bean>  

    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
        <property name="securityManager" ref="securityManager" />  
    </bean> 

这里写图片描述

阅读更多
版权声明:本文为博主yellowcong原创文章,未经博主允许不得转载。 https://blog.csdn.net/yelllowcong/article/details/78828044
文章标签: shiro
个人分类: shiro
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭