【更新】看到很多博客写 shiro权限认证的,都是一半的代码,复制上根本不能使用,依赖文件对于小白来说,更是不知道使用什么依赖,所以我把相应的java文件的包 都一并带上

spring-shiro属于轻量级权限框架,即使spring-security更新换代,市场上大多数企业还是选择shiro

废话不多说  引入pom文件相关依赖

         <!--日志管理-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.16</version>
</dependency>
<!--shiro权限框架-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>

导入之后 相关依赖包就会自动加载 shiro-core、shiro-spring、shiro-web等等  依赖版本还得根据shiro集成的spring版本进行加载(注意版本号)

设计登录认证,就少不三张表。没做过登录认证的小白    仔细看,我在Shiro配置中,尽量的去加入注释说明

先贴上我的 用户,角色,权限 三张表的 java 对象

需求分析为:用户角色 - 多对多

           角色权限 - 多对多

注意:直接复制的同学,三张表的注解,各位可以忽略删除  也可以学习使用 Spring-Data-Jpa 底层是 Hibernate,建表和查询方便

三个关系告诉你了,其实只需要最后关联的是 : 用户 - 权限  这里不需要 role角色表(实际项目中可以选择需要)

import lombok.Data;
import lombok.ToString; @Data
@ToString
public class User {
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.user_id
*
* @mbg.generated
*/
private Integer userId; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.user_name
*
* @mbg.generated
*/
private String userName; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.password
*
* @mbg.generated
*/
private String password; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.phone
*
* @mbg.generated
*/
private String phone; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.email
*
* @mbg.generated
*/
private String email; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.status
*
* @mbg.generated
*/
private Integer status; private String salt; public String getSalt() {
return salt;
} public void setSalt(String salt) {
this.salt = salt;
} /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.note
*
* @mbg.generated
*/
private String note; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.create_time
*
* @mbg.generated
*/
private String createTime; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_users.update_time
*
* @mbg.generated
*/
private String updateTime; /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.user_id
*
* @return the value of tb_users.user_id
*
* @mbg.generated
*/
public Integer getUserId() {
return userId;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.user_id
*
* @param userId the value for tb_users.user_id
*
* @mbg.generated
*/
public void setUserId(Integer userId) {
this.userId = userId;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.user_name
*
* @return the value of tb_users.user_name
*
* @mbg.generated
*/
public String getUserName() {
return userName;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.user_name
*
* @param userName the value for tb_users.user_name
*
* @mbg.generated
*/
public void setUserName(String userName) {
this.userName = userName == null ? null : userName.trim();
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.password
*
* @return the value of tb_users.password
*
* @mbg.generated
*/
public String getPassword() {
return password;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.password
*
* @param password the value for tb_users.password
*
* @mbg.generated
*/
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.phone
*
* @return the value of tb_users.phone
*
* @mbg.generated
*/
public String getPhone() {
return phone;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.phone
*
* @param phone the value for tb_users.phone
*
* @mbg.generated
*/
public void setPhone(String phone) {
this.phone = phone == null ? null : phone.trim();
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.email
*
* @return the value of tb_users.email
*
* @mbg.generated
*/
public String getEmail() {
return email;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.email
*
* @param email the value for tb_users.email
*
* @mbg.generated
*/
public void setEmail(String email) {
this.email = email == null ? null : email.trim();
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.status
*
* @return the value of tb_users.status
*
* @mbg.generated
*/
public Integer getStatus() {
return status;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.status
*
* @param status the value for tb_users.status
*
* @mbg.generated
*/
public void setStatus(Integer status) {
this.status = status;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.note
*
* @return the value of tb_users.note
*
* @mbg.generated
*/
public String getNote() {
return note;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.note
*
* @param note the value for tb_users.note
*
* @mbg.generated
*/
public void setNote(String note) {
this.note = note == null ? null : note.trim();
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.create_time
*
* @return the value of tb_users.create_time
*
* @mbg.generated
*/
public String getCreateTime() {
return createTime;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.create_time
*
* @param createTime the value for tb_users.create_time
*
* @mbg.generated
*/
public void setCreateTime(String createTime) {
this.createTime = createTime;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_users.update_time
*
* @return the value of tb_users.update_time
*
* @mbg.generated
*/
public String getUpdateTime() {
return updateTime;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_users.update_time
*
* @param updateTime the value for tb_users.update_time
*
* @mbg.generated
*/
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
} }

User

import lombok.Data;
import lombok.ToString; import java.util.Date; /**
* @author wusiwee
* @date 2020/4/3 10:58
*/
@Data
@ToString
public class Permission { /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.func_id
*
* @mbg.generated
*/
private Integer funcId; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.func_name
*
* @mbg.generated
*/
private String funcName; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.func_url
*
* @mbg.generated
*/
private String funcUrl; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.func_code
*
* @mbg.generated
*/
private String funcCode; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.parent_id
*
* @mbg.generated
*/
private Integer parentId; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.func_type
*
* @mbg.generated
*/
private Integer funcType; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.status
*
* @mbg.generated
*/
private Integer status; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.sort_num
*
* @mbg.generated
*/
private Integer sortNum; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.create_time
*
* @mbg.generated
*/
private Date createTime; /**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column tb_functions.update_time
*
* @mbg.generated
*/
private Date updateTime; /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.func_id
*
* @return the value of tb_functions.func_id
*
* @mbg.generated
*/
public Integer getFuncId() {
return funcId;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.func_id
*
* @param funcId the value for tb_functions.func_id
*
* @mbg.generated
*/
public void setFuncId(Integer funcId) {
this.funcId = funcId;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.func_name
*
* @return the value of tb_functions.func_name
*
* @mbg.generated
*/
public String getFuncName() {
return funcName;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.func_name
*
* @param funcName the value for tb_functions.func_name
*
* @mbg.generated
*/
public void setFuncName(String funcName) {
this.funcName = funcName == null ? null : funcName.trim();
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.func_url
*
* @return the value of tb_functions.func_url
*
* @mbg.generated
*/
public String getFuncUrl() {
return funcUrl;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.func_url
*
* @param funcUrl the value for tb_functions.func_url
*
* @mbg.generated
*/
public void setFuncUrl(String funcUrl) {
this.funcUrl = funcUrl == null ? null : funcUrl.trim();
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.func_code
*
* @return the value of tb_functions.func_code
*
* @mbg.generated
*/
public String getFuncCode() {
return funcCode;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.func_code
*
* @param funcCode the value for tb_functions.func_code
*
* @mbg.generated
*/
public void setFuncCode(String funcCode) {
this.funcCode = funcCode == null ? null : funcCode.trim();
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.parent_id
*
* @return the value of tb_functions.parent_id
*
* @mbg.generated
*/
public Integer getParentId() {
return parentId;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.parent_id
*
* @param parentId the value for tb_functions.parent_id
*
* @mbg.generated
*/
public void setParentId(Integer parentId) {
this.parentId = parentId;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.func_type
*
* @return the value of tb_functions.func_type
*
* @mbg.generated
*/
public Integer getFuncType() {
return funcType;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.func_type
*
* @param funcType the value for tb_functions.func_type
*
* @mbg.generated
*/
public void setFuncType(Integer funcType) {
this.funcType = funcType;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.status
*
* @return the value of tb_functions.status
*
* @mbg.generated
*/
public Integer getStatus() {
return status;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.status
*
* @param status the value for tb_functions.status
*
* @mbg.generated
*/
public void setStatus(Integer status) {
this.status = status;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.sort_num
*
* @return the value of tb_functions.sort_num
*
* @mbg.generated
*/
public Integer getSortNum() {
return sortNum;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.sort_num
*
* @param sortNum the value for tb_functions.sort_num
*
* @mbg.generated
*/
public void setSortNum(Integer sortNum) {
this.sortNum = sortNum;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.create_time
*
* @return the value of tb_functions.create_time
*
* @mbg.generated
*/
public Date getCreateTime() {
return createTime;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.create_time
*
* @param createTime the value for tb_functions.create_time
*
* @mbg.generated
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
} /**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column tb_functions.update_time
*
* @return the value of tb_functions.update_time
*
* @mbg.generated
*/
public Date getUpdateTime() {
return updateTime;
} /**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column tb_functions.update_time
*
* @param updateTime the value for tb_functions.update_time
*
* @mbg.generated
*/
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

Permission

开始进入Shiro篇

一:自定义Reaml域,用于实现自身认证体系,大白话:什么样的认证规则,我都可以来定

    创建Reaml对象 继承 AuthorizingRealm 实现

授权方法

doGetAuthorizationInfo(PrincipalCollection principals){}

认证方法

doGetAuthenticationInfo(AuthenticationToken token){}
import com.bear.entity.Permission;
import com.bear.entity.User;
import com.bear.service.PermissionService;
import com.bear.service.UserService;
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.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList;
import java.util.List; /**
* @author wusw
* @version 1.0
* @date 2020/4/2 19:46
*/
public class ShiroReaml extends AuthorizingRealm {
/**
* 注入userService 服务层 用户与数据库数据查询
*/
@Autowired
private UserService userService;
/**
* 注入permissionService 服务层 用户与数据库数据查询
*/
@Autowired
private PermissionService permissionService; /**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//这个User对应下面认证方法的 返回的第一个参数 ew SimpleAuthenticationInfo(user, user.getPassword(), "shiroReaml")
User user = (User)principalCollection.getPrimaryPrincipal();
//查询用户相关权限
List<Permission> permissionList = permissionService.findPermissionByUserId(user.getUserId());
//授权对象
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//创建一个List<String> 用于接收权限信息
ArrayList<String> list = new ArrayList<>();
for (Permission permission : permissionList) {
//添加权限String字符串:存值示例: "admin:*","admin:list"...
info.addStringPermission(permission.getFuncCode());
}
return info;
} /**
* 认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//这一块toString返回 username 是login方法在 newUserNamePassword(username,password)创建的token封装成的
String username = token.getPrincipal().toString();
//打印一下,项目中 尽量不要使用System.out.println(),最好使用log日志进行记录
System.out.println("认证获取的username:"+username); //查询数据库用户是否存在 不存在则抛异常 Shiro会自动认证失败
User user = this.userService.findByUsername(username);
//参数一 可以传 username,user对象 等等 我这里是user对象 对应上面授权方法principalCollection获取的值
//参数二 用户密码
//参数三 shiroReaml 名称要与 shiroConfig配置中的 Reaml 的注入Bean保持一致
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), "shiroReaml");
return authenticationInfo;
}
}

二:Shiro配置  加上注解 @Configuration 让springboot识别它为一个配置类

注意:打字太多,我把相应规则的 url 贴上,供大家参考

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.HashMap; /**
* 请注意看每个方法上的注释
* @author wusw
* @version 1.0
* @date 2020/4/2 19:41
*/
@Configuration
public class ShiroConfig { /**
* 添加创建 securityMeneger 工厂注入Bean
* @param securityManager 注解Qualifier中的名字 和下面 DefaultWebSecurityManager 的Bean的名字相同
* @return
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager){
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
filterFactoryBean.setSecurityManager(securityManager);
//设置权限过滤器集合 key-value 形式
// key :访问路径 正常/**写在最下面,执行顺序是从上至下,这里是个大坑,一不小心,程序就凉凉了呢~
// value:anon(可以匿名访问),authc(认证后才能访问),logout(退出后自动清除session)
HashMap<String, String> map = new HashMap<>();
map.put("/bear/login","anon");
map.put("/bear/logout","logout");
map.put("/**","authc"); filterFactoryBean.setLoginUrl("/bear/toLogin");
filterFactoryBean.setUnauthorizedUrl("/bear/401");
filterFactoryBean.setSuccessUrl("/bear/index");
//将map集合 传给过滤器
filterFactoryBean.setFilterChainDefinitionMap(map); return filterFactoryBean;
} /**
* 创建 securityMeneger 类的注入Bean
* @param shiroReaml 注解Qualifier中的名字 和下面 ShiroReaml的Bean的名字相同
* @return
*/
@Bean("securityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("shiroReaml") ShiroReaml shiroReaml){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroReaml);
return securityManager;
} /**
* 创建自定义域 reaml注入Bean
* @return
*/
@Bean("shiroReaml")
public ShiroReaml shiroReaml(){
return new ShiroReaml();
}
}

主要已经搞定,贴上相关service,controller,以及yml配置文件,dao层交互我使用的是mybaties相关pom依赖各位小伙伴自己导入 xml中namespase和type路径请自行导入

# 数据库的配置信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://0.0.0.0/db?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Hongkong&verifyServerCertificate=false
username: ***
password: ***
type: com.alibaba.druid.pool.DruidDataSource
thymeleaf:
mode: HTML5
encoding: UTF-8
servlet:
content-type: text/html
mvc:
static-path-pattern: /**
# mybatis的配置信息
mybatis:
config-location: classpath:mybatis/config/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*.xml server:
port: 8081

applicaiton.yml

<?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.bear.dao.IUserMapper"> <resultMap id="BaseResultMap" type="com.bear.entity.User">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<id column="user_id" jdbcType="INTEGER" property="userId" />
<result column="user_name" jdbcType="VARCHAR" property="userName" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="phone" jdbcType="VARCHAR" property="phone" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="salt" jdbcType="VARCHAR" property="salt" />
<result column="status" jdbcType="INTEGER" property="status" />
<result column="note" jdbcType="VARCHAR" property="note" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap> <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from tb_users
where user_id = #{userId,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.bear.entity.User">
insert into tb_users (user_id, user_name, password,
phone, email, status,
note, create_time, update_time
)
values (#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
#{phone,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER},
#{note,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP}
)
</insert>
<update id="updateByPrimaryKey" parameterType="com.bear.entity.User">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update tb_users
set user_name = #{userName,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR},
phone = #{phone,jdbcType=VARCHAR},
email = #{email,jdbcType=VARCHAR},
status = #{status,jdbcType=INTEGER},
note = #{note,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = #{updateTime,jdbcType=TIMESTAMP}
where user_id = #{userId,jdbcType=INTEGER}
</update>
<!-- <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select user_id, user_name, password, phone, email, status, note, create_time, update_time
from tb_users
where user_id = #{userId,jdbcType=INTEGER}
</select>-->
<select id="findAll" resultMap="BaseResultMap">
select user_id, user_name, password, phone, email, status, note, create_time, update_time
from tb_users
</select> <!-- 根据用户名密码查询 -->
<select id="findByUsername" resultMap="BaseResultMap">
select * from tb_users where user_name = #{username}
</select>
<!-- 根据分页查询 -->
<!-- <select id="findByPage" resultMap="BaseResultMap">
select * from tb_users limit #{page},#{rows}
</select>
&lt;!&ndash; 统计总记录数 &ndash;&gt;
<select id="totalCount" resultType="long">
select count(*) from tb_users
</select>
&lt;!&ndash; 根据ID查询 &ndash;&gt;
<select id="findById" resultMap="BaseResultMap">
select * from tb_users where user_id = #{userId}
</select>--> </mapper>

IUserMappler.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.bear.dao.IPermissionMapper">
<resultMap id="BaseResultMap" type="com.bear.entity.Permission">
<!-- WARNING - @mbg.generated This element is automatically generated by
MyBatis Generator, do not modify. -->
<id column="func_id" jdbcType="INTEGER" property="funcId" />
<result column="func_name" jdbcType="VARCHAR" property="funcName" />
<result column="func_url" jdbcType="VARCHAR" property="funcUrl" />
<result column="func_code" jdbcType="VARCHAR" property="funcCode" />
<result column="parent_id" jdbcType="INTEGER" property="parentId" />
<result column="func_type" jdbcType="INTEGER" property="funcType" />
<result column="status" jdbcType="INTEGER" property="status" />
<result column="sort_num" jdbcType="INTEGER" property="sortNum" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!-- WARNING - @mbg.generated This element is automatically generated by
MyBatis Generator, do not modify. -->
delete from tb_functions
where func_id = #{funcId,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.bear.entity.Permission">
<!-- WARNING - @mbg.generated This element is automatically generated by
MyBatis Generator, do not modify. -->
insert into tb_functions (func_id, func_name, func_url,
func_code,
parent_id, func_type,
status, sort_num, create_time,
update_time)
values
(#{funcId,jdbcType=INTEGER}, #{funcName,jdbcType=VARCHAR},
#{funcUrl,jdbcType=VARCHAR},
#{funcCode,jdbcType=VARCHAR},
#{parentId,jdbcType=INTEGER}, #{funcType,jdbcType=INTEGER},
#{status,jdbcType=INTEGER}, #{sortNum,jdbcType=INTEGER},
#{createTime,jdbcType=TIMESTAMP},
#{updateTime,jdbcType=TIMESTAMP})
</insert>
<update id="updateByPrimaryKey" parameterType="com.bear.entity.Permission">
<!-- WARNING - @mbg.generated This element is automatically generated by
MyBatis Generator, do not modify. -->
update tb_functions
set func_name = #{funcName,jdbcType=VARCHAR},
func_url = #{funcUrl,jdbcType=VARCHAR},
func_code =
#{funcCode,jdbcType=VARCHAR},
parent_id = #{parentId,jdbcType=INTEGER},
func_type = #{funcType,jdbcType=INTEGER},
status =
#{status,jdbcType=INTEGER},
sort_num = #{sortNum,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time =
#{updateTime,jdbcType=TIMESTAMP}
where func_id =
#{funcId,jdbcType=INTEGER}
</update>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer"
resultMap="BaseResultMap">
<!-- WARNING - @mbg.generated This element is automatically generated by
MyBatis Generator, do not modify. -->
select func_id, func_name, func_url, func_code, parent_id, func_type,
status, sort_num,
create_time, update_time
from tb_functions
where
func_id = #{funcId,jdbcType=INTEGER}
</select>
<select id="selectAll" resultMap="BaseResultMap">
<!-- WARNING - @mbg.generated This element is automatically generated by
MyBatis Generator, do not modify. -->
select func_id, func_name, func_url, func_code, parent_id, func_type,
status, sort_num,
create_time, update_time
from tb_functions
</select> <select id="findByRoleIds" resultMap="BaseResultMap"
parameterType="java.util.List">
select distinct f.* from tb_functions f , tb_role_function rf where
f.func_id = rf.func_id and rf.role_id in
<foreach collection="list" item="id" open="(" close=")"
separator=",">
#{id}
</foreach>
and f.func_type = 0
</select> <select id="findPermissionByUserId" resultMap="BaseResultMap"
parameterType="int">
select
DISTINCT
f.*
from
tb_users u,tb_user_role ur,tb_roles r,tb_functions f,tb_role_function rf
where
u.user_id = ur.user_id and
r.role_id = ur.role_id and
f.func_id = rf.func_id and
r.role_id = rf.role_id and
u.user_id = #{userId}
</select> </mapper>

IPermissionMapper

dao层:

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface IUserMapper {
/**
* 根据用户名查找用户
* @param username
* @return
*/
User findByUsername(String username); /**
* 更新
* @param user
*/
void updateByPrimaryKey(User user); /**
* 新增
* @param user
*/
void insert(User user); /**
* 根据id删除用户(后期修改为改变状态)
* @param id
*/
void deleteByPrimaryKey(Integer id); /**
* 查询所有用户列表
* @return
*/
List<User> findAll();
}

IUserMapper

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
* @author wusiwee
* @date 2020/4/3 11:00
*/
@Mapper
public interface IPermissionMapper { /**
* 根据user id查询用户权限
* @param userId
* @return
*/
List<Permission> findPermissionByUserId(Integer userId);
}

IPermissionMapper

service层:

import java.util.List;

public interface UserService {

    User findByUsername(String username);

    List<User> findAll();
}

UserService

import com.bear.dao.IUserMapper;
import com.bear.entity.User;
import com.bear.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.List; @Service
public class UserServiceImpl implements UserService { @Autowired
private IUserMapper userMapper; @Override
public User findByUsername(String username) {
User result = null;
if (username != null) {
result = this.userMapper.findByUsername(username);
}
return result;
} @Override
public List<User> findAll() {
return this.userMapper.findAll();
}
}

UserServiceImpl

import com.bear.entity.Permission;

import java.util.List;

/**
* @author wusiwee
* @date 2020/4/3 11:02
*/
public interface PermissionService { List<Permission> findPermissionByUserId(Integer userId);
}

PermissionService

import com.bear.dao.IPermissionMapper;
import com.bear.entity.Permission;
import com.bear.service.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.List; /**
* @author wusiwee
* @date 2020/4/3 11:02
*/
@Service
public class PermissionServiceImpl implements PermissionService { @Autowired
private IPermissionMapper permissionMapper; @Override
public List<Permission> findPermissionByUserId(Integer userId) {
List<Permission> result = null;
if (userId != null) {
result = this.permissionMapper.findPermissionByUserId(userId);
}
return result;
}
}

PermissionServiceImpl

controller层(注意Login方法的subject为shiro登录使用):

注解@RequiresPermissions("system:*")为校验用户是否有权限,没有此权限则不允许访问此方法 跳转401
import com.bear.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping("/bear")
public class LoginController { @Autowired
private UserService userService; @GetMapping("toLogin")
public String toLogin(){
return "login";
} @GetMapping("/login")
public String login(String username, String password, Model model){
if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)){
//进行登录验证
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
//认证
boolean authenticated = subject.isAuthenticated();
if (authenticated){
//获取当前对象,存入session
User user = (User)subject.getPrincipal();
subject.getSession().setAttribute("user",user);
System.out.println("登陆成功");
return "redirect:index";
}else {
model.addAttribute("msg","登录认证失败!");
return "login";
}
}catch (Exception e){
model.addAttribute("msg","登录认证失败!");
return "login";
} }
return "login";
}
@RequestMapping("/index")
public String index(Model model){
model.addAttribute("userList",this.userService.findAll());
return "index";
} @RequestMapping("/logout")
public String index(){
return "redirect:login";
} @RequestMapping("/401")
public String fours(){
return "401";
} @RequiresPermissions("system")
@RequestMapping("/success")
public String success(){
return "success";
}
}

LoginController

html 页面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>成功页面</title>
</head>
<body>
SUCCESS!
</body>
</html>

success页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h2>欢迎来到登录页面!</h2>
<form action="/bear/login" method="GET" name="loginForm">
登录用户:<input type="text" name="username" value=""><br/>
登录密码:<input type="text" name="password" value=""><br/>
<input type="submit" name="log" value="登录">
</form>
<!--/*@thymesVar id="msg" type="at"*/-->
<div th:text="${msg}"></div>
</body>
</html>

login页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首面</title>
</head>
<style>
table{
border: 1px solid grey;
border-collapse: collapse;
}
table td{
border: 1px solid grey;
border-collapse: collapse;
}
</style>
<body>
<h2>用户列表页面</h2>
<table>
<tr>
<td>用户ID</td>
<td>用户名</td>
<td>手机号</td>
<td>邮箱</td>
<td>状态</td>
<td>创建时间</td>
</tr>
<tr th:each="user:${userList}">
<td th:text="${user.userId}"></td>
<td th:text="${user.userName}"></td>
<td th:text="${user.phone}"></td>
<td th:text="${user.email}"></td>
<td th:text="${user.status == 1?'正常':'失效'}">正常</td>
<td th:text="${user.createTime}"></td>
</tr>
</table>
<form action="/bear/logout" method="get">
<input type="submit" value="退出">
</form>
</body>
</html>

index页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>401没有认证</title>
</head>
<body>
<h2>抱歉,您的权限不足或认证失败,请重新登录!</h2>
</body>
</html>

401没有权限页面

配置完成

启动运行Applicaiton.java,最后一行,启动成功  

. ____ _ __ _ _

/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE) 2020-04-07 15:11:42.580 INFO 14672 --- [ main] com.bear.PublicApplication : Starting PublicApplication on shands-siwee with PID 14672 (D:\java\GitProjects\bear-world\target\classes started by Shands-New in D:\java\GitProjects\bear-world)
2020-04-07 15:11:42.584 INFO 14672 --- [ main] com.bear.PublicApplication : No active profile set, falling back to default profiles: default
2020-04-07 15:11:43.534 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'shiroConfig' of type [com.bear.shiro.ShiroConfig$$EnhancerBySpringCGLIB$$45102fe0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.599 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties' of type [org.mybatis.spring.boot.autoconfigure.MybatisProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.604 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration' of type [org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$6a2f2642] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.605 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Generic' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Generic] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.617 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.665 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'dataSource' of type [com.alibaba.druid.pool.DruidDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.677 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.923 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sqlSessionFactory' of type [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.926 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sqlSessionTemplate' of type [org.mybatis.spring.SqlSessionTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.928 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'IUserMapper' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.929 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'IUserMapper' of type [com.sun.proxy.$Proxy63] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.929 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'userServiceImpl' of type [com.bear.service.impl.UserServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.932 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'IPermissionMapper' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.932 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'IPermissionMapper' of type [com.sun.proxy.$Proxy64] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.932 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'permissionServiceImpl' of type [com.bear.service.impl.PermissionServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:43.933 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'shiroReaml' of type [com.bear.shiro.ShiroReaml] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:44.601 INFO 14672 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'securityManager' of type [org.apache.shiro.web.mgt.DefaultWebSecurityManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-07 15:11:44.857 INFO 14672 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2020-04-07 15:11:44.868 INFO 14672 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-04-07 15:11:44.868 INFO 14672 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.33]
2020-04-07 15:11:45.041 INFO 14672 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-04-07 15:11:45.042 INFO 14672 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2400 ms
2020-04-07 15:11:45.231 INFO 14672 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-04-07 15:11:45.301 INFO 14672 --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
2020-04-07 15:11:45.356 WARN 14672 --- [ main] org.thymeleaf.templatemode.TemplateMode : [THYMELEAF][main] Template Mode 'HTML5' is deprecated. Using Template Mode 'HTML' instead.
2020-04-07 15:11:45.455 INFO 14672 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2020-04-07 15:11:45.458 INFO 14672 --- [ main] com.bear.PublicApplication : Started PublicApplication in 3.516 seconds (JVM running for 4.842)

启动程序

测试访问 :localhost:8081/bear/index ——>此时是被拦截的,会自动跳转toLogin到登录页面

 

spring-boot整合shiro作权限认证的更多相关文章

  1. Spring Boot 整合 Shiro ,两种方式全总结!

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  2. Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  3. Spring Boot 整合 Shiro实现认证及授权管理

    Spring Boot Shiro 本示例要内容 基于RBAC,授权.认证 加密.解密 统一异常处理 redis session支持 介绍 Apache Shiro 是一个功能强大且易于使用的Java ...

  4. Spring boot整合shiro权限管理

    Apache Shiro功能框架: Shiro聚焦与应用程序安全领域的四大基石:认证.授权.会话管理和保密. #,认证,也叫作登录,用于验证用户是不是他自己所说的那个人: #,授权,也就是访问控制,比 ...

  5. spring boot 2 + shiro 实现权限管理

    Shiro是一个功能强大且易于使用的Java安全框架,主要功能有身份验证.授权.加密和会话管理.看了网上一些文章,下面2篇文章写得不错.Springboot2.0 集成shiro权限管理 Spring ...

  6. spring boot整合shiro后,部分注解(Cache缓存、Transaction事务等)失效的问题

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/elonpage/article/details/78965176 前言 整合有缓存.事务的sprin ...

  7. Spring boot整合shiro框架

    ShiroConfiguration package com.energy.common.config; import java.util.LinkedHashMap; import java.uti ...

  8. spring boot整合shiro出现UnavailableSecurityManagerException

    spring boot自带spring security,spring security自然不用说是一个强大的安全框架,但是用惯了shiro,一时半会用不来spring security,所以要在sp ...

  9. 上手spring boot项目(二)之spring boot整合shiro安全框架

    题记:在学习了springboot和thymeleaf之后,想完成一个项目练练手,于是使用springboot+mybatis和thymeleaf完成一个博客系统,在完成的过程中出现的一些问题,将这些 ...

随机推荐

  1. GIT URI

    https://u3shadow@code.google.com/p/myandorid/

  2. Robot Framework 接口自动化介绍

    接口测试的重要性大家应该都清楚,就不多说了,本文中主要介绍接口测试如何在robot framework自动化测试框架中进行. 一.环境依赖 1.安装robot framework环境,本文中不做讲解 ...

  3. Sharepoint2013商务智能学习笔记之简单概述(一)

    SharePoint 2013 中的商业智能 (BI) 提供集 Microsoft Office 应用程序和其他 Microsoft 技术于一体的全面的 BI 工具.这些 BI 工具有:Excel 2 ...

  4. 没有定义json_encode()函数。

    php5是没有json扩展的,需要自行下载. 命令php -m 可以查看安装了哪些扩展. 1.修改php.ini 在php.ini 中加入 extension=json.so:sudo vi /etc ...

  5. vue+element-ui 实现分页

    <el-table ref="multipleTable" :data="tableData.slice((currentPage-1)*pagesize,curr ...

  6. 对 React Context 的理解以及应用

    在React的官方文档中,Context被归类为高级部分(Advanced),属于React的高级API,但官方并不建议在稳定版的App中使用Context. 很多优秀的React组件都通过Conte ...

  7. 洛谷P4121 [WC2005]双面棋盘(线段树套并查集)

    传送门 先膜一下大佬->这里 据说这题正解是LCT,然而感觉还是线段树套并查集的更容易理解 我们对于行与行之间用线段树维护,每一行内用并查集暴力枚举 每一行内用并查集暴力枚举连通块这个应该容易理 ...

  8. [Xcode 实际操作]五、使用表格-(7)UITableView单元格间隔背景色

    目录:[Swift]Xcode实际操作 本文将演示如何给表格设置间隔的背景颜色. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //首先 ...

  9. Python中print()函数不换行的方法

    一.让print()函数不换行 在Python中,print()函数默认是换行的.但是,在很多情况下,我们需要不换行的输出(比如在算法竞赛中).那么,在Python中如何做到这一点呢? 其实很简单.只 ...

  10. 同源策略与CORS跨域请求

    一.同源策略 1.简介 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源 ...