SpringBoot+shiro+mybatis+Thymeleaf实现权限登录系统

记录一下,学习shiro的一个小Demo:

1.首先是底层数据库:

-- ----------------------------
-- Table structure for role
-- ----------------------------
CREATE TABLE `role`  (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色表主键',`role_name` varchar(32) DEFAULT NULL COMMENT '角色名称',PRIMARY KEY (`id`)
);-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, 'SUPER_ADMIN');
INSERT INTO `role` VALUES (2, 'ADMIN');
INSERT INTO `role` VALUES (3, 'USER');-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户主键',`username` varchar(32) NOT NULL COMMENT '用户名',`password` varchar(32) NOT NULL COMMENT '密码',`role_id` int(11) DEFAULT NULL COMMENT '与role角色表联系的外键',PRIMARY KEY (`id`),CONSTRAINT `user_role_on_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
);-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'BWH_Steven', '666666', 1);
INSERT INTO `user` VALUES (2, 'admin', '666666', 2);
INSERT INTO `user` VALUES (3, 'zhangsan', '666666', 3);-- ----------------------------
-- Table structure for permission
-- ----------------------------
CREATE TABLE `permission`  (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限表主键',`permission_name` varchar(50) NOT NULL COMMENT '权限名',`role_id` int(11) DEFAULT NULL COMMENT '与role角色表联系的外键',PRIMARY KEY (`id`),CONSTRAINT `permission_role_on_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
);-- ----------------------------
-- Records of permission
-- ----------------------------
INSERT INTO `permission` VALUES (1, 'user:*', 1);
INSERT INTO `permission` VALUES (2, 'user:*', 2);
INSERT INTO `permission` VALUES (3, 'user:queryAll', 3);

2.创建spring boot项目,用maven构建

创建实体类(User,Role,Permissions):User:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Integer id;private String username;private String password;//用户对应的角色集合private Role role;
}

Role:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {private Integer id;private String roleName;}

Permissions:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Permissions {private Integer id;private String permissionName;private Role role;
}

我们需要知道三个实体类之间的关系,User与Role一对一,Role与Permissions一对一,当然也可以把它都写成多对多,这就需要去更改数据库文件,和实体类了。

3.在pom.xml添加相关依赖:

下面只给出相关依赖源

<dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.5.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></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><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>

4.整合mybatis和springboot:

就只需要创建一个dao层,一个服务层,需要记住要添加注解
(1)mapper配置文件(也可以使用注解形式):

<?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.example.csy.dao.UserMapper"><select id="queryUserByUsername" resultMap="userRoleMap">SELECT u.*,r.role_name FROM `user` u, `role` rWHERE username = #{username} AND u.role_id = r.id;</select><!-- 定义封装 User和 role 的 resultMap --><resultMap id="userRoleMap" type="com.example.csy.entity.User"><id property="id" column="id"/><result property="username" column="username"></result><result property="password" column="password"></result><!-- 配置封装 UserPojo 的内容 --><association property="role" javaType="com.example.csy.entity.Role"><id property="id" column="id"></id><result property="roleName" column="role_name"></result></association></resultMap><select id="queryPermissionByUsername" resultMap="permissionRoleMap">SELECT p.* ,r.role_name FROM `user` u, `role` r, `permission` pWHERE username = #{username} AND u.role_id = r.id AND p.role_id = r.id;</select><!-- 定义封装 permission 和 role 的 resultMap --><resultMap id="permissionRoleMap" type="com.example.csy.entity.Permissions"><id property="id" column="id"/><result property="permissionName" column="permission_name"></result><!-- 配置封装 Role 的内容 --><association property="role" javaType="com.example.csy.entity.Role"><id property="id" column="id"></id><!--property是实体类中被赋值的参数名,column是数据库的列名--><result property="roleName" column="role_name"></result></association></resultMap>
</mapper>

(2)DAO层:

@Mapper
public interface UserMapper {User queryUserByUsername(@Param("username") String username);Permissions queryPermissionByUsername(@Param("username") String username);
}

(3)service层:

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic User queryUserByUsername(String username) {return userMapper.queryUserByUsername(username);}@Overridepublic Permissions queryPermissionByUsername(String username) {return userMapper.queryPermissionByUsername(username);}
}

