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

下面我来详细讲解“Spring Boot在Web应用中基于JdbcRealm安全验证过程”的完整攻略。

什么是JdbcRealm

JdbcRealm是Shiro提供的Realm之一,可以用于将用户、角色、权限等信息保存在关系型数据库中。JdbcRealm通过JDBC连接数据库,实现身份认证和授权。

Spring Boot集成JdbcRealm

在Spring Boot应用中,我们可以通过在pom.xml中引入shiro-spring-boot-start和spring-jdbc包来实现JdbcRealm的集成。

在application.properties文件中,我们需要配置数据库连接信息和Shiro的配置信息,示例如下:

# 数据库连接信息
spring.datasource.url=jdbc:mysql://localhost:3306/shiro_db?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=

# Shiro配置信息
shiro.jdbc.authcSql=select password from user where username=?
shiro.jdbc.rolesSql=select role_name from user_role where username=?
shiro.jdbc.permissionsSql=select permission from role_permission where role_name=?

在上述配置信息中,我们定义了三个SQL语句,分别用于查询用户名对应的密码、查询用户名对应的角色名称以及查询角色名称对应的权限信息。这些SQL语句会在JdbcRealm中被使用。

在Spring Boot应用中,我们需要在配置类中注入JdbcRealm,并配置Shiro的SecurityManager和FilterChain等信息。示例如下:

@Configuration
public class ShiroConfig {
    @Bean
    public JdbcRealm jdbcRealm(DataSource dataSource) {
        JdbcRealm realm = new JdbcRealm();
        realm.setDataSource(dataSource);
        realm.setAuthenticationQuery("select password from user where username=?");
        realm.setUserRolesQuery("select role_name from user_role where username=?");
        realm.setPermissionsQuery("select permission from role_permission where role_name=?");
        return realm;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(JdbcRealm jdbcRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(jdbcRealm);
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        Map<String, String> filterChain = new LinkedHashMap<>();
        filterChain.put("/logout", "logout");
        filterChain.put("/**", "authc");
        shiroFilter.setFilterChainDefinitionMap(filterChain);
        shiroFilter.setLoginUrl("/login");
        return shiroFilter;
    }
}

在上述配置中,我们注入了JdbcRealm,并设置了SecurityManager和FilterChain等信息。filterChain.put("/**", "authc")表示所有资源都需要进行身份认证。shiroFilter.setLoginUrl("/login")设置了defaultFilterChainDefinition中authc对应的默认登陆页面,如果需要进行登陆,会跳转至该页面。

示范性案例1:简单的Web认证

以下展示一个使用JdbcRealm实现简单的Web认证的案例。

我们首先需要创建一个基本的Spring Boot应用,然后引入shiro-spring-boot-start和spring-jdbc包。

在application.properties中设置数据库连接信息和Shiro的配置信息。

在控制层中添加以下代码:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            return "Hello World";
        } else {
            return "请先登陆";
        }
    }

    @GetMapping("/login")
    public String login() {
        return "请先登陆";
    }
}

当请求/hello时,会进行身份认证,如果已经登陆,则返回“Hello World”,否则返回“请先登陆”。

当请求/login时,将显示登陆页面。

接下来,在启动类中添加以下代码:

@SpringBootApplication
@EnableTransactionManagement
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    // 创建一个默认用户,用于初始化数据
    @Bean
    public CommandLineRunner init(UserService userService) {
        return args -> {
            User user = new User();
            user.setUsername("admin");
            user.setPassword("admin");
            userService.createUser(user);
        };
    }
}

在上述代码中,我们通过CommandLineRunner接口创建一个默认用户,用于初始化数据。这里我们使用了UserService服务,用于将用户添加到数据库中。

接下来,我们创建UserService服务实现类:

@Service
@Transactional
public class UserServiceImpl implements UserService {
    private final UserDao userDao;

    @Autowired
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void createUser(User user) {
        userDao.createUser(user);
    }

    @Override
    public User getUserByUsername(String username) {
        return userDao.getUserByUsername(username);
    }
}

在上述代码中,我们注入了UserDao,用于将用户数据存入数据库中。

最后,我们创建UserDao实现类:

@Repository
public class UserDaoImpl implements UserDao {
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public UserDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void createUser(User user) {
        String sql = "insert into user(username,password) values(?,?)";
        jdbcTemplate.update(sql, user.getUsername(), user.getPassword());
    }

