springboot整合shiro的过程详解

目录
  • 什么是 Shiro
  • Shiro 架构
    • Shiro 架构图
    • Shiro 工作原理
    • Shiro 详细架构图
  • springboot 整合 shiro
    • springboot 整合 shiro 思路
  • 项目搭建
    • 主要依赖
    • 数据库表设计
    • 实体类
    • 自定义 Realm
  • shiro 的配置类
    • ShiroFilterFactoryBean 过滤器链配置中的 url 匹配规则
    • ShiroFilterFactoryBean 过滤器
    • ShiroFilterFactoryBean 过滤器分类
  • 前端页面
    • 登录页面 login.html
    • 首页页面 index.html
    • 添加页面 add.html
    • 更新页面 update.html
    • 未授权页面 unauthorized.html
  • controller 控制器
    • shiro 注解
  • 测试
    • 测试一
  • 小结

什么是 Shiro

Shiro 是一个强大的简单易用的 Java 安全框架,主要用来更便捷的 认证,授权,加密,会话管理Shiro 首要的和最重要的目标就是容易使用并且容易理解,通过 Shiro 易于理解的API,您可以快速、轻松地获得任何应用程序——从最小的移动应用程序最大的网络和企业应用程序

Shiro 架构

Shiro 架构图

  • Authentication:身份认证/登录
  • Authorization:验证权限,即,验证某个人是否有做某件事的权限
  • Session Management:会话管理。管理用户特定的会话,支持 web 与非 web
  • Cryptography: 加密,保证数据安全
  • Caching:缓存
  • Remember Me:记住我,即记住登录状态,一次登录后,下次再来的话不用登录了

Shiro 工作原理

Shiro 的架构有三个主要概念:SubjectSecurityManagerRealms

  • Subject:当前参与应用安全部分的主角。可以是用户,可以试第三方服务,可以是 cron 任务,或者任何东西。主要指一个正在与当前软件交互的东西。所有 Subject 都需要 SecurityManager,当你与 Subject 进行交互,这些交互行为实际上被转换为与 SecurityManager 的交互
  • SecurityManager:安全管理器,Shiro 架构的核心,它就像 Shiro 内部所有原件的保护伞。然而一旦配置了 SecurityManagerSecurityManager 就用到的比较少,开发者大部分时间都花在 Subject 上面。当你与 Subject 进行交互的时候,实际上是 SecurityManager在 背后帮你举起 Subject 来做一些安全操作
  • RealmsRealms 作为 Shiro 和你的应用的连接桥,当需要与安全数据交互的时候,像用户账户,或者访问控制,Shiro 就从一个或多个 Realms 中查找。Shiro 提供了一些可以直接使用的 Realms,如果默认的 Realms不能满足你的需求,你也可以定制自己的 Realms

Shiro 详细架构图

  • Subject:与应用交互的主体,例如用户,第三方应用等
  • SecurityManagershiro 的核心,负责整合所有的组件,使他们能够方便快捷完成某项功能。例如:身份验证,权限验证等
  • Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得 Shiro 默认的不好,可以自定义实现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了。
  • Authorizer:决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能
  • SessionManager:会话管理。CacheManager:缓存管理器。创建和管理缓存,为 authentication, authorizationsession management 提供缓存数据,避免直接访问数据库,提高效率
  • Cryptography;密码模块,提供加密组件
  • Realms:可以有 1 个或多个 Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是 JDBC 实现,也可以是 LDAP 实现,或者内存实现等等;由用户提供;注意:Shiro 不知道你的用户/权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的 Realm

springboot 整合 shiro

springboot 整合 shiro 思路

项目搭建

主要依赖

<!--thymeleaf 模板引擎-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--shiro-->
<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-spring-boot-starter</artifactId>
	<version>1.4.0</version>
</dependency>
<!-- thymeleaf 集成 shiro -->
<dependency>
	<groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
	<version>2.0.0</version>
</dependency>

数据库表设计

CREATE TABLE `shiro_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `nickname` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;

INSERT INTO `shiro_user` VALUES (1, 'lisi', '110110', '李四');
INSERT INTO `shiro_user` VALUES (2, 'zs', '123456', '逆风飞翔');
INSERT INTO `shiro_user` VALUES (3, 'jack', '111111', '砥砺奋进');
INSERT INTO `shiro_user` VALUES (4, 'Tom', '123123', '静夜思');
INSERT INTO `shiro_user` VALUES (5, 'nike', '222222', '杀伤力巨大');

CREATE TABLE `shiro_user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