弄到这里,我们的mybatis+springboot整合也基本结束,所以在测试类里测试一下:

@SpringBootTest
class CsyApplicationTests {@Autowiredprivate UserMapper userMapper;@Testvoid contextLoads() {User admin = userMapper.queryUserByUsername("admin");System.out.println(admin.toString());Permissions permission = userMapper.queryPermissionByUsername("admin");System.out.println(permission.toString());}
}

测试结果:
得到了查询结果

6.整合Thymeleaf进来:

前端页面:
在html页面我们整合了Thymeleaf,使用了Jquery,semantic,需要导包

index.html代码:
在这里,如果是User就只能访问A,Admin能访问A,B,superAdmin能访问A,B,C

<!DOCTYPE html>
<html lang="zh_CN"xmlns:th="http://www.thymeleaf.org"xmlns="http://www.w3.org/1999/xhtml"xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"
>
<html lang="en">
<head><meta charset="UTF-8"><title>信息管理平台-首页</title><metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1"/><title>首页</title><!--semantic-ui--><linkhref="https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css"rel="stylesheet"/><!--<link href="css/index.css" rel="stylesheet">--><link th:href="@{/css/index.css}" rel="stylesheet"><!-- <script th:src="@{js/jquery-3.1.1.min.js}"></script> --><script src="js/jquery-3.1.1.min.js"></script>
</head>
<body>
<div class="ui container"><div class="ui secondary menu"><a class="active item" th:href="@{/index}">首页</a><a class="active item" th:href="@{/about}">关于</a><!--登录注销--><div class="right menu"><!--如果未登录--><!--<div shiro:authorize="!isAuthenticated()">--><div shiro:notAuthenticated=""><a class="item" th:href="@{/toLoginPage}"><i class="address card icon"></i> 登录</a></div><!--如果已登录--><div shiro:authenticated=""><a class="item"><i class="address card icon"></i>用户名:<span shiro:principal></span><!--角色:<span sec:authentication="principal.authorities"></span>--></a></div><div shiro:authenticated=""><a class="item" th:href="@{/logout}"><i class="address card icon"></i> 注销</a></div></div></div><div class="ui stackable three column grid"><div class="column" shiro:hasAnyRoles="USER,ADMIN,SUPER_ADMIN"><!--有其中任一一个角色课访问--><div class="ui raised segments"><div class="ui segment"><a th:href="@{/levelA/a}">L-A-a</a></div><div class="ui segment"><a th:href="@{/levelA/b}">L-A-b</a></div><div class="ui segment"><a th:href="@{/levelA/c}">L-A-c</a></div></div></div><div class="column" shiro:hasAnyRoles="ADMIN,SUPER_ADMIN"><div class="ui raised segments"><div class="ui segment"><a th:href="@{/levelB/a}">L-B-a</a></div><div class="ui segment"><a th:href="@{/levelB/b}">L-B-b</a></div><div class="ui segment"><a th:href="@{/levelB/c}">L-B-c</a></div></div></div><div class="column" shiro:hasRole="SUPER_ADMIN"><div class="ui raised segments"><div class="ui segment"><a th:href="@{/levelC/a}">L-C-a</a></div><div class="ui segment"><a th:href="@{/levelC/b}">L-C-b</a></div><div class="ui segment"><a th:href="@{/levelC/c}">L-C-c</a></div></div></div><!-- <div class="column"></div> --></div><div class="ui stacked segment"><div class="ui stackable three column grid"><div class="column"><p>晚风吹起你鬓间的白发<br/>抚平回忆留下的疤<br/>你的眼中 明暗交杂 一笑生花<br/>暮色遮住你蹒跚的步伐<br/>走进床头藏起的画<br/>画中的你 低着头说话<br/>我仍感叹于世界之大</p></div><div class="column"><p>也沉醉于儿时情话<br/>不剩真假 不做挣扎 无谓笑话<br/>我终将青春还给了她<br/>连同指尖弹出的盛夏<br/>心之所动 就随风去了<br/>以爱之名 你还愿意吗<br/>❤</p></div><div class="column"><img class="ui medium circular image" src="data:images/001.jpg"></div></div></div><div class="ui info message"><div class="header">理想二旬不止</div><p>BWH_Steven</p></div>
</div></body>
</html>

