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日

相关文章

  • Sprint Boot @Cacheable使用方法详解

    Spring Boot的@Cacheable注解 在Spring Boot中,@Cacheable注解用于启用缓存支持。使用@Cacheable注解可以将方法的返回值缓存起来,并在下一次调用该方法时直接返回缓存的结果,而不是再次执行该方法。本文将详细介绍@Cacheable注解的作用和使用方法,并提供两个示例说明。 @Cacheable注解作用 在Sprin…

    Java 2023年5月5日
    00
  • java使用OGEngine开发2048

    让我来为您详细讲解如何使用OGEngine开发2048游戏。 准备工作 在开发2048游戏之前,我们需要先准备好开发环境以及相关工具。以下是准备工作的步骤: 下载并安装JDK(Java Development Kit),确保安装的JDK版本高于1.8。 下载并安装Eclipse IDE(Integrated Development Environment),…

    Java 2023年6月15日
    00
  • 微信小程序微信登录的实现方法详解(JAVA后台)

    下面是详细的攻略: 背景介绍 微信小程序微信登录是指用户可以通过微信账号快速登录小程序,无需再次注册账号。实现微信登录的关键在于后台服务器实现微信的登录认证功能。本文将详细讲解如何在Java后台实现微信登录的功能。 实现方法 实现微信登录功能的具体步骤如下: 1.前端页面添加微信登录按钮 <button type="primary"…

    Java 2023年5月23日
    00
  • Spring MVC整合 freemarker及使用方法

    Spring MVC是一款非常流行的MVC框架,而Freemarker是一款优秀的模板引擎,两者的整合可以使得我们在Web开发中处理模板更加高效、简便。以下是Spring MVC整合Freemarker的攻略及使用方法。 引入依赖 在pom文件中引入freemarker和spring-webmvc依赖: <dependency> <grou…

    Java 2023年5月20日
    00
  • SpringBoot如何实现Tomcat自动配置

    Spring Boot 是一个基于 Spring 的开源应用框架,它可以快速搭建大规模、高性能的 Web 应用。Spring Boot 的最大特点就是自动配置,这也是 Spring Boot 的核心功能之一。它可以自动将 Web 容器嵌入到应用中。Tomcat 是个著名的 Web 容器,Spring Boot 如何实现 Tomcat 的自动配置呢? Spri…

    Java 2023年5月19日
    00
  • Spring Boot 日志配置方法(超详细)

    Spring Boot日志配置方法(超详细) Spring Boot是一个非常流行的Java开发框架,它提供了多种日志框架,包括Logback、Log4j2、Java Util Logging等。本文将详细介绍Spring Boot日志配置方法,包括配置文件、注解、代码等。 1. 配置文件 Spring Boot的日志配置文件是application.pro…

    Java 2023年5月14日
    00
  • Apache POI将PPT转换成图片实例代码

    下面就来详细讲解“Apache POI将PPT转换成图片实例代码”的完整攻略。 简介 Apache POI是一个开源的Java库,用于处理Microsoft Office文档格式,如PPT、XLS和DOC等格式。本文将针对PPT格式文件,介绍如何使用Apache POI将PPT转换成图片。 准备工作 在使用Apache POI之前,首先需要进行一些准备工作。…

    Java 2023年5月20日
    00
  • 详解SpringMVC中的四种跳转方式、视图解析器问题

    以下是关于“详解SpringMVC中的四种跳转方式、视图解析器问题”的完整攻略,其中包含两个示例。 SpringMVC中的四种跳转方式 SpringMVC中有四种跳转方式,分别是: forward redirect internalRedirect sendRedirect 1. forward forward是一种服务器内部跳转方式,它将请求转发给另一个控…

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