INSERT INTO `shiro_user_role` VALUES (1, 1, 1);
INSERT INTO `shiro_user_role` VALUES (2, 2, 3);
INSERT INTO `shiro_user_role` VALUES (3, 3, 3);
INSERT INTO `shiro_user_role` VALUES (4, 4, 2);

CREATE TABLE `shiro_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_code` varchar(255) NOT NULL,
  `role_name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

INSERT INTO `shiro_role` VALUES (1, '1', '管理员');
INSERT INTO `shiro_role` VALUES (2, '2', '普通一级用户');
INSERT INTO `shiro_role` VALUES (3, '3', '普通二级用户');
INSERT INTO `shiro_role` VALUES (4, '4', '普通三级用户');

CREATE TABLE `shiro_auth_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `auth_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;

INSERT INTO `shiro_auth_role` VALUES (1, 1, 1);
INSERT INTO `shiro_auth_role` VALUES (2, 2, 1);
INSERT INTO `shiro_auth_role` VALUES (3, 3, 1);
INSERT INTO `shiro_auth_role` VALUES (4, 4, 1);
INSERT INTO `shiro_auth_role` VALUES (5, 3, 2);
INSERT INTO `shiro_auth_role` VALUES (6, 4, 2);
INSERT INTO `shiro_auth_role` VALUES (7, 4, 3);
INSERT INTO `shiro_auth_role` VALUES (8, 4, 4);
INSERT INTO `shiro_auth_role` VALUES (9, 1, 3);

CREATE TABLE `shiro_auth` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `auth_code` varchar(255) NOT NULL,
  `auth_name` varchar(255) NOT NULL,
  `parent_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

INSERT INTO `shiro_auth` VALUES (1, 'user:add', '添加', 1);
INSERT INTO `shiro_auth` VALUES (2, 'user:delete', '删除', 2);
INSERT INTO `shiro_auth` VALUES (3, 'user:update', '更新', 3);
INSERT INTO `shiro_auth` VALUES (4, 'user:list', '查看', 4);

实体类

public class User implements Serializable {
    private Integer id;

    @NotBlank(message = "账号不能为空")
    private String username;

    @NotEmpty(message = "密码不能为空")
    private String password;

    private String nickname;

	// set/get方法省略
}

public class Role {
    private Integer id;

    private String roleCode;

    private String roleName;

	// set/get方法省略
}

public class Auth {
    private Integer id;

    private String authCode;

    private String authName;

    private Integer parentId;

	// set/get方法省略
}

自定义 Realm

realmshiro 进行登录认证,权限,角色校验的关键,我们需要重写里面的方法

@Component
@Slf4j
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    // 授权,权限操作
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(@NotNull PrincipalCollection principals) {
        log.info("------进入授权操作了------");
        User user = (User) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 通过账号来查询相应的角色,权限数据
        List<AuthAndRoleVO> authAndRoleVOS = userService.selectAuthAndRole(user.getUsername());
        authAndRoleVOS.forEach(item -> {
            log.info("查询到的权限,角色:" + item.toString());
            String roleName = item.getRoleName();
            String authCode = item.getAuthCode();
            info.addStringPermission(authCode);
            info.addRole(roleName);
        });
        return info;
    }

    // 认证操作
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        log.info("------进入认证操作了------");
        // 拿到UsernamePasswordToken,它里面有用户名,密码数据
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        // 查询数据库
        User user = userService.selectOne(usernamePasswordToken.getUsername(), String.valueOf(usernamePasswordToken.getPassword()));
        if (user == null) {
            return null;
        }
        return new SimpleAuthenticationInfo(user, token.getCredentials(), getName());
    }
}
  • 这里 ORM 持久层不再赘述,用 mybatisjpa 等都可以
  • doGetAuthorizationInfo(): 权限认证。即登录过后,每个用户的身份不一样,对应的所能看的页面也不一样,也就是拥有的权限也不一样
  • doGetAuthenticationInfo():身份认证。即登录通过账号和密码验证登陆人的身份信息

shiro 的配置类

@Configuration
public class ShiroConfig {