login.html代码:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"xmlns="http://www.w3.org/1999/xhtml"xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
>
<head><meta charset="UTF-8"><title>用户管理系统-登录</title><!-- <script th:src="@{js/jquery-3.1.1.min.js}"></script> --><script src="js/jquery-3.1.1.min.js"></script><linkhref="https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css"rel="stylesheet"/>
</head>
<body>
<h1>用户管理系统-登录</h1>
<div class="ui container" style="margin-top: 180px;"><div style="text-align: center; margin-bottom: 20px;"><h1 class="header">登录</h1></div><div class="ui three column stackable grid login-div"><div class="column"></div><div class="column"><form id="login" class="ui fluid form segment" th:action="@{/login}" method="post"><div class="field"><label class="">用户名</label><div class="ui left icon input"><input type="text" name="username" placeholder=""/><i class="user icon"></i><div class="ui corner label"><i class="icon asterisk"></i></div></div></div><div class="field"><label class="">密码</label><div class="ui left icon input"><input type="password" name="password" placeholder=""/><i class="lock icon"></i><div class="ui corner label"><i class="icon asterisk"></i></div></div></div><div class="inline field"><div class="ui checkbox"><input type="checkbox" name="terms"/><label>记住密码</label></div></div><div class="inline field"><input type="submit" class="ui blue submit button"></div></form></div><div class="column"></div></div>
</div></body>
</html>

success.html:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>用户管理系统-成功</title>
</head>
<body>
<h2>登录成功</h2>
<a href="/index">返回主页</a>
</body>
</html>

7.将shiro整合到项目里:

(1)自定义Realm:

我们需要自定义,认证和授权:

