Spring Boot在Web应用中基于JdbcRealm安全验证过程

关于Spring Boot在Web应用中基于JdbcRealm安全验证的完整攻略,可以分为以下几个部分:

  1. 依赖配置
    在项目的pom.xml文件中添加Shiro和JDBC驱动的依赖:
<dependencies>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
    </dependency>
</dependencies>
  1. Shiro配置
    Shiro通过Ini配置文件或者编程方式来进行配置,这里我们选择编程方式。实现ShiroConfig类,在里面配置需要的对象,例如Realm、SecurityManager等。具体代码如下:
@Configuration
public class ShiroConfig {

    /**
     * 自定义Realm实现
     */
    @Bean
    public JdbcRealm jdbcRealm() {
        JdbcRealm jdbcRealm = new JdbcRealm();
        jdbcRealm.setDataSource(dataSource());  // 设置数据源
        jdbcRealm.setAuthenticationQuery("SELECT password FROM users WHERE username = ?");  // 查询用户密码
        jdbcRealm.setUserRolesQuery("SELECT r.role_name FROM user_role ur, roles r WHERE ur.user_id = (SELECT id FROM users WHERE username = ?) AND ur.role_id = r.id");  // 查询用户角色
        jdbcRealm.setPermissionsQuery("SELECT p.permission_name FROM roles_permissions rp, permissions p WHERE rp.permission_id = p.id AND rp.role_id = (SELECT id FROM roles WHERE role_name = ?)");  // 查询角色权限
        jdbcRealm.setCredentialsMatcher(hashedCredentialsMatcher());  // 设置密码校验器
        return jdbcRealm;
    }

    /**
     * 配置SecurityManager
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        securityManager.setRealm(jdbcRealm());
        return securityManager;
    }

    /**
     * 密码校验器
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("MD5");  // MD5加密
        matcher.setHashIterations(1);  // 迭代次数
        return matcher;
    }

    /**
     * 数据源配置
     */
    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        return dataSource;
    }

    /**
     * 配置Shiro过滤器
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        shiroFilterFactoryBean.setLoginUrl("/login");  // 设置登录页面
        shiroFilterFactoryBean.setSuccessUrl("/index");  // 设置登录成功跳转页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");  // 设置未授权页面
        // 配置过滤器链
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/static/**", "anon");  // 静态资源不拦截
        filterChainDefinitionMap.put("/logout", "logout");  // 登出
        filterChainDefinitionMap.put("/login", "anon");  // 登录页面不拦截
        filterChainDefinitionMap.put("/**", "authc");  // 其他页面需要认证
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

}
  1. 编写登录页面
    在登录页面,需要提交用户名和密码,具体代码如下:
<form method="post" action="/login">
    <label>用户名:</label>
    <input type="text" name="username"/>
    <br/>
    <label>密码:</label>
    <input type="password" name="password"/>
    <br/>
    <input type="submit" value="登录"/>
</form>
  1. 编写控制器
    在控制器中,需要实现登录、登出等操作,具体代码如下:
@Controller
public class UserController {

    /**
     * 跳转到登录页面
     */
    @GetMapping("/login")
    public String login() {
        return "login";
    }

    /**
     * 登录
     */
    @PostMapping("/login")
    public String doLogin(String username, String password) {
        // 创建UsernamePasswordToken
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        // 获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        try {
            // 进行登录
            subject.login(token);
            return "redirect:/index";
        } catch (AuthenticationException e) {
            // 登录失败
            return "login";
        }
    }

    /**
     * 登出
     */
    @GetMapping("/logout")
    public String logout() {
        // 获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        // 登出
        subject.logout();
        return "redirect:/login";
    }

    /**
     * 首页
     */
    @GetMapping("/index")
    public String index() {
        return "index";
    }

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

}
  1. 配置示例
    我们可以通过在数据库中添加用户表、角色表、权限表,来实现基于JdbcRealm的安全验证。例如在用户表中添加了一条记录:
INSERT INTO users(id, username, password) VALUES(1, 'test', '098f6bcd4621d373cade4e832627b4f6');

其中密码使用了MD5对123456进行了加密。

我们还可以在角色表中添加一个admin角色,在用户角色表中为test用户添加了admin角色。在权限表中为admin角色添加了一个/test的权限。

