目录
一、授权角色,权限
UserMapper.xml 添加查询方法
UserMapper
UserBiz
UserBizImpl
MyRealm 重新MyRealm 编写授权方法
配置文件 applicationContext-shiro.xml
二、shiro注解式开发
常用注解介绍
注解的使用
小结:
1.授权
2.注解式开发
本期代码内容同样基于上一期博客代码内容
图中的五张表对应着数据库中这五张表中的内容
授角色:用户具备哪些角色 查询zdm
select roleid from t_shiro_user u,t_shiro_user_role ur
where u.userid = ur.userid and username='zdm'
授权限:用户具备哪些权限
select rp.perid from t_shiro_user u,t_shiro_user_role ur,t_shiro_role_permission rp
where u.userid = ur.userid and ur.roleid = rp.roleid and u.username='ls'
授权步骤:
1.Mapper层、service层
2.shiro的授权方法
注意:角色与权限的结果要与spring-shiro.xml中的配置保持一致
3.测试
package com.xiaokun.ssm.mapper;
import com.xiaokun.ssm.model.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Set;
@Repository
public interface UserMapper {
int deleteByPrimaryKey(Integer userid);
int insert(User record);
int insertSelective(User record);
User selectByPrimaryKey(Integer userid);
int updateByPrimaryKeySelective(User record);
int updateByPrimaryKey(User record);
// 通过 账户名 查询用户信息
User queryUserByUserName(@Param("userName") String userName);
// 通过 账户名 查询 对应的 权限
// 这里返回Set Set 和 List 的区别的是:Set 不可以重复,List 是可以重复的
// 所有说我们要将权限剔除
Set selectRoleIdsByUserName(@Param("userName") String userName);
// 通过 用户名 查询 对应的 角色
Set selectPerIdsByUserName(@Param("userName") String userName);
}
package com.xiaokun.ssm.biz;
import com.xiaokun.ssm.model.User;
import org.apache.ibatis.annotations.Param;
public interface UserBiz {
int deleteByPrimaryKey(Integer userid);
int insert(User record);
int insertSelective(User record);
User selectByPrimaryKey(Integer userid);
User queryUserByUserName(@Param("userName") String userName);
int updateByPrimaryKeySelective(User record);
int updateByPrimaryKey(User record);
Set selectRoleIdsByUserName(String userName);
Set selectPerIdsByUserName(String userName);
}
package com.xiaokun.ssm.biz.impl;
import com.xiaokun.ssm.biz.UserBiz;
import com.xiaokun.ssm.mapper.UserMapper;
import com.xiaokun.ssm.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author 小坤
* @create 2022-08-25-13:30
*/
@Service
public class UserBizImpl implements UserBiz {
@Autowired
private UserMapper userMapper;
@Override
public int deleteByPrimaryKey(Integer userid) {
return userMapper.deleteByPrimaryKey(userid);
}
@Override
public int insert(User record) {
return userMapper.insert(record);
}
@Override
public int insertSelective(User record) {
return userMapper.insertSelective(record);
}
@Override
public User selectByPrimaryKey(Integer userid) {
return userMapper.selectByPrimaryKey(userid);
}
@Override
public User queryUserByUserName(String userName) {
return userMapper.queryUserByUserName(userName);
}
@Override
public int updateByPrimaryKeySelective(User record) {
return userMapper.updateByPrimaryKeySelective(record);
}
@Override
public int updateByPrimaryKey(User record) {
return userMapper.updateByPrimaryKey(record);
@Override
public Set selectRoleIdsByUserName(String userName) {
return userMapper.selectRoleIdsByUserName(userName);
}
@Override
public Set selectPerIdsByUserName(String userName) {
return userMapper.selectPerIdsByUserName(userName);
}
}
}
package com.xiaokun.ssm.shiro;
import com.xiaokun.ssm.biz.UserBiz;
import com.xiaokun.ssm.model.User;
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.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Set;
/**
* @author 小坤
* @create 2022-08-25-13:37
*/
public class MyRealm extends AuthorizingRealm {
public UserBiz userBiz;
public UserBiz getUserBiz() {
return userBiz;
}
public void setUserBiz(UserBiz userBiz) {
this.userBiz = userBiz;
}
/**
* 授权
* @param principalCollection
* @return
* shiro-web.ini
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 获取到我们的账户名
String userName = principalCollection.getPrimaryPrincipal().toString();
// 查询对应的角色
Set roleIds = userBiz.selectRoleIdsByUserName(userName);
Set perIds = userBiz.selectPerIdsByUserName(userName);
// 授权器
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 将当前登录的 权限 交给 shiro的授权器
info.setStringPermissions(perIds);
// 将当前登录的 角色 交给 shiro的授权器
info.setRoles(roleIds);
return info;
}
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
* shiro.ini
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 拿到我们的用户名
String userName = authenticationToken.getPrincipal().toString();
User user = userBiz.queryUserByUserName(userName);
// 拿到数据库中的用户信息,放入token凭证中,用于controler进行对比
AuthenticationInfo info = new SimpleAuthenticationInfo(
user.getUsername(),
user.getPassword(),
ByteSource.Util.bytes(user.getSalt()),
this.getName() //realm的名字
);
return info;
}
}
/user/login=anon
/user/updatePwd.jsp=authc
/admin/*.jsp=roles[4]
/user/teacher.jsp=perms[2]
测试一下,使用zs的账号登录
使用zs登录,无法访问
换zdm进行登录 密码为123
在测试一下teacher.jsp界面,我们先用zs登录,zs没有这个权限所以它不能访问
当我们用ls来登录的时候,因为ls它就具备有这个权限,所以可以访问
步骤:
① 将对应注解添加到指定需要权限控制的方法上
身份认证:requireUser
角色认证:requireRole
权限认证:requirePermission
② 在SpringMVC.xml中添加拦截器相关的配置
使用ls登录进去的时候shiro标签下少两个东西
因为交给授权器的是id,所以我们在main.jsp里面就要换
mian.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="r" uri="http://shiro.apache.org/tags" %>
Title
主界面<%=System.currentTimeMillis()%>,欢迎您:[${sessionScope.username}]
在使用ls账号进行登录主界面如图:
常用注解介绍
@RequiresAuthenthentication:表示当前Subject已经通过login进行身份验证;即 Subject.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
controller层 中的 ShiroController
package com.xiaokun.ssm.controller;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/shiro")
@Controller
public class ShiroController {
// @RequiresUser代表 当前方法只有登录后才能够访问
// RequiresUser等价于 spring-shiro.xml中的/user/updatePwd.jsp=authc配置
@RequiresUser
@RequestMapping("/passUser")
public String passUser(){
System.out.println("身份认证通过...");
return "admin/addUser";
}
// @RequiresRoles 当前方法只有 具备指定的角色 才能够访问
// RequiresRoles 等价于 spring-shiro.xml中的/admin/*.jsp=roles[4]配置
@RequiresRoles(value = {"1","4"},logical = Logical.AND)
@RequestMapping("/passRole")
public String passRole(){
System.out.println("角色认证通过...");
return "admin/addUser";
}
// @RequiresPermissions 当前方法只有 具备指定的权限 才能够访问
// RequiresPermissions 等价于 spring-shiro.xml中的/user/teacher.jsp=perms[2]配置
@RequiresPermissions(value = {"2"},logical = Logical.AND)
@RequestMapping("/passPermission")
public String passPermission(){
System.out.println("权限认证通过...");
return "admin/addUser";
}
}
springmvc-servle.xml 中添加拦截器的配置
unauthorized
使用zs的账号进行登录
使用passRole查询一下
我们只要换一个具备这两个条件的权限即可查询到假设我们换admin进行登录就可以查询到
如果把ShiroController.java 这里换成or
再使用zs账号进行登录 如图:
1.用户所拥有的角色
我们只需要角色的id所以我们连表查询只需要两张表 角色表 用户角色中间表
2.用户所拥有的权限
我们通过用户表 用户角色中间表 角色权限中间表 就能拿到权限的id了
步骤:
1.Mapper层、service层
2.MyRealm中的授权方法
查询用户所拥有的角色及权限赋值给授权器
3.测试
why:每一个页面每一个请求都需要在Spring-shiro.xml中做配置①常用注解:标记在方法上
身份认证:requireUser
角色认证:requireRole
权限认证:requirePermission
②SpringMVC.xml添加拦截器配置