shiro授权-SSM

先在数据库中建立相应的数据表,以及后面使用需要的sql语句

#建表脚本
CREATE TABLE t_sys_user
(
  userid INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID,主键',                                    
  username VARCHAR(10) UNIQUE NOT NULL COMMENT '用户账号',                                        
  PASSWORD VARCHAR(32) NOT NULL COMMENT '用户密码=MD5+盐加密',
  salt VARCHAR(32) NOT NULL COMMENT '盐',                                                    
  createdate TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期'                      
);

CREATE TABLE t_sys_role
(
  roleid INT PRIMARY KEY AUTO_INCREMENT COMMENT '角色ID,主键',                                   
  rolename VARCHAR(100) UNIQUE NOT NULL COMMENT '角色名称',                                                     
  description VARCHAR(100) COMMENT '角色描述'                                                    
);

CREATE TABLE t_sys_permission
(
  perid INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID,主键',                              
  pername VARCHAR(100) NOT NULL COMMENT '权限名称', 
  pid INT COMMENT '父编号',                                                       
  permission VARCHAR(100) NOT NULL COMMENT '权限字符串:例如:system:user:create:1'
);

CREATE TABLE t_sys_user_role
(
  urid INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID,主键',                                       
  userid INT NOT NULL COMMENT '用户ID',                                                      
  roleid INT NOT NULL COMMENT '角色ID'
);

CREATE TABLE t_sys_role_permission
(                                   
  roleid INT NOT NULL COMMENT '角色ID',                                                   
  perid INT NOT NULL COMMENT  '权限ID'
);


#数据添加

insert  into `t_sys_permission`(`perid`,`pername`,`pid`,`permission`) values (10,'书本管理',-1,''),(11,'系统管理',-1,''),(1001,'书本管理',10,'bookmanager:book:*'),(1002,'订单管理',10,'bookmanager:order:*'),(1101,'用户管理',11,'system:user:*'),(100101,'书本查询',1001,'bookmanager:book:query'),(100102,'书本新增',1001,'bookmanager:book:add'),(100103,'书本修改',1001,'bookmanager:book:edit'),(100104,'书本删除',1001,'bookmanager:book:del'),(110101,'用户查询',1101,'system:user:query'),(110102,'用户新增',1101,'system:user:add'),(110103,'用户修改',1101,'system:user:edit');

/*Data for the table `t_sys_role` */

insert  into `t_sys_role`(`roleid`,`rolename`,`description`) values (1,'管理员',NULL),(2,'高级用户',NULL),(3,'普通用户',NULL);

/*Data for the table `t_sys_role_permission` */

insert  into `t_sys_role_permission`(`roleid`,`perid`) values (1,1001),(1,100101),(1,100102),(1,100103),(1,100104),(1,1101),(1,110101),(1,110102),(1,110103),(2,100101),(2,100102);

/*Data for the table `t_sys_user` */

insert  into `t_sys_user`(`userid`,`username`,`password`,`salt`,`createdate`) values (1,'admin','c3b3ac764e1dbf4a1e4483f42c7140cb','af0111353776182a4f166e1d49a7dd2f','2018-11-26 15:02:42'),(2,'zhangsan','9c917b6f860eeb24361c75f27a236d6b','bcdf6f5c2237bdb440684b6c4ce943d4','2018-11-28 16:44:33');

/*Data for the table `t_sys_user_role` */

insert  into `t_sys_user_role`(`urid`,`userid`,`roleid`) values (1,1,1),(2,2,2);



select * from t_sys_user;
SELECT * FROM t_sys_user_role;
select * from t_sys_role;
select * from t_sys_role_permission;
select * from t_sys_permission;
#关系:用户->角色->权限
#前提:用户登录后,根据用户账号(唯一)获取角色和权限

#1.根据username获取用户对应的角色
select 
r.rolename
from 
t_sys_user u,t_sys_user_role ur,t_sys_role r
where
u.userid=ur.userid and ur.roleid=r.roleid
and u.username='zhangsan';
#2.根据username获取用户对象的角色权限

select 
p.permission
from 
t_sys_user u,t_sys_user_role ur,t_sys_role r,t_sys_role_permission rp,t_sys_permission p
where
u.userid=ur.userid and ur.roleid=r.roleid
and r.roleid=rp.roleid
and rp.perid=p.perid
and u.username='zhangsan';