    /**
     * 安全管理器
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(userRealm);
        return defaultWebSecurityManager;
    }

    /**
     * thymeleaf模板引擎中使用shiro标签时,要用到
     */
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        // 设置登录页面url
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        shiroFilterFactoryBean.setSuccessUrl("/user/index");
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/unauthorized");

        // 注意此处使用的是LinkedHashMap是有顺序的,shiro会按从上到下的顺序匹配验证,匹配了就不再继续验证
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
		// 静态资源放行
        filterChainDefinitionMap.put("/layer/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/jquery/**", "anon");
        // add.html页面放行
        filterChainDefinitionMap.put("/user/add", "anon");
        // update.html必须认证
        filterChainDefinitionMap.put("/user/update", "authc");
        // index.html必须认证
        filterChainDefinitionMap.put("/user/index", "authc");
        // 设置授权,只有user:add权限的才能请求/user/add这个url
        filterChainDefinitionMap.put("/user/add", "perms[user:add]");
        filterChainDefinitionMap.put("/user/update", "perms[user:update]");     

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
}

ShiroFilterFactoryBean 过滤器链配置中的 url 匹配规则

  • ?:匹配一个字符,如 /admin?,将匹配 /admin1、/admin2,但不匹配 /admin
  • *:匹配零个或多个字符串,如 /admin* ,将匹配 /admin、/admin123,但不匹配 /admin/1
  • **:匹配路径中的零个或多个路径,如 /admin/**,将匹配 /admin/a、/admin/a/b

ShiroFilterFactoryBean 过滤器

  • anon:匿名过滤器,无需认证就可以访问。例:/statics/**= anon 表示 statics 目录下所有资源都能访问
  • authc:必须认证了才能访问,否则跳转到登录页面。例:/unauthor.jsp= authc 如果用户没有登录就访问 unauthor.jsp,则直接跳转到登录页面
  • user:必须通过记住我功能通过或认证通过才能访问
  • perms:拥有对某个资源的权限才能访问。例:/statics/** = perms["user:add:*,user:modify:*"] 表示访问 statics 目录下的资源时只有新增和修改的权限
  • roles:拥有某个角色权限才能访问。例:/welcom.jsp = roles[admin] 表示访问 welcom.jsp 页面时会检查是否拥有 admin 角色

ShiroFilterFactoryBean 过滤器分类

  • 认证过滤器:anon、authcBasic、auchc、user、logout
  • 授权过滤器:perms、roles、ssl、rest、port

前端页面

登录页面 login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <link rel="shortcut icon" type="image/x-icon" th:href="@{/img/favicon.ico}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" />
</head>
<body>
<form action="" method="post">
    <p>
        账号:
        <label><input type="text" class="username" name="username"></label>
    </p>
    <p>
        密码:
        <label><input type="text" class="password" name="password"></label>
    </p>
    <p>
        <label><input id="checkbox1" type="checkbox" name="rememberMe"></label>记住我
    </p>
    <p><button type="button" class="loginBtn">登录</button></p>
</form>
</body>
<script type="text/javascript" th:src="@{/jquery/jquery-3.3.1.min.js}"></script>
<script type="text/javascript" th:src="@{/layer/layer.js}"></script><!--layui的弹出层-->
<script type="text/javascript">
    $(document).ready(function () {
        $('.loginBtn').on('click', function () { // 登录按钮
            const username = $('.username').val();
            const password = $('.password').val();
            $.ajax({// 用户登录
                type: 'post',
                url: '/user/doLogin',
                dataType: 'json',
                data: ({
                    'username': username,
                    'password': password
                }),
                success: function (resp) {
                    console.log(resp);
                    if (resp.code !== 200) {
                        layer.msg(resp.message, function () {// layui的弹窗
                        });
                    } else if (resp.code === 200) {
                        window.location.href = 'http://127.0.0.1:8080'+ resp.action;
                    }
                },
                error: function () {// 此处添加错误处理
                    layer.open({
                        title: '提示信息',
                        content: '后台访问错误,请联系管理员',
                        skin: 'layui-layer-molv',
                        icon: 0
                    });
                }
            });
        });
    });
</script>
</html>

首页页面 index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <link rel="shortcut icon" type="image/x-icon" th:href="@{/img/favicon.ico}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" />
</head>
<body>
    <h1>首页</h1>

    <a th:href="@{/user/add}" rel="external nofollow" >add</a> | <a th:href="@{/user/update}" rel="external nofollow" >update</a><br>

    <a th:href="@{/user/logout}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >退出登录</a>
</body>
</html>

添加页面 add.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>add</title>
    <link rel="shortcut icon" type="image/x-icon" th:href="@{/img/favicon.ico}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" />
</head>
<body>
    <h1>add</h1><br>

    <a th:href="@{/user/logout}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >退出登录</a>
</body>
</html>

更新页面 update.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>update</title>
    <link rel="shortcut icon" type="image/x-icon" th:href="@{/img/favicon.ico}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" />
</head>
<body>
    <h1>update</h1><br>

    <a th:href="@{/user/logout}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >退出登录</a>
</body>
</html>

未授权页面 unauthorized.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>未授权</title>
    <link rel="shortcut icon" type="image/x-icon" th:href="@{/img/favicon.ico}" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" />
</head>
<body>
    <p1>未授权,无法访问此页面</p1></br>
    <a th:href="@{/user/index}" rel="external nofollow" >回到上一页</a>
</body>
</html>

controller 控制器

鉴于文章篇幅,这里只展示主要的逻辑代码

@Controller
@RequestMapping(path = "/user")
@Slf4j
public class UserController {

	@GetMapping(path = "/login")
    public String login() {
        return "login";
    }

    @GetMapping(path = "/index")
    public String index() {
        return "index";
    }

    @GetMapping(path = "/add")
    public String add() {
        return "add";
    }

    @GetMapping(path = "/update")
    public String update() {
        return "update";
    }

	// 未授权页面
    @GetMapping(path = "/unauthorized")
    public String unauthorized() {
        return "unauthorized";
    }

    // 用户登录
    @PostMapping(path = "/doLogin")
    @ResponseBody
    public ResultMap doLogin(@NotNull @Valid User user, @NotNull BindingResult bindingResult) {
        // ------参数校验------
        if (bindingResult.hasErrors()) {
            String message = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
            log.info("校验的message信息为:" + message);
            return new ResultMap().fail().message(message);
        }
        // 将用户名,密码交给shiro
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        String msg;
        try {
            // shiro帮我们匹配密码什么的,我们只需要把东西传给它,它会根据我们在UserRealm里认证方法设置的来验证
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            return new ResultMap().success().action("/user/index");
        } catch (AuthenticationException e) {
            if (e instanceof IncorrectCredentialsException) {
                msg = "密码错误";
            } else if (e instanceof LockedAccountException) {
                msg = "用户被禁用";
            } else if (e instanceof UnknownAccountException) {
                msg = "用户不存在";
            } else {
                msg = "用户认证失败";
            }
        }
        return new ResultMap().error().message(msg);
    }

    // 用户退出登录
    @GetMapping(path = "/logout")
    public String logout() {
        SecurityUtils.getSubject().logout();
        return "login";
    }
}

shiro 注解

在 contrller 的这些方法中,也可以使用 shiro 提供的一些注解来校验用户,认证用户。不过个人认为使用这些注解有点麻烦(因为有些注解会抛出异常,然后再 controller 层还要捕获异常),所以我在 ShiroConfig 配置类中进行了配置

  • @RequiresAuthentication:表示当前 Subject 已经通过 login 进行了身份验证;即 Subject.isAuthenticated() 返回 true
  • @RequiresUser:表示当前 Subject 已经通过身份验证或者通过记住我进行登录的
  • @RequiresGuest:表示当前 Subject 没有身份验证或通过记住我登录过,即是游客身份
  • @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND):表示当前 Subject 需要角色 admin 和 user。如果当前 Subject 不同时 拥有所有指定角色,则方法不会执行还会抛出 AuthorizationException 异常
  • @RequiresPermissions(value={“user:a”, “user:b”}, logical= Logical.OR):表示当前 Subject 需要权限 user:a 或 user:b。如果当前 Subject 不具有这样的权限,则方法不会被执行

测试

启动项目,首先进入登录页面 login.html,如下

我们分别以数据库中的 {jack,111111} 和 {Tom,123123} 账号与密码进行测试

测试一

首先使用 {jack,111111} 来进行登录,如下

进入首页页面,如下

我们在接着查看控制台日志,如下

我们看到首页页面有两个超链接页面,以用户 jack 的身份分别进入两个页面。首先进入 add.html 页面,如下

说明用户 jack 拥有访问 add.html 的权限,此时在查看控制台日志,如下

注意查看用户 jack 的数据,他的权限只有 user/add 和 user/list,是没有 user/update 权限的,也就是没有权限访问 update.html 页面的。可以验证,我们再以用户 jack 的身份进入 update.html 页面,如下

关于测试,到此为止。当然,依然可以使用其他的数据在进行测试

小结

shiro 最为关键的就是 realm 了,继承 AuthorizingRealm,然后重写两个方法

  • doGetAuthorizationInfo(): 权限认证。即登录过后,每个用户的身份不一样,对应的所能看的页面也不一样,也就是拥有的权限也不一样
  • doGetAuthenticationInfo():身份认证。即登录通过账号和密码验证登陆人的身份信息

在 controller 中的核心登录操作,就是将前端页面用户的登录数据(如账号,密码)交给 UsernamePasswordToken,然后使用当前的 Subject 对象调用 login(token) 方法即可,如下

// 将用户名,密码交给shiro
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());

// shiro帮我们匹配密码什么的,我们只需要把东西传给它,它会根据我们在UserRealm里认证方法设置的来验证
Subject subject = SecurityUtils.getSubject();
subject.login(token);

源码:springboot-shiro

到此这篇关于springboot整合shiro的文章就介绍到这了,更多相关springboot整合shiro内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • shiro 与 SpringMVC的整合完美示例

    想要整合Shiro和springmvc,在网上找了很多例子,感觉都有一点复杂.所以就自己写了一个最简单整合项目,记录在这里以备后面查看. 这个例子包含如下三个部分: 1.简单的页面 2.shiro配置 3.springmvc配置 shiro可以直接和spring整合,但是这样需要单独配置spring用于整合shiro,在配置springmvc.配置文件看起来乱七八糟的.所以这里就shiro不采用spring来管理.因此这里的整合类似 shiro + servlet + springmvc.这样配

  • springboot整合shiro实现记住我功能

    前言 上一篇文章我们完成了在 thymeleaf 模板引擎中使用 shiro 标签,也就是根据不同的用户身份信息,前端页面来显示不同的页面内容.本篇文章我们来完成在登录页面的记住我的功能 springboot 整合 shiro 之实现记住我 项目依然使用 springboot整合shiro这个项目,稍稍改动即可完成记住我的功能 配置类 ShiroConfig 完整的代码如下 @Configuration public class ShiroConfig { /** * 安全管理器 * * @pa

  • Java Apache Shiro安全框架快速开发详解流程

    目录 一.Shiro简介: shiro功能: Shiro架构(外部) Shiro架构(内部) 二.快速入门 1.拷贝案例 2.分析代码 三.SpringBoot 集成 Shiro 1.编写测试环境 2.使用 1.登录拦截 2.用户认证 四.Shiro整合Mybatis 五.实现请求授权 六.Shiro整合Thymeleaf 一.Shiro简介: Apache Shiro是一个Java的安全(权限)框架. Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在Ja

  • springboot整合shiro之thymeleaf使用shiro标签的方法

    thymeleaf介绍 简单说, Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP .相较与其他的模板引擎,它有如下三个极吸引人的特点: 1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果.这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式.浏览器解释 html 时会忽略未定义的标签属性,所以 t

  • spring-shiro权限控制realm实战教程

    目录 spring-shiro权限控制realm 用户与角色实体 Realm类 Shiro 配置类 控制器 Service shiro权限不生效原因分析 shiro遇到的坑 问题原因:权限标签定义问题 spring-shiro权限控制realm 用户与角色实体 Role.java @Data @Entity public class Role { @Id @GeneratedValue private Integer id; private Long userId; private String

  • 详解springboot shiro jwt实现权限管理

    springboot + shiro + jwt (详情解析+代码实现)加密接口 设置权限 首先需要把shiro的几个配置类给下载好(我已经把需要的配置类给放到了github和网盘之中) 先讲完各个配置类的作用,后面讲具体流程 ShiroConfig.java 类主要是设置了过滤器 和shiro自己的session,假如这个类没有放行就只有token才能访问后端接口 UserRealm.java 类主要是检测用户权限和授予权限,对用户名的验证 JWTFilter.java 类主要是防止别人访问你

  • springboot整合shiro的过程详解

    目录 什么是 Shiro Shiro 架构 Shiro 架构图 Shiro 工作原理 Shiro 详细架构图 springboot 整合 shiro springboot 整合 shiro 思路 项目搭建 主要依赖 数据库表设计 实体类 自定义 Realm shiro 的配置类 ShiroFilterFactoryBean 过滤器链配置中的 url 匹配规则 ShiroFilterFactoryBean 过滤器 ShiroFilterFactoryBean 过滤器分类 前端页面 登录页面 log

  • SpringBoot整合Shiro的代码详解

    shiro是一个权限框架,具体的使用可以查看其官网 http://shiro.apache.org/  它提供了很方便的权限认证和登录的功能. 而springboot作为一个开源框架,必然提供了和shiro整合的功能!接下来就用springboot结合springmvc,mybatis,整合shiro完成对于用户登录的判定和权限的验证. 1.准备数据库表结构 这里主要涉及到五张表:用户表,角色表(用户所拥有的角色),权限表(角色所涉及到的权限),用户-角色表(用户和角色是多对多的),角色-权限表

  • SpringBoot整合Druid数据源过程详解

    这篇文章主要介绍了SpringBoot整合Druid数据源过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.数据库结构 2.项目结构 3.pom.xml文件 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</ar

  • SpringBoot整合Shiro的方法详解

    目录 1.Shito简介 1.1 什么是shiro 1.2 有哪些功能 2.QuickStart 3.SpringBoot中集成 1.导入shiro相关依赖 2.自定义UserRealm 3.定义shiroConfig 4.新建页面进行测试 1.Shito简介 1.1 什么是shiro Apache Shiro是一个java安全(权限)框架 Shiro可以非常容易的开发出足够好的应用,其不仅可以用在javase环境,也可以用在javaee环境 shiro可以完成,认证,授权,加密,会话管理,we

  • SpringBoot整合SpringCloud的过程详解

    目录 1. SpringCloud特点 2. 分布式系统的三个指标CAP 3. Eureka 4. SpringCloud Demo 4.1 registry 4.2 api 4.3 provider 4.4 consumer 4.5 POSTMAN一下 1. SpringCloud特点 SpringCloud专注于为典型的用例和扩展机制提供良好的开箱即用体验,以涵盖其他情况: 分布式/版本化配置 服务注册和发现 Eureka 路由 Zuul 服务到服务的呼叫 负载均衡 Ribbon 断路器 H

  • SpringBoot整合FastDFS方法过程详解

    一.pom.xml <?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

  • SpringBoot整合Swagger2的步骤详解

    简介 swagger是一个流行的API开发框架,这个框架以"开放API声明"(OpenAPI Specification,OAS)为基础, 对整个API的开发周期都提供了相应的解决方案,是一个非常庞大的项目(包括设计.编码和测试,几乎支持所有语言). springfox大致原理: springfox的大致原理就是,在项目启动的过种中,spring上下文在初始化的过程, 框架自动跟据配置加载一些swagger相关的bean到当前的上下文中,并自动扫描系统中可能需要生成api文档那些类,

  • SpringBoot整合rockerMQ消息队列详解

    目录 Springboot整合RockerMQ 使用总结 消费模式 生产者组和消费者组 生产者投递消息的三种方式 如何保证消息不丢失 顺序消息 分布式事务 Springboot整合RockerMQ 1.maven依赖 <dependencies> <!-- springboot-web组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>

  • SpringBoot开发存储服务器实现过程详解

    目录 正文 基础环境 创建项目 添加Rest API接口功能(提供上传服务) 启动服务,测试API接口可用性 增加下载文件支持 文件大小设置 打包文件部署 正文 今天我们尝试Spring Boot整合Angular,并决定建立一个非常简单的Spring Boot微服务,使用Angular作为前端渲编程语言进行前端页面渲染. 基础环境 技术 版本 Java 1.8+ SpringBoot 1.5.x 创建项目 初始化项目 mvn archetype:generate -DgroupId=com.e

  • spring整合Quartz框架过程详解

    这篇文章主要介绍了spring整合Quartz框架过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.Quartz框架简介 Quartz是一个完全由Java编写的开源任务调度的框架,通过触发器设置作业定时运行规则,控制作业的运行时间.其中quartz集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性.主要用来执行定时任务,如:定时发送信息.定时生成报表等等. Quartz框架的主要特点: · 强大的调度功能,例如丰富多样的

随机推荐