一.概述
说明:本次操作是在上一篇的基础上进行的授权操作。
https://www.bilibili.com/video/BV1uz4y197Zm?p=1
在菜单权限表中,admin具有id=2的菜单权限;ljf具有id=1,id=3的菜单权限,如下图
也就是说admin能访问所有模块的权限;ljf具有只能访问订单管理下的添加权限。
参考资料:
https://www.bilibili.com/video/BV1uz4y197Zm?p=1
二.项目操作
2.1 配置userDao层
package com.shiro.ljf.demo.sptshirodemo.dao;
import com.shiro.ljf.demo.sptshirodemo.entity.MenuPerms;
import com.shiro.ljf.demo.sptshirodemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDao {
//注册数据
public void addData(User user);
//根据用户名查询用户
public User findByUserName(String userName);
//根据用户名查询所有角色
User findRolesByUserName(String username);
//根据角色id查询权限集合
List<MenuPerms> findPermsByRoleId(String id);
}
2.2 配置service层
package com.shiro.ljf.demo.sptshirodemo.service;
import com.shiro.ljf.demo.sptshirodemo.entity.MenuPerms;
import com.shiro.ljf.demo.sptshirodemo.entity.User;
import java.util.List;
public interface UserService {
//注册用户方法
void register(User user);
//查找用户名
public User findByUserName(String username);
//根据用户名查询所有角色
User findRolesByUserName(String username);
//根据角色id查询权限集合
List<MenuPerms> findPermsByRoleId(String id);
}
2.3 mapper层
<!--通过角色id查询权限菜单 -->
<select id="findPermsByRoleId" parameterType="String" resultType="com.shiro.ljf.demo.sptshirodemo.entity.MenuPerms">
SELECT p.id,p.NAME,p.url,r.NAME
FROM t_role r
LEFT JOIN t_role_menu_perms rp
ON r.id=rp.roleid
LEFT JOIN t_menu_perms p ON rp.permsid=p.id
WHERE r.id=#{id}
</select>
2.4 controller层
package com.shiro.ljf.demo.sptshirodemo.controller;
import com.shiro.ljf.demo.sptshirodemo.entity.User;
import com.shiro.ljf.demo.sptshirodemo.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
/**
* @ClassName: UserLoginController
* @Description: TODO
* @Author: liujianfu
* @Date: 2020/10/29 08:13:50
* @Version: V1.0
**/
@Controller
@RequestMapping("user")
public class UserLoginController {
@Autowired
private UserService userService;
/**
* 用来处理身份认证
*
* @param username
* @param password
* @return
*/
@RequestMapping("login")
public String login(String username, String password, String code, HttpSession session, Model model) {
try {
System.out.println("进入login的登录方法====");
//获取主体对象
Subject subject = SecurityUtils.getSubject();
//当执行这个login的方法,就会触发在自定义的CustomerRealm的AuthenticationInfo的方法
subject.login(new UsernamePasswordToken(username, password));//!!!!
return "redirect:/index.jsp";
} catch (UnknownAccountException e) {
e.printStackTrace();
System.out.println("用户名错误!");
} catch (IncorrectCredentialsException e) {
e.printStackTrace();
System.out.println("密码错误!");
System.out.println("密码错误!");
model.addAttribute("error","密码错误");
return "login";
}catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
System.out.println("登录页面");
return "redirect:/login.jsp";
}
/**
* 退出登录
*/
@RequestMapping("logout")
public String logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();//退出用户
return "redirect:/login.jsp";
}
/**
* 用户注册
*/
@RequestMapping("register")
public String register(User user) {
try {
System.out.println("进入userController 层了:!!!!!");
if(user!=null&&user.getPassword()!=null){
System.out.println("user的信息不为null:");
userService.register(user);
return "redirect:/login.jsp";
}
return "redirect:/register.jsp";
}catch (Exception e){
e.printStackTrace();
return "redirect:/register.jsp";
}
}
/**
* work
*/
@RequestMapping("work")
public String work() {
try {
System.out.println("进入userController 层了work:!!!!!");
return "redirect:/order.jsp";
}catch (Exception e){
e.printStackTrace();
return "redirect:/register.jsp";
}
}
}
2.5 自定义reaml
package com.shiro.ljf.demo.sptshirodemo.shiro;
import com.shiro.ljf.demo.sptshirodemo.entity.MenuPerms;
import com.shiro.ljf.demo.sptshirodemo.entity.User;
import com.shiro.ljf.demo.sptshirodemo.service.UserService;
import com.shiro.ljf.demo.sptshirodemo.utils.ApplicationContextUtils;
import com.shiro.ljf.demo.sptshirodemo.utils.MyByteSource;
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.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.util.List;
/**
* @ClassName: CustomerRealm
* @Description: TODO
* @Author: liujianfu
* @Date: 2020/10/28 15:17:48
* @Version: V1.0
**/
public class CustomerRealm extends AuthorizingRealm {
/**
* @author liujianfu
* @description 授权方法
* @date 2020/10/28 16:54
* @return org.apache.shiro.authz.AuthorizationInfo
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("进入授权部分======:");
//获取身份信息
String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
System.out.println("调用授权验证: "+primaryPrincipal);
/**
if("ljf".equals(primaryPrincipal)){//登录的用户ljf,具有以下角色
//角色的授权
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addRole("admin");
simpleAuthorizationInfo.addRole("guest");
//权限字符串的授权
simpleAuthorizationInfo.addStringPermission("haha:add:01");
simpleAuthorizationInfo.addStringPermission("haha:update:02");
return simpleAuthorizationInfo;
}
**/
//根据主身份信息获取角色 和 权限信息
UserService userService = (UserService) ApplicationContextUtils.getBean("userService");
User user = userService.findRolesByUserName(primaryPrincipal);
//授权角色信息
if(!CollectionUtils.isEmpty(user.getRoles())){
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
user.getRoles().forEach(role->{
simpleAuthorizationInfo.addRole(role.getName());
//权限信息
List<MenuPerms> perms = userService.findPermsByRoleId(role.getId());
if(!CollectionUtils.isEmpty(perms)){
perms.forEach(perm->{
simpleAuthorizationInfo.addStringPermission(perm.getName());
});
}
});
return simpleAuthorizationInfo;
}
return null;
}
/**
* @author liujianfu
* @description
* @date 2020/10/28 16:54
* @return org.apache.shiro.authc.AuthenticationInfo
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("============================================进入认证方法==================");
/** 写死的部分
//获取身份信息
String primaryPrincipal = (String) authenticationToken.getPrincipal();
System.out.println("调用验证: "+primaryPrincipal);
//根据主身份信息获取角色 和 权限信息
if("admin".equals(primaryPrincipal)) {
System.out.println("this name:"+this.getName());
return new SimpleAuthenticationInfo(primaryPrincipal,"123",this.getName());
}
return null;
**/
//根据身份信息 ,动态从数据库中加载数据
String principal = (String) authenticationToken.getPrincipal();
//在工厂中获取service对象
UserService userService = (UserService) ApplicationContextUtils.getBean("userService");
User user = userService.findByUserName(principal);
if(!ObjectUtils.isEmpty(user)){
//设置用户名,密码,随机盐
return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),
new MyByteSource(user.getSalt()),
this.getName());
}
return null;
}
}
三 演示操作
1.使用admin 操作
1.输入地址
2.登录界面
3.主界面
3.2 通过ljf普通用户
1.输入地址
2.登录界面
3.主界面
结论:实现了不同用户所属不通角色,操作不同的权限资源