新建springboot项目
导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.16</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shrimpking</groupId>
<artifactId>springboot-67</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-67</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- springboot整合方式的依赖包 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!-- 引入jsp解析的依赖 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--swagger依赖-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- ehcache缓存 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.9.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
mysql数据库
drop table if exists af_user;
create table af_user(
id int not null auto_increment primary key comment '主键,自增',
username varchar(50) not null comment '账号',
`password` varchar(50) not null comment '密码',
salt varchar(100) not null comment '加密盐'
) comment '用户表';
drop table if exists af_role;
create table af_role(
id int not null auto_increment primary key comment '主键',
role_name varchar(30) not null comment '角色名称'
) comment '角色表';
insert into af_role values(1,'admin');
insert into af_role values(2,'user');
insert into af_role values(3,'product');
drop table if exists af_user_role;
create table af_user_role(
id int not null auto_increment primary key comment '主键',
user_id int not null comment '用户id',
role_id int not null comment '角色id'
) comment '用户角色表';
insert into af_user_role values (1,1,1);
insert into af_user_role values (2,1,2);
insert into af_user_role values (3,2,2);
insert into af_user_role values (4,2,3);
drop table if exists af_permission;
create table af_permission(
id int not null auto_increment primary key comment '主键',
permission_name varchar(30) not null comment '权限名称',
url varchar(100) default null comment '请求路径'
) comment '权限表';
insert into af_permission values (1,'user:add','');
insert into af_permission values (2,'user:update','');
insert into af_permission values (3,'user:delete','');
insert into af_permission values (4,'user:find','');
insert into af_permission values (5,'other:add','');
insert into af_permission values (6,'other:delete','');
drop table if exists af_role_permission;
create table af_role_permission(
id int not null auto_increment primary key comment '主键',
role_id int not null comment '角色id',
permission_id int not null comment '权限id'
) comment '角色权限表';
insert into af_role_permission values (1,1,1);
insert into af_role_permission values (2,1,2);
insert into af_role_permission values (3,1,3);
insert into af_role_permission values (4,1,4);
insert into af_role_permission values (5,2,5);
insert into af_role_permission values (6,2,6);
pojo
permission.java
package com.shrimpking.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 权限表
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("af_permission")
@ApiModel(value="Permission对象", description="权限表")
public class Permission implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "权限名称")
private String permissionName;
@ApiModelProperty(value = "请求路径")
private String url;
}
role.java
package com.shrimpking.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 角色表
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("af_role")
@ApiModel(value="Role对象", description="角色表")
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "角色名称")
private String roleName;
//权限集合
@TableField(exist = false)
private List<Permission> permissions;
}
rolepermission.java
package com.shrimpking.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 角色权限表
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("af_role_permission")
@ApiModel(value="RolePermission对象", description="角色权限表")
public class RolePermission implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "角色id")
private Integer roleId;
@ApiModelProperty(value = "权限id")
private Integer permissionId;
}
user.java
package com.shrimpking.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 用户表
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("af_user")
@ApiModel(value="User对象", description="用户表")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键,自增")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "账号")
private String username;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "加密盐")
private String salt;
//定义角色集合
@TableField(exist = false)
private List<Role> roles;
}
userRole.java
package com.shrimpking.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 用户角色表
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("af_user_role")
@ApiModel(value="UserRole对象", description="用户角色表")
public class UserRole implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "用户id")
private Integer userId;
@ApiModelProperty(value = "角色id")
private Integer roleId;
}
mapper
permissionmapper.java
package com.shrimpking.mapper;
import com.shrimpking.pojo.Permission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 权限表 Mapper 接口
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface PermissionMapper extends BaseMapper<Permission> {
}
rolemapper.java
package com.shrimpking.mapper;
import com.shrimpking.pojo.Role;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 角色表 Mapper 接口
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface RoleMapper extends BaseMapper<Role> {
}
rolepermissionmapper.java
package com.shrimpking.mapper;
import com.shrimpking.pojo.RolePermission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 角色权限表 Mapper 接口
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface RolePermissionMapper extends BaseMapper<RolePermission> {
}
usermapper.java
package com.shrimpking.mapper;
import com.shrimpking.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 用户表 Mapper 接口
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
userrolemapper.java
package com.shrimpking.mapper;
import com.shrimpking.pojo.UserRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户角色表 Mapper 接口
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface UserRoleMapper extends BaseMapper<UserRole> {
}
mapperxml
permissionMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.shrimpking.mapper.PermissionMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.shrimpking.pojo.Permission">
<id column="id" property="id" />
<result column="permission_name" property="permissionName" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, permission_name
</sql>
</mapper>
rolemapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.shrimpking.mapper.RoleMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.shrimpking.pojo.Role">
<id column="id" property="id" />
<result column="role_name" property="roleName" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, role_name
</sql>
</mapper>
rolepermissionMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.shrimpking.mapper.RolePermissionMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.shrimpking.pojo.RolePermission">
<id column="id" property="id" />
<result column="role_id" property="roleId" />
<result column="permission_id" property="permissionId" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, role_id, permission_id
</sql>
</mapper>
userMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.shrimpking.mapper.UserMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.shrimpking.pojo.User">
<id column="id" property="id" />
<result column="username" property="username" />
<result column="password" property="password" />
<result column="salt" property="salt" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, username, password, salt
</sql>
</mapper>
userrolemapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.shrimpking.mapper.UserRoleMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.shrimpking.pojo.UserRole">
<id column="id" property="id" />
<result column="user_id" property="userId" />
<result column="role_id" property="roleId" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, user_id, role_id
</sql>
</mapper>
service
permisstionsercive.java
package com.shrimpking.service;
import com.shrimpking.pojo.Permission;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 权限表 服务类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface PermissionService extends IService<Permission> {
}
rolepermissionservice.java
package com.shrimpking.service;
import com.shrimpking.pojo.RolePermission;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 角色权限表 服务类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface RolePermissionService extends IService<RolePermission> {
}
roleservice.java
package com.shrimpking.service;
import com.shrimpking.pojo.Permission;
import com.shrimpking.pojo.Role;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 角色表 服务类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface RoleService extends IService<Role> {
List<Permission> getPermissionByRoleId(Integer id);
}
userroleservice.java
package com.shrimpking.service;
import com.shrimpking.pojo.UserRole;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户角色表 服务类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface UserRoleService extends IService<UserRole> {
}
userservice.java
package com.shrimpking.service;
import com.shrimpking.pojo.Role;
import com.shrimpking.pojo.User;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 用户表 服务类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
public interface UserService extends IService<User> {
//注册用户
boolean register(User user);
//根据用户名查询用户实体
User getUserByUserName(String username);
//根据用户名查询角色列表
User getRolesByUserName(String username);
}
serviceimpl
permisstionservcieimpl.java
package com.shrimpking.service.impl;
import com.shrimpking.pojo.Permission;
import com.shrimpking.mapper.PermissionMapper;
import com.shrimpking.service.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 权限表 服务实现类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
}
rolepermissionservcieimpl.java
package com.shrimpking.service.impl;
import com.shrimpking.pojo.RolePermission;
import com.shrimpking.mapper.RolePermissionMapper;
import com.shrimpking.service.RolePermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 角色权限表 服务实现类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Service
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission> implements RolePermissionService {
}
roleserviceimpl.java
package com.shrimpking.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shrimpking.mapper.PermissionMapper;
import com.shrimpking.mapper.RolePermissionMapper;
import com.shrimpking.pojo.Permission;
import com.shrimpking.pojo.Role;
import com.shrimpking.mapper.RoleMapper;
import com.shrimpking.pojo.RolePermission;
import com.shrimpking.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 角色表 服务实现类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
@Autowired
private RolePermissionMapper rolePermissionMapper;
@Autowired
private PermissionMapper permissionMapper;
@Override
public List<Permission> getPermissionByRoleId(Integer id)
{
//根据角色id,获取permssionid
LambdaQueryWrapper<RolePermission> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(RolePermission::getRoleId,id);
List<RolePermission> rolePermissions = this.rolePermissionMapper.selectList(queryWrapper);
//获取permission
List<Permission> resultList = new ArrayList<>();
for (RolePermission rolePermission : rolePermissions)
{
LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Permission::getId,rolePermission.getPermissionId());
Permission one = this.permissionMapper.selectOne(wrapper);
resultList.add(one);
}
return resultList;
}
}
userroleserviceimpl.java
package com.shrimpking.service.impl;
import com.shrimpking.pojo.UserRole;
import com.shrimpking.mapper.UserRoleMapper;
import com.shrimpking.service.UserRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户角色表 服务实现类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Service
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {
}
userserviceimpl.java
package com.shrimpking.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shrimpking.mapper.RoleMapper;
import com.shrimpking.mapper.UserRoleMapper;
import com.shrimpking.pojo.Permission;
import com.shrimpking.pojo.Role;
import com.shrimpking.pojo.User;
import com.shrimpking.mapper.UserMapper;
import com.shrimpking.pojo.UserRole;
import com.shrimpking.service.RoleService;
import com.shrimpking.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shrimpking.utils.SaltUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 用户表 服务实现类
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private UserRoleMapper userRoleMapper;
@Autowired
private RoleMapper roleMapper;
@Autowired
private RoleService roleService;
@Override
public boolean register(User user)
{
//处理登录业务层
//明文密码进行md5 + 盐 + 散列次数
//生成随机盐
String salt = SaltUtils.getSalt(4);
//加密
Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);
//保存盐
user.setSalt(salt);
//保存加密的密码
//
user.setPassword(md5Hash.toHex());
int insert = this.userMapper.insert(user);
if(insert > 0) return true;
return false;
}
@Override
public User getUserByUserName(String username)
{
//数据库中的username字段没有设置唯一键,使用selecOne会报错,所以返回列表
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getUsername,username);
queryWrapper.orderByDesc(User::getId);
List<User> userList = this.userMapper.selectList(queryWrapper);
return userList.get(0);
}
@Override
public User getRolesByUserName(String username)
{
//根据用户名获取用户
User user = getUserByUserName(username);
//根据用户id,获取roleid
LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserRole::getUserId,user.getId());
List<UserRole> userRoles = this.userRoleMapper.selectList(queryWrapper);
//根据
List<Role> resultList = new ArrayList<>();
for (UserRole ur : userRoles)
{
LambdaQueryWrapper<Role> queryWrapper2 = new LambdaQueryWrapper<>();
queryWrapper2.eq(Role::getId,ur.getRoleId());
Role role = this.roleMapper.selectOne(queryWrapper2);
//根据角色,获取权限
List<Permission> permissions = this.roleService.getPermissionByRoleId(role.getId());
role.setPermissions(permissions);
resultList.add(role);
}
//
user.setRoles(resultList);
return user;
}
}
controller
ordercontroller.java
package com.shrimpking.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/10/3 14:43
*/
@Controller
@RequestMapping("/order")
public class OrderController
{
@GetMapping("/save")
public String save(){
//代码方式判断角色和权限
//获取主体
Subject subject = SecurityUtils.getSubject();
//
if(subject.hasRole("admin")){
System.out.println("保存订单");
} else {
System.out.println("无权访问");
}
return "redirect:/index.jsp";
}
@RequiresRoles("admin")
@GetMapping("/update")
public String update(){
//注解方式,判断角色和权限
System.out.println("修改订单");
return "redirect:/index.jsp";
}
}
permissioncontroller.java
package com.shrimpking.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 权限表 前端控制器
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@RestController
@RequestMapping("/permission")
public class PermissionController {
}
rolecontroller.java
package com.shrimpking.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 角色表 前端控制器
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@RestController
@RequestMapping("/role")
public class RoleController {
}
rolepermission.java
package com.shrimpking.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 角色权限表 前端控制器
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@RestController
@RequestMapping("/role-permission")
public class RolePermissionController {
}
testcontroller.java
package com.shrimpking.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
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.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/10/2 22:18
*/
@Controller
@RequestMapping("/test")
public class TestController
{
/**
* 登录
* @param username
* @param password
* @return
*/
@PostMapping("/login")
public String login(String username,String password){
//获取主体对象
Subject subject = SecurityUtils.getSubject();
//生成令牌token
AuthenticationToken token = new UsernamePasswordToken(username,password);
//
try
{
subject.login(token);
return "redirect:/index.jsp";
}
catch (UnknownAccountException e)
{
e.printStackTrace();
System.out.println("用户不存在");
}
catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误");
}
return "redirect:/login.jsp";
}
/**
* 退出
* @return
*/
@GetMapping("/logout")
public String logout(){
//获取身份主体
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/login.jsp";
}
}
usercontroller.java
package com.shrimpking.controller;
import com.shrimpking.pojo.User;
import com.shrimpking.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 用户表 前端控制器
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public String register(User user){
boolean register = this.userService.register(user);
if(register) return "redirect:/login.jsp";
return "redirect:/register.jsp";
}
}
userrolecontroller.java
package com.shrimpking.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 用户角色表 前端控制器
* </p>
*
* @author shrimpking
* @since 2023-10-03
*/
@RestController
@RequestMapping("/user-role")
public class UserRoleController {
}
config
shiroconfig.java
package com.shrimpking.config;
import com.shrimpking.shiro.realms.CustomerRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/10/2 21:30
* shiro的配置类
*/
@Configuration
public class ShiroConfig
{
//创建shirofilter
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
//负责拦截请求
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
factoryBean.setSecurityManager(defaultWebSecurityManager);
//配置系统受限资源
Map<String,String> map = new HashMap<>();
//配置系统公共资源
map.put("/test/login","anon");
map.put("/register.jsp","anon");
map.put("/user/register","anon");
map.put("/swagger-ui.html#/","anon");
//请求这个资源需要认证和授权后
map.put("/**","authc");
factoryBean.setFilterChainDefinitionMap(map);
//
factoryBean.setLoginUrl("/login.jsp");
return factoryBean;
}
//创建安全管理器
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(Realm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//设置realm
securityManager.setRealm(realm);
return securityManager;
}
//创建自定义realm
@Bean
public Realm realm(){
CustomerRealm customerRealm = new CustomerRealm();
//设置加密凭证匹配器
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//使用md5加密
matcher.setHashAlgorithmName("MD5");
//散列次数
matcher.setHashIterations(1024);
//设置匹配器
customerRealm.setCredentialsMatcher(matcher);
//开启缓存
customerRealm.setCacheManager(new EhCacheManager());
//全局开启
customerRealm.setCachingEnabled(true);
//开启认证缓存
customerRealm.setAuthenticationCachingEnabled(true);
customerRealm.setAuthenticationCacheName("authenticationCache");
//开启授权缓存
customerRealm.setAuthorizationCachingEnabled(true);
customerRealm.setAuthorizationCacheName("authorizationCache");
return customerRealm;
}
}
swaggerconfig.java
package com.shrimpking.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/9/10 14:58
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig
{
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder().build();
}
}
realms
package com.shrimpking.shiro.realms;
import com.shrimpking.pojo.Permission;
import com.shrimpking.pojo.Role;
import com.shrimpking.pojo.User;
import com.shrimpking.service.UserService;
import com.shrimpking.service.impl.UserServiceImpl;
import com.shrimpking.utils.ApplicationContextUtils;
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.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Collection;
import java.util.List;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/10/2 21:42
* 自定义realm类
*/
public class CustomerRealm extends AuthorizingRealm
{
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
{
//获取身份信息
String principal = principalCollection.getPrimaryPrincipal().toString();
//System.out.println("自定义授权");
//根据用户名查询角色和权限
// if("zhangsan".equals(principal)){
// SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// info.addRole("admin");
// info.addStringPermission("other:add:*");
// info.addStringPermission("other:delete:*");
// return info;
// }
//赋值授权角色
User user = this.userService.getRolesByUserName(principal);
//列表不为空
if(!CollectionUtils.isEmpty(user.getRoles())){
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
user.getRoles().forEach(role -> {
info.addRole(role.getRoleName());
//权限,不为空时继续下探
if(!CollectionUtils.isEmpty(role.getPermissions())){
List<Permission> permissions = role.getPermissions();
//System.out.println(permissions);
permissions.forEach(permission -> {
info.addStringPermission(permission.getPermissionName());
});
}
});
return info;
}
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException
{
//获取身份信息
String principal = authenticationToken.getPrincipal().toString();
User user = this.userService.getUserByUserName(principal);
//如果使用Autowired自动注入有问题时,请使用这个工具类,获取srping容器中的
//UserService userService = (UserService) ApplicationContextUtils.getBean("userServiceImpl");
//User user = userService.getUserByUserName(principal);
//判断
if(user != null) {
return new SimpleAuthenticationInfo(
principal,
user.getPassword(),
ByteSource.Util.bytes(user.getSalt().getBytes()),
this.getName()
);
}
return null;
}
}
utils
applicationcontextutils.java
package com.shrimpking.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/10/3 12:26
* 工具类,获取spring容器中的相应对象
*/
@Component
public class ApplicationContextUtils implements ApplicationContextAware
{
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
context = applicationContext;
}
/**
* 根据beanName获取spring容器中的类对象实例
* @param beanName
* @return
*/
public static Object getBean(String beanName){
return context.getBean(beanName);
}
}
saltutils.java
package com.shrimpking.utils;
import java.util.Random;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/10/3 10:59
* 生成随机加密盐
*/
public class SaltUtils
{
public static String getSalt(int n){
char[] chars = "abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789".toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++)
{
char aChar = chars[new Random().nextInt(chars.length)];
sb.append(aChar);
}
return sb.toString();
}
}
启动类
package com.shrimpking;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.shrimpking.mapper")
public class Springboot67Application
{
public static void main(String[] args)
{
SpringApplication.run(Springboot67Application.class, args);
}
}
jsp
login.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title></title>
</head>
<body>
<h1>登录管理</h1>
<form action="${pageContext.request.contextPath}/test/login" method="post">
账号:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
<a href="${pageContext.request.contextPath}/register.jsp">没有账号,请注册</a>
</body>
</html>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
<head>
<title></title>
</head>
<body>
<h1>系统主页</h1>
<a href="${pageContext.request.contextPath}/test/logout">退出系统</a>
<ul>
<shiro:hasRole name="admin">
<li><a href="#">用户管理</a></li>
<li><a href="#">商品管理</a></li>
<li><a href="#">订单管理</a></li>
<ul>
<li><a href="${pageContext.request.contextPath}/order/save">订单保存</a></li>
<li><a href="${pageContext.request.contextPath}/order/update">修改订单</a></li>
</ul>
<li><a href="#">物流管理</a></li>
</shiro:hasRole>
<shiro:hasAnyRoles name="user,admin">
<li><a href="#">一般用户管理</a>
<ul>
<shiro:hasPermission name="user:add:*">
<li><a href="#">添加</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="user:update:*">
<li><a href="#">修改</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="user:delete:*">
<li><a href="#">删除</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="user:find:*">
<li><a href="#">查询</a></li>
</shiro:hasPermission>
</ul>
</li>
<li><a href="#">其他管理</a>
<ul>
<shiro:hasPermission name="other:add:*">
<li><a href="#">添加</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="other:update:*">
<li><a href="#">修改</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="other:delete:*">
<li><a href="#">删除</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="other:find:*">
<li><a href="#">查询</a></li>
</shiro:hasPermission>
</ul>
</li>
</shiro:hasAnyRoles>
</ul>
</body>
</html>
register.jsp
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title></title>
</head>
<body>
<h1>用户注册</h1>
<form action="${pageContext.request.contextPath}/user/register" method="post">
账号:<input type="text" name="username" required><br>
密码:<input type="password" name="password" required><br>
<input type="submit" value="立即注册">
</form>
</body>
</html>
test
package com.shrimpking;
import com.shrimpking.utils.SaltUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2023/10/3 11:09
*/
@SpringBootTest
public class SaltTest
{
@Test
public void test(){
String salt = SaltUtils.getSalt(4);
System.out.println(salt);
}
}
测试
登录
注册
zhangsan 1234
lisi 1234