SpringBoot集成shiro认证,实现Shiro认证的登录操作

简介: SpringBoot集成shiro认证,实现Shiro认证的登录操作

什么是Shiro权限管理?

Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相 当简单,对比

Spring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时

可能并不需要那么复杂的东西,所以使用小而简单的 Shiro 就足够了。对于它俩到底哪个 好,这个不必纠结,能更简单的解决项目问题就好了。


权限管理分为认证和授权

认证

认证的基本概念

身份认证:校验用户是不是系统合法用户的过程(比如登录操作)


身份认证,就是判断一个用户是否为合法用户的处理过程。


最常用的简单身份认证方式是系统通过核对用户输入的用户名和密码,看其是否与系统中存储的该用户的用户名和密码是否一致,来判断用户身份是否正确。


对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡。通过二维码等等都是认证的过程


认证基本的对象

Subject 主体

官方给出的解释是这样的:

Without question, the most important concept in Apache Shiro is the Subject. ‘Subject’ is just a security term that means a security-specific ‘view’ of an application user. A Shiro Subject instance represents both security state and operations for a single application user.

翻译过来就是:

毫无疑问,shiro中最重要的概念就是subject(主体)。subject是一个虚拟的用户对象(就是相当于我们之前的User Admin对象等)。

使用Subject的之后的流程变化

其实,

Subject可以认为就是Admin User这些类

另外subject中还有两个重要概念:

Credential 凭证信息 就是密码的意思

Principal 身份信息 就是账号的意思

扩展阅读:(看一下官方的解释为什么叫Subject而不叫User)


We originally wanted to call it ‘User’ since that “just makes sense”, but we decided against it: too many applications have existing APIs that already have their own User classes/frameworks, and we didn’t want to conflict with those. Also, in the security world, the term ‘Subject’ is actually the recognized nomenclature.

翻译如下:

我们最初是想把它叫做User的,这样很容易理解,但是大部分的应用程序都已经有了User类,为了不和这些原有的api发生冲突,我们最后决定不这么做。


认证的登录操作案例:SpringBoot集成shiro

下面开始使用Shiro实现带认证的登录操作

导入依赖
<!--shiro相关依赖-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.3.2</version>
</dependency>
第一个demo

基本思路

用户输入的账号密码 和 数据库中存储的账号密码 比对

注意:shiro 默认不支持连接数据库 默认通过配置文件获取数据

所以我们要重写Realm中的方法,实现对数据库的连接

  1. 接收用户输入的账号密码,
  2. 要重写Realm中的方法,实现对数据库的连接和数据获取
  3. 写Springboot的配置类,创建并将重写的Realm设置放进去安全管理器, 将安全管理器 和Subject建立联系
  4. 将用户输入的账号密码给Subject
  5. 调用Subject的login方法完成登录

代码实现流程

重写Realm的代码
package com.macw.realm;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.macw.entity.Admin;
import com.macw.mapper.AdminMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
/**
 * @author maCw
 * @version 1.0
 * @date 2019/8/22 16:13
 */
public class MyRealm extends AuthenticatingRealm {
    @Resource
    private AdminMapper adminMapper;
    /**
     * 记录日志
     */
    Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1,获取令牌中的数据,账号
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        //2,通过账号查询获取数据库中对应的账号信息
        Admin admin = adminMapper.selectOne(new QueryWrapper<Admin>().eq("username", username));
        logger.info("---"+admin);
        Subject subject = SecurityUtils.getSubject();
        //将查询的对象放进去subject自带的session中去
        subject.getSession().setAttribute("admins", admin);
        //如果有数据,对象为非null,说明查询到了数据,封装account返回
        if (admin != null){
            SimpleAccount simpleAccount = new SimpleAccount(admin.getUsername(), admin.getPassword(), this.getName());
            return simpleAccount;
        }else {
            //如果对象为空,return null就会抛出账户不存在异常
            return null;
        }
    }
}
在SpringBoot中配置shiro
package com.macw.config;
import com.macw.realm.MyRealm;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.config.WebIniSecurityManagerFactory;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
 * @Configuration 标记当前类为配置类  相当于spring.xml
 */
@Configuration
public class ShiroConfig {
    /**
     * @Bean 声明创建对象  并把对象放在工厂中  相当于bean标签
     * 如果形参类型对应的对象在工厂中有  会自动装配上
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultSecurityManager defaultSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        /**
         * 过滤器链 过滤拦截规则 哪些页面拦截  哪些页面不拦截
         */
        Map map = new HashMap();
        /**
         * anon 代表匿名可访问 就是不用登录就可以访问  登录页面  登录的url
         * authc 认证可访问 代表登录后才能访问
         *
         * 支持通配符*
         * 注意拦截规则 一个一个配置
         */
        map.put("/login.jsp","anon");
        map.put("/login/*","anon");
        map.put("/main/*", "authc");
        map.put("/guru/*", "authc");
        map.put("/menu/*", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        /**
         * 设置安全管理器,将创建的安全管理器放进shiroFilterFactoryBean过滤工厂里面
         */
        shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);
        return shiroFilterFactoryBean;
    }
    /**
     * 创建安全管理器,并将自定义的Realm放进去管理器
     * @return
     */
    @Bean
    public DefaultSecurityManager getDefaultSecurityManager(MyRealm myRealm){
        DefaultSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
//        需要赋值一个Realm
        defaultSecurityManager.setRealm(myRealm);
        return defaultSecurityManager;
    }
    /**
     * 创建自定义的Realm
     */
    @Bean
    public MyRealm getMyRealm(){
        return new MyRealm();
    }
}