这样,在访问/test页面时,需要用户进行登录,才能够访问。如果用户没有admin角色的权限,将会跳转到未授权页面。

通过以上步骤,我们就可以实现基于JdbcRealm的安全验证过程。

示例代码请参考:https://github.com/gaohan0719/shiro-jdbc-demo

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot在Web应用中基于JdbcRealm安全验证过程 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • layui+jquery支持IE8的表格分页方法

    下面为您详细讲解“layui+jquery支持IE8的表格分页方法”的完整攻略。 简介 Layui是一款轻量级的前端UI框架,兼容性良好,但官方仅支持IE10以上版本。有时候我们需要兼容低版本的IE浏览器,本文就是讲解使用layui+jquery实现支持IE8的表格分页方法。 准备工作 引入Layui和jquery库; 定义表格结构,设置表头等; 引入分页组…

    Java 2023年6月15日
    00
  • 详解java如何正确使用volatile

    如何正确使用volatile 什么是volatile 在Java中,volatile是一种非常特殊的关键字。它用来表示一个变量是易变的,即它可能由于线程间的可见性导致不同线程读到不同的值。当我们声明一个变量为volatile时,Java会保证这个变量的内存可见性和线程安全性。 为什么使用volatile 因为当多个线程访问共享状态时,可能会出现一些意料不到的…

    Java 2023年5月26日
    00
  • Java Apache Commons报错“URISyntaxException”的原因与解决方法

    “ControllerResourcesNotFoundException”是Java的Struts框架中的一个异常,通常由以下原因之一引起: 配置错误:如果配置文件中存在错误,则可能会出现此异常。例如,可能会使用错误的文件路径或文件名。 资源文件缺失:如果资源文件缺失,则可能会出现此异常。例如,可能会缺失struts.xml文件。 以下是两个实例: 例1 …

    Java 2023年5月5日
    00
  • Java利用future及时获取多线程运行结果

    下面是Java利用Future及时获取多线程运行结果的完整攻略: 1. Future概述 Future是一种多线程编程模型,在Java5中引入,主要用于解决由于异步执行任务而导致的程序阻塞问题。通过Future,可以异步执行任务的同时,获取该任务执行的结果。 在Java中,Future是通过Future接口实现的。Future接口定义了获取异步计算结果的方法…

    Java 2023年5月18日
    00
  • 如何使用Java安全管理框架?

    如何使用Java安全管理框架? Java安全管理框架是Java平台提供的一个安全机制,通过使用Java安全管理框架,开发者可以实现对Java应用程序的安全控制。 安装Java安全管理框架 Java安全管理框架已经集成到JDK中,无需另行安装。 配置Java安全管理策略文件 Java安全管理框架通过配置Java安全管理策略文件来实现安全控制。Java安全管理策…

    Java 2023年5月11日
    00
  • C#桥接模式完整实例

    C#桥接模式是一种软件设计模式,旨在将抽象和实现分离开来,以便它们可以独立地进行变化和演化。在此模式下,一个抽象类在其内部维护一个实现类的引用,并将具体的实现委托给实现类。这样便可以在不改变抽象类结构的情况下,改变具体实现类。 下面我们采用一个“图形和颜色”系统作为示例,在这个系统中,“图形”和“颜色”是两个独立的概念,它们可以独立从抽象和实现上进行扩展,并…

    Java 2023年5月19日
    00
  • Intellij IDEA 与maven 版本不符 Unable to import maven project See logs for details: No implementation for org.apache.maven.model.path.PathTranslator was bound

    这个错误提示通常是由于Intellij IDEA和Maven版本不匹配导致的。以下是一些解决此问题的攻略: 1. 通过设置maven home目录解决 请先确定你正在使用的Intellij IDEA是否与Maven版本兼容。在Intellij IDEA的Maven设置中,设置正确的Maven home目录。如果Maven home目录没有设置正确,会导致In…

    Java 2023年5月20日
    00
  • 详解Spring MVC CORS 跨域

    详解Spring MVC CORS 跨域 CORS(Cross-Origin Resource Sharing)是一种Web浏览器的安全机制,用于限制跨域请求。在Spring MVC中,我们可以使用@CrossOrigin注解来处理CORS跨域请求。 @CrossOrigin注解 @CrossOrigin注解是Spring MVC提供的一个注解,它可以用来处…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部