public class UserRealm extends AuthorizingRealm {@Autowiredprivate UserMapper userMapper;/*** @MethodName doGetAuthorizationInfo 授权操作* @Description 权限配置类* @Param [principalCollection]* @Return AuthorizationInfo*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {// 获取用户名信息String username = (String) principalCollection.getPrimaryPrincipal();// 创建一个简单授权验证信息SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();// 给这个用户设置从 role 表获取到的角色信息authorizationInfo.addRole(userMapper.queryUserByUsername(username).getRole().getRoleName());//给这个用户设置从 permission 表获取的权限信息authorizationInfo.addStringPermission(userMapper.queryPermissionByUsername(username).getPermissionName());return authorizationInfo;}/*** @MethodName doGetAuthenticationInfo 身份验证* @Description 认证配置类* @Param [authenticationToken]* @Return AuthenticationInfo* @Author WangShiLin*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {// 根据在接受前台数据创建的 Token 获取用户名String username = (String) authenticationToken.getPrincipal();//        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
//        System.out.println(userToken.getPrincipal());
//        System.out.println(userToken.getUsername());
//        System.out.println(userToken.getPassword());// 通过用户名查询相关的用户信息(实体)User user = userMapper.queryUserByUsername(username);if (user != null) {// 存入 Session,可选SecurityUtils.getSubject().getSession().setAttribute("user", user);// 密码认证的工作,Shiro 来做AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), "userRealm");return authenticationInfo;} else {// 返回 null 即会抛异常return null;}}
}

(2)写配置类shiroConfig:

@Configuration
public class ShiroConfig {//将自己的验证方式加入容器@Beanpublic UserRealm myShiroRealm() {return new UserRealm();}/*** 配置安全管理器 SecurityManager** @return*/@Beanpublic DefaultWebSecurityManager securityManager() {// 将自定义 Realm 加进来DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 关联 RealmsecurityManager.setRealm(myShiroRealm());return securityManager;}/*** 配置 Shiro 过滤器** @param securityManager* @return*/@Beanpublic ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {// 定义 shiroFactoryBeanShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 关联 securityManagershiroFilterFactoryBean.setSecurityManager(securityManager);// 自定义登录页面,如果登录的时候,就会执行这个请求,即跳转到登录页shiroFilterFactoryBean.setLoginUrl("toLoginPage");// 指定成功页面shiroFilterFactoryBean.setSuccessUrl("/success");// 指定未授权界面shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");// 设置自定义 filterMap<String, Filter> filterMap = new LinkedHashMap<>();filterMap.put("anyRoleFilter", new MyRolesAuthorizationFilter());shiroFilterFactoryBean.setFilters(filterMap);// LinkedHashMap 是有序的,进行顺序拦截器配置Map<String, String> filterChainMap = new LinkedHashMap<>();// 配置可以匿名访问的地址,可以根据实际情况自己添加,放行一些静态资源等,anon 表示放行filterChainMap.put("/css/**", "anon");filterChainMap.put("/img/**", "anon");filterChainMap.put("/js/**", "anon");// 指定页面放行,例如登录页面允许所有人登录filterChainMap.put("/toLoginPage", "anon");// 以“/user/admin” 开头的用户需要身份认证,authc 表示要进行身份认证filterChainMap.put("/user/admin/**", "authc");// 页面 -用户需要角色认证filterChainMap.put("/levelA/**", "anyRoleFilter[USER,ADMIN,SUPER_ADMIN]");filterChainMap.put("/levelB/**", "anyRoleFilter[ADMIN,SUPER_ADMIN]");filterChainMap.put("/levelC/**", "anyRoleFilter[SUPER_ADMIN]");//        filterChainMap.put("/levelA/**", "roles[USER]");
//        filterChainMap.put("/levelB/**", "roles[ADMIN]");
//        filterChainMap.put("/levelC/**", "roles[SUPER_ADMIN]");// /user/admin/ 下的所有请求都要经过权限认证,只有权限为 user:[*] 的可以访问,也可以具体设置到 user:xxxfilterChainMap.put("/user/admin/**", "perms[user:*]");// 配置注销过滤器filterChainMap.put("/logout", "logout");// 将Map 存入过滤器shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);return shiroFilterFactoryBean;}/*** 整合 thymeleaf* @return*/@Bean(name = "shiroDialect")public ShiroDialect shiroDialect(){return new ShiroDialect();}

首先我们将自定义的Realm方法,依赖注入进来到容器

//将自己的验证方式加入容器@Beanpublic UserRealm myShiroRealm() {return new UserRealm();}

然后是:SecurityManager配置安全管理器

/*** 配置安全管理器 SecurityManager** @return*/@Beanpublic DefaultWebSecurityManager securityManager() {// 将自定义 Realm 加进来DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 关联 RealmsecurityManager.setRealm(myShiroRealm());return securityManager;}

最后就是自定义的过滤器,控制那些页面需要什么样的角色才能访问,哪些资源需要谁才能访问,并且setSecurityManager,返回一个ShiroFilterFactoryBean。

重点说一下拦截放行(Map)这块:通过 map 键值对的形式存储,key 存储 URL ,value 存储对应的一些权限或者角色等等,其实 key 这块还是很好理解的,例如 :/css/、/user/admin/ 分别代表 css 文件夹下的所有文件,以及请求路径前缀为 /user/admin/ URL,而对应的 value 就有一定的规范了。

关键:
anon:无需认证,即可访问,也就是游客也可以访问
authc:必须认证,才能访问,也就是例如需要登录后
roles[xxx] :比如拥有某种角色身份才能访问 ,注:xxx为角色参数
perms[xxx]:必须拥有对某个请求、资源的相关权限才能访问,注:xxx为权限参数

(3)自定义一个角色认证过滤器MyRolesAuthorizationFilter:

因为我们的角色,只需用有一个角色就能访问到映射页面,shiro默认是hasAllRoles,也就是说,我们要满足所有的身份才能访问,所以需要我们自定义一个hasAnyRoles,任选其一角色即可。

public class MyRolesAuthorizationFilter extends AuthorizationFilter {@SuppressWarnings({"unchecked"})public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {Subject subject = getSubject(request, response);String[] rolesArray = (String[]) mappedValue;if (rolesArray == null || rolesArray.length == 0) {//no roles specified, so nothing to check - allow access.return false;}List<String> roles = CollectionUtils.asList(rolesArray);boolean[] hasRoles = subject.hasRoles(roles);for (boolean hasRole : hasRoles) {if (hasRole) {return true;}}return false;}
}

(4)最后就是controller

controller是springMvc的前端控制器,接收什么请求,并且返回对应指定的页面(映射)。
首先我们先将所以页面的映射写好,

PageController:

@Controller
public class PageController {@RequestMapping({"/", "index"})public String index() {return "index";}@RequestMapping("about")public String toAboutPage() {return "redirect:http://www.ideal-20.cn";}@RequestMapping("/toLoginPage")public String toLoginPage() {return "views/login";}@RequestMapping("/levelA/{name}")public String toLevelAPage(@PathVariable("name") String name) {return "views/L-A/" + name;}@RequestMapping("/levelB/{name}")public String toLevelBPage(@PathVariable("name") String name) {return "views/L-B/" + name;}@RequestMapping("/levelC/{name}")public String toLevelCPage(@PathVariable("name") String name) {return "views/L-C/" + name;}@RequestMapping("/unauthorized")public String toUnauthorizedPage() {return "views/unauthorized";}@RequestMapping("/success")public String toSuccessPage() {return "views/success";}}

UserController:
上面那两个映射,只是测试,主要是那个login方法,他可以根据我们前台输入的数据,并创建一个token,如果该token能被认证,即返回成功页面,否则就失败。

@Controller
public class UserController {@RequestMapping("/user/queryAll")@ResponseBodypublic String queryAll() {return "这是 user/queryAll 方法";}@RequestMapping("/user/admin/add")@ResponseBodypublic String adminAdd() {return "这是 user/adminAdd 方法";}@RequestMapping("/login")public String login(String username, String password, HttpServletRequest request) {// 由于是根据name参数获取的,我这里封装了一下User user = new User();user.setUsername(username);user.setPassword(password);// 创建出一个 Token 内容本质基于前台的用户名和密码(不一定正确)UsernamePasswordToken token = new UsernamePasswordToken(username, password);// 获取 subject 认证主体(这里也就是现在登录的用户)Subject subject = SecurityUtils.getSubject();try{// 认证开始,这里会跳转到自定义的 UserRealm 中subject.login(token);// 可以存储到 session 中request.getSession().setAttribute("user", user);return "views/success";}catch(Exception e){// 捕获异常e.printStackTrace();request.getSession().setAttribute("user", user);request.setAttribute("errorMsg", "兄弟,用户名或密码错误");return "views/login";}}
}

8.最终效果:

首先是http://localhost:8080/index

登录界面:

表单提交后,就返回值到UserController那个Login方法,认证:

这样我们就登录成功了,并且是superAdmin的权限,可以查看A,B,C

而用户张三,只能看见A

到此结束,本博客借鉴:博客,需要源码的请查看此博客。

springboot实现权限列表_SpringBoot+shiro+mybatis+Thymeleaf实现权限登录相关推荐

  1. 超详细!附源码!SpringBoot+shiro+mybatis+Thymeleaf实现权限登录系统

    最近在做一个期末作品,就是使用ssm+thymeleaf+vue+shiro完成一个具有权限登录,且能实现用户信息增删查改的这么一个项目,下面仅仅是实现权限认证和登录.为什么我选shiro,而不选sp ...

  2. java 数据 权限_Java如何利用Mybatis进行数据权限控制详解

    前言 权限控制主要分为两块,认证(Authentication)与授权(Authorization).认证之后确认了身份正确,业务系统就会进行授权,现在业界比较流行的模型就是RBAC(Role-Bas ...

  3. springboot动态切换数据源_Springboot整合Mybatis注解实现动态数据源切换

    AbstractRoutingDataSource AbstractRoutingDataSource是spring-jdbc包提供的一个了AbstractDataSource的抽象类,它实现了Dat ...

  4. springboot 按钮权限验证_SpringBoot中实现Shiro控制ThymeLeaf界面按钮级权限控制

    需求简述 在业绩核算系统中,我们使用了SpringBoot作为项目的整体架构,使用ThymeLeaf作为前端界面框架,使用Shiro作为我们的权限控制框架,Shiro作为轻量级的权限框架,使用起来非常 ...

  5. 一篇搞定 SpringBoot+Mybatis+Shiro 实现多角色权限管理

    初衷:我在网上想找整合springboot+mybatis+shiro并且多角色认证的博客,发现找了好久也没有找到想到的,现在自己会了,就打算写个博客分享出去,希望能帮到你. 原创不易,请点赞支持! ...

  6. 全程配图超清晰的Springboot权限控制后台管理项目实战第二期(Springboot+shiro+mybatis+redis)

    全程配图超清晰的Springboot权限控制后台管理项目实战第二期(Springboot+shiro+mybatis+redis) 众所周知,作为一个后端新手学习者,通过项目来学习,增长项目经验,是一 ...

  7. springBoot+security+mybatis 实现用户权限的数据库动态管理

    [b][size=large]一.Spring Security 应用的概述[/size][/b] [size=medium] 鉴于目前微服务的兴起,Spring周边方案的普及,以及 Spring S ...

  8. thymeleaf模板+Shiro标签对按钮权限的控制

    thymeleaf模板+Shiro标签对按钮权限的控制 环境介绍 SpringBoot+Shiro+thymeleaf模板+Layui(前端) 这两天学习了shiro相关的技术,碰到一个问题:如何根据 ...

  9. springboot+mybatis+thymeleaf学习一个简单的管理系统

    在淘宝上买的课程的一个例子,看了视频,抄了一遍代码,那时候刚开始学springboot,所以感觉没什么用,然后就又学习了一段时间.最近回想起来有这样的一个系统符合我现阶段的学习程度,然后就又写了一遍. ...

  10. shiro利用mysql动态授权_SpringBoot+Shiro学习之数据库动态权限管理和Redis缓存

    发现问题,需找解决思路. 之前我们整合Shiro,完成了登录认证和权限管理的实现,登录认证没什么说的,需要实现AuthorizingRealm中的doGetAuthenticationInfo方法进行 ...

最新文章

  1. 把office文档转换为html过程中的一些坑
  2. 【转自元宝兄】关于delphi Com+调用C# DLL的一点说明
  3. 【机器学习】什么是机器学习?(上)
  4. 并行中的分区Partitioner
  5. [渝粤教育] 广东-国家-开放大学 21秋期末考试服务标准化10011k1
  6. 【转】Dynamics 365中配置和使用文件夹级别的跟踪(folder-level tracking)
  7. 为什么使用累积分布函数处理后像素值会均匀分布_亿万级数据处理的高效解决方案
  8. django再windows下测试命令总结
  9. Oracle大型数据库系统在AIX/UNIX上的实战详解
  10. 数商云钢材行业智慧供应商管理系统:降低企业运营成本,构建数字化供应商管理体系
  11. 萌娃投票程序php+mysql,PHP+MySql+jQuery实现的顶和踩投票功能
  12. PostgreSQL的upsert功能(on conflict do)的用法
  13. Win10自带OpenSSH的使用
  14. SDN:简述对SDN架构的认识
  15. TCP套接口的FIN_WAIT_2状态超时
  16. brpc源码学习(六)- brpc server 端整体流程
  17. Codeforces Round #731 (Div. 3)(ABCDEFG)
  18. 使用Xshell实现SSH隧道穿透
  19. Luogu P4707 重返现世
  20. Gbase 8s 产品特性

热门文章

  1. 一名董事长给大学生的18条忠告(全)
  2. flutter的路由工具类
  3. 华铭智能属于芯片概念吗_华铭智能:子公司1个亿参股边缘计算独角兽九次方大数据!...
  4. 软件技术方案模板_携手跨越,法本信息数字化解决方案赋能企业,共建数字未来...
  5. android 停止服务执行,android - 为什么在停止服务(执行onDestroy已执行)后,服务中的变量没有“重置”?...
  6. Request header field storeid is not allowed by Access-Control-Allow-Headers in preflight response.
  7. ELK logstash gork匹配在线测试
  8. BUG没确认就重启机器,大哥你凭什么说有这样的BUG
  9. LINUX下载编译Which
  10. 正确修改LINUX SHELL的.bashrc,显示短路径