如果引用到其他项目的话这里需要修改的是 拦截规则 和 自定义的Realm

修改原来的登录方法

在控制器里的登录方法中修改:

    /**
     * 使用shiro登录
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("adminLogin")
    public String adminLogin(String username,String password){
//        1.将用户输入的账号密码 封装在token中
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//        2.获取Subject
        Subject subject = SecurityUtils.getSubject();
//        3.通过Subject 的login方法 完成登录
        try {
            subject.login(token);
            //到这里如果没有异常说明登录成功,
            return "redirect:/main/main.jsp";
        }catch (Exception e){
            //有异常说明登录失败,重定向到登录页面
            return "redirect:/login.jsp";
        }
    }
shiro中Session的使用

方案1:HttpSession

方案2:shiro中的session

Session session1 = SecurityUtils.getSubject().getSession();

注意:方案1 和 方案2 都可以 使用 但是只能使用一种方案 不要混合使用

登录认证总结

认证:登录,身份认证,校验用户是不是系统合法用户的过程

主体Subject:就是Admin,User这些类,但是和之前自己定义的User Admin稍以后区别,Subject不仅封装用户和认证相关的数据(账号密码),还封装了和认证相关的方法(login方法)


Credential 凭证信息 就是密码的意思


Principal 身份信息 就是账号的意思


重写Realm中的方法

为什么要重写Realm中的方法


默认不支持连接数据库 默认的实现是查询配置文件


解决方案


shiro默认的doGetAuthenticationInfo方法是查询配置文件,由于这个方法是父类的一个抽象方法,通过继承和多态,可以继承父类,覆盖这个方法(在方法中写入我们新的方法实现 连接数据库 查询数据库中的账号信息)


集成项目的基本流程

  1. 写shiro的配置类(创建对象)
    注意:拦截规则 和 自定义的Realm 需要根据自己项目的情况调整
  2. 修改原来的登录方法
目录
相关文章
|
23天前
|
XML Java API
Spring Boot集成MinIO
本文介绍了如何在Spring Boot项目中集成MinIO,一个高性能的分布式对象存储服务。主要步骤包括:引入MinIO依赖、配置MinIO属性、创建MinIO配置类和服务类、使用服务类实现文件上传和下载功能,以及运行应用进行测试。通过这些步骤,可以轻松地在项目中使用MinIO的对象存储功能。
|
25天前
|
消息中间件 Java Kafka
什么是Apache Kafka?如何将其与Spring Boot集成?
什么是Apache Kafka?如何将其与Spring Boot集成?
62 5
|
25天前
|
安全 Java 数据安全/隐私保护
如何使用Spring Boot进行表单登录身份验证:从基础到实践
如何使用Spring Boot进行表单登录身份验证:从基础到实践
41 5
|
1月前
|
JSON 安全 算法
Spring Boot 应用如何实现 JWT 认证?
Spring Boot 应用如何实现 JWT 认证?
71 8
|
28天前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
43 1
|
1月前
|
XML Java 数据库连接
SpringBoot集成Flowable:打造强大的工作流管理系统
在企业级应用开发中,工作流管理是一个核心组件,它能够帮助我们定义、执行和管理业务流程。Flowable是一个开源的工作流和业务流程管理(BPM)平台,它提供了强大的工作流引擎和建模工具。结合SpringBoot,我们可以快速构建一个高效、灵活的工作流管理系统。本文将探讨如何将Flowable集成到SpringBoot应用中,并展示其强大的功能。
229 1
|
28天前
|
消息中间件 监控 Java
您是否已集成 Spring Boot 与 ActiveMQ?
您是否已集成 Spring Boot 与 ActiveMQ?
52 0
|
1月前
|
JSON Java API
springboot集成ElasticSearch使用completion实现补全功能
springboot集成ElasticSearch使用completion实现补全功能
42 1
|
2月前
|
人工智能 JavaScript 网络安全
ToB项目身份认证AD集成(三完):利用ldap.js实现与windows AD对接实现用户搜索、认证、密码修改等功能 - 以及针对中文转义问题的补丁方法
本文详细介绍了如何使用 `ldapjs` 库在 Node.js 中实现与 Windows AD 的交互,包括用户搜索、身份验证、密码修改和重置等功能。通过创建 `LdapService` 类,提供了与 AD 服务器通信的完整解决方案,同时解决了中文字段在 LDAP 操作中被转义的问题。
|
1月前
|
XML 存储 Java
SpringBoot集成Flowable:构建强大的工作流引擎
在企业级应用开发中,工作流管理是核心功能之一。Flowable是一个开源的工作流引擎,它提供了BPMN 2.0规范的实现,并且与SpringBoot框架完美集成。本文将探讨如何使用SpringBoot和Flowable构建一个强大的工作流引擎,并分享一些实践技巧。
155 0