定义mapper层的方法

 在相对应的xml中实现方法

 注意!!!如果是我这种传值请在方法参数添加注解@Param

如图:

然后在对应的Service中添加方法注意删除注解

如图:

然后在Serive的实现类中实现方法的调用

如图:

 

然后在自定义Real的安全数据源(采用数据库方式)中写入:

  @Autowired
    private ISysUserService sysUserService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录账号
        String username=principalCollection.getPrimaryPrincipal().toString();
//        根据username获取用户对应角色
        Set<String> roles=sysUserService.findRoles(username);
//        根据username获取用户对应的角色权限
        Set<String> permissions = sysUserService.findPermissions(username);
//      创建SimpleAuthorizationInfo
        SimpleAuthorizationInfo simple=new SimpleAuthorizationInfo();
//        填充用户的角色和权限
        simple.setRoles(roles);
        simple.setStringPermissions(permissions);
        return simple;
    }

在index.jsp页面中引入shiro

如图:

然后在想要区分权限的地方使用shiro的标签即可

如图: 

 启动项目

来到登录页面,我们先登录有权限的账号:

 登录成功后,我们来到首页,可以看到有权限的账号能看到被限制的部分

然后使用没有权限的普通用户账号:

我们能清晰的看到显示的内容少了很多:

 看看网页源代码:

发现在客户端根本就没有被限制的内容,并不是隐藏,这种使用标签的方式太暴力了 

所以介绍另一种方式:在spring-mvc.xml中开启注解


  <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
      depends-on="lifecycleBeanPostProcessor">
    <property name="proxyTargetClass" value="true"></property>
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
</bean>

然后在你需要使用的Controller.java中的相应方法上加入注解

@RequiresRoles("管理员")   //效果是限定身份是管理员才能使用

或者是:

@RequiresPermissions("bookmanager:book:update")//限定只有权限有bookmanager:book:update的才能使用

如图:

加入注解后启动项目,登录一个没有权限的账号,使用被限定了的查询功能

(因为不是标签,所以是在后台中调用时判断生效)

得到: 

什么也没有查到。 

通过Debug可以知道是因为不是管理员的原因

导致了异常,但是这里的全局异常处理并没有收集,所以此处的map集合是空的,所以此处既没有填充错误码,也没有填充错误信息,直接把空的map集合返回了

 

所以我们添加一个判断

 然后在来一遍上面的操作就会看到:

如果没效果,那么可能是缓存问题,重新启动项目可以解决 

 其他方法并不会受到影响。

使用有权限的账号进行相同的操作:

可以正常查询。

@RequiresRoles(value = {"管理员","高级用户"},logical = Logical.OR)   //限定身份是管理员或者高级用户才能使用
@RequiresRoles(value = {"管理员","高级用户"},logical = Logical.AND)   //限定身份是管理员并且也是高级用户才能使用,单独的一个身份无法使用

 

Shiro标签库

  guest标签 :验证当前用户是否为“访客”,即未认证(包含未记住)的用户
  user标签 :认证通过或已记住的用户
  authenticated标签 :已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在
  notAuthenticated标签 :未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户
  principal 标签 :输出当前用户信息,通常为登录帐号信息 
  hasRole标签 :验证当前用户是否属于该角色 
  lacksRole标签 :与hasRole标签逻辑相反,当用户不属于该角色时验证通过
  hasAnyRole标签 :验证当前用户是否属于以下任意一个角色
  hasPermission标签 :验证当前用户是否拥有指定权限
  lacksPermission标签 :与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过 

 Shiro注解

  @RequiresAuthenthentication:表示当前Subject已经通过login进行身份验证;即 Subjecj.isAuthenticated()返回 true
  @RequiresUser:表示当前Subject已经身份验证或者通过记住我登录的
  @RequiresGuest:表示当前Subject没有身份验证或者通过记住我登录过,即是游客身份
  @RequiresRoles(value = {"admin","user"},logical = Logical.AND):表示当前Subject需要角色admin和user
  @RequiresPermissions(value = {"user:delete","user:b"},logical = Logical.OR):表示当前Subject需要权限user:delete或者user:b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值