    @Override
    public User getUserByUsername(String username) {
        String sql = "select password from user where username=?";
        RowMapper<User> rowMapper = (resultSet, i) -> {
            User user = new User();
            user.setUsername(username);
            user.setPassword(resultSet.getString("password"));
            return user;
        };
        List<User> userList = jdbcTemplate.query(sql, rowMapper, username);
        if (userList.isEmpty()) {
            return null;
        } else {
            return userList.get(0);
        }
    }
}

在上述代码中,我们使用JdbcTemplate实现了UserDao接口,并提供了添加用户和查询用户数据的方法。

了解了上述代码后,我们启动应用,访问 http://localhost:8080/hello ,会自动跳转至登陆页面,此时输入用户名和密码(由于上面的初始化脚本,这里我们可以使用默认的用户名“admin”和密码“admin”),登陆成功后就可以看到“Hello World”了。

示范性案例2:使用Shiro注解实现授权

以下展示一个使用Shiro注解实现授权的案例。

我们首先需要创建一个基本的Spring Boot应用,然后引入shiro-spring-boot-start和spring-jdbc包。

在application.properties中设置数据库连接信息和Shiro的配置信息。

在控制层中添加以下代码:

@RestController
public class HelloController {
    @GetMapping("/hello")
    @RequiresRoles("admin")
    public String hello() {
        return "Hello World";
    }

    @GetMapping("/login")
    public String login() {
        return "请先登陆";
    }
}

在上述代码中,我们使用@RequiresRoles注解表示需要admin角色才能访问该接口。

接下来,在启动类中添加以下代码:

@SpringBootApplication
@EnableTransactionManagement
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    // 创建一个默认用户,用于初始化数据
    @Bean
    public CommandLineRunner init(UserService userService) {
        return args -> {
            User user = new User();
            user.setUsername("admin");
            user.setPassword("admin");
            userService.createUser(user);
            UserRole userRole = new UserRole(user.getUsername(), "admin");
            userService.createUserRole(userRole);
        };
    }
}

在上述代码中,我们使用了UserService中的createUserRole方法,用于将用户添加到角色中。

接下来,我们做一些修改,在ShiroConfig中注入自定义的Relam,并设置FilterChain等信息:

@Configuration
public class ShiroConfig {
    private final ApplicationContext ac;

    @Autowired
    public ShiroConfig(ApplicationContext ac) {
        this.ac = ac;
    }

    @Bean
    public JdbcRealm jdbcRealm(DataSource dataSource) {
        JdbcRealm realm = new JdbcRealm();
        realm.setDataSource(dataSource);
        realm.setAuthenticationQuery("select password from user where username=?");
        realm.setUserRolesQuery("select role_name from user_role where username=?");
        realm.setPermissionsQuery("select permission from role_permission where role_name=?");
        return realm;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(JdbcRealm jdbcRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(jdbcRealm);
        return securityManager;
    }

    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        return new DefaultAdvisorAutoProxyCreator();
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        advisor.setAdvice(new AopAllianceAnnotationsAuthorizingMethodInterceptor());
        return advisor;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        Map<String, String> filterChain = new LinkedHashMap<>();
        filterChain.put("/logout", "logout");
        filterChain.put("/login", "anon");
        filterChain.put("/**", "authc");
        shiroFilter.setFilterChainDefinitionMap(filterChain);
        shiroFilter.setLoginUrl("/login");
        return shiroFilter;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }

    @Bean
    public AnnotationMethodInvocationCachingInterceptor annotationMethodInvocationCachingInterceptor() {
        return new AnnotationMethodInvocationCachingInterceptor();
    }
}

在上述代码中,我们使用了Shiro注解实现授权,将其注入到Spring容器中。

我们需要添加UserRol实体类,并创建UserRoleDao接口和实现类如下:

public interface UserRoleDao {
    int createUserRole(UserRole userRole);
}

@Repository
public class UserRoleDaoImpl implements UserRoleDao {
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public UserRoleDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public int createUserRole(UserRole userRole) {
        String sql = "insert into user_role(username, role_name) values(?,?)";
        return jdbcTemplate.update(sql, userRole.getUsername(), userRole.getRoleName());
    }
}

在上述代码中,我们使用JdbcTemplate实现了UserRoleDao接口,提供了添加用户角色的方法。

了解了上述代码后,我们启动应用,访问 http://localhost:8080/hello ,会自动跳转至登陆页面,此时输入用户名和密码(由于上面的初始化脚本,这里我们可以使用默认的用户名“admin”和密码“admin”),登陆成功后就可以看到“Hello World”了。

这里需要注意,由于我们设置了UserRoleDao实现类的@Transactional注解,所以添加角色时必须提交事务,否则会报JdbcTemplate未绑定到线程的错误。

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

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • JVM调优的方法有哪些?

    JVM调优是保障应用性能的重中之重。它可以通过不同的方法来优化JVM,提升应用的性能。下面是JVM调优的方法。 JVM调优方法 优化JVM的参数设置 JVM的性能与调优参数密不可分。参数的设置可以通过启动时传递参数、修改配置文件、通过代码调用等方式。常用的参数设置包括: -Xms和-Xmx: 设置Java堆的最小和最大值 -XX:MaxPermSize: 设…

    Java 2023年5月10日
    00
  • 解决dubbo错误ip及ip乱入问题的方法

    解决dubbo错误ip及ip乱入问题的方法 在使用dubbo进行微服务开发时,可能会出现一些ip相关的问题,如服务提供者使用了错误的ip地址进行暴露,或者消费者调用时使用了错误的ip地址等等。这些问题会导致服务无法正常运行。本攻略将介绍如何解决dubbo错误ip及ip乱入问题。 Dubbo服务提供者使用了错误的ip地址进行暴露 在dubbo的服务提供者端,可…

    Java 2023年6月2日
    00
  • 分析SpringBoot的启动原理

    下面我会详细地讲解分析Spring Boot启动原理的攻略,内容如下。 什么是Spring Boot Spring Boot 是一个基于Spring Framework构建的用于快速构建Web应用程序和微服务的开源框架。 Spring Boot的主要目的是简化Spring的配置和开发过程。Spring Boot集成了Spring框架,内嵌了Tomcat、Je…

    Java 2023年5月15日
    00
  • Mybatis的Dao层实现原理分析

    接下来我将详细讲解Mybatis的Dao层实现原理分析的完整攻略。 什么是Dao层 Dao层是指数据访问层,它负责与数据库进行交互,完成数据的增、删、改、查等操作。在Dao层中,最常用的是SQL语句。Mybatis是一种主流的持久层框架,它的Dao层实现原理值得深入学习。 Mybatis的Dao层实现原理 1. 配置文件 Mybatis框架使用XML文件来配…

    Java 2023年5月20日
    00
  • C#中的9个“黑魔法”

    下面是详细讲解 “C#中的9个“黑魔法””: 1. Reflector Reflector 是一款第三方反编译工具,它能够将 .NET 程序编译后的程序集反编译成 C# 代码、IL 代码等多种格式,不仅可以加深我们对代码的理解,还可以帮助我们阅读和调试第三方代码。对于 C# 程序员来说,Reflector 可谓是必备工具之一。 举个例子,如下是一个由 .NE…

    Java 2023年5月31日
    00
  • SpringBoot快速通关自动配置应用

    Spring Boot快速通关自动配置应用攻略 1. 简介 Spring Boot 为 Java 程序开发提供了快速构建基于 Spring 框架的应用程序的便捷方式。使用 Spring Boot,开发人员可以快速开发出可运行的、独立的应用程序,而无需维护一组繁琐的配置文件和依赖项。 本文将介绍使用 Spring Boot 进行自动配置的基础知识和攻略。 2.…

    Java 2023年5月15日
    00
  • JSP中param标签用法实例分析

    即将为您讲解JSP中param标签的用法。 什么是param标签 param标签是JSP中一个自定义标签,用于向一个JSP标记库动态传递参数。该标签必须被包含在定义了该库的标记文件中,以便在库的使用者中提供一些参数化的功能。 param标签的使用方法 下面是param标签的通用语法: <jsp:param [name="parameter_n…

    Java 2023年6月15日
    00
  • Java基于Calendar类输出指定年份和月份的日历代码实例

    Java基于Calendar类输出指定年份和月份的日历代码实例如下: import java.util.*; public class CalendarExample { public static void main(String[] args) { // 声明并获取Calendar对象 Calendar calendar = Calendar.getIn…

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