当前位置:   article > 正文

springboot+mybatis+sucurity_loaduserbyusername的用户查询service mapper xml实现

loaduserbyusername的用户查询service mapper xml实现

Mybatis Plus 是一个非常流行的 ORM 框架,可以帮助我们在 Spring 中更方便地访问数据库。在配合 Spring Security 使用时,我们可以使用 Mybatis Plus 来定义数据访问层(DAO),使用 Spring Boot 的自动配置功能来配置 Mybatis Plus 和 Spring Security,从而实现用户认证和授权的功能。

下面是一个使用 Mybatis Plus 和 Spring Security 的示例:

1.创建用户表

首先,我们需要在数据库中创建用户表,作为存储用户信息和凭证的表。在本例中,我们创建一个名为 sys_user 的表,包含了用户 ID、用户名、密码和是否启用等字段。

  1. CREATE TABLE `sys_user` (
  2. `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  3. `username` varchar(50) NOT NULL COMMENT '用户名',
  4. `password` varchar(100) NOT NULL COMMENT '密码',
  5. `enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用:0-禁用,1-启用',
  6. PRIMARY KEY (`id`),
  7. UNIQUE KEY `idx_username` (`username`) USING BTREE
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息表';

2.添加 Mybatis Plus 和 Spring Security 的依赖

在 Maven 中添加 Mybatis Plus 和 Spring Security 的依赖:

  1. <!-- pom.xml -->
  2. <dependency>
  3. <groupId>com.baomidou</groupId>
  4. <artifactId>mybatis-plus-boot-starter</artifactId>
  5. <version>3.4.2</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-security</artifactId>
  10. <version>2.5.2</version>
  11. </dependency>

3.配置 Mybatis Plus 和 Spring Security

在 Spring Boot 的配置文件中,添加如下配置:

  1. # application.yml
  2. server:
  3. port: 8080
  4. spring:
  5. datasource:
  6. url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useSSL=false
  7. username: root
  8. password: root
  9. driver-class-name: com.mysql.cj.jdbc.Driver
  10. security:
  11. user:
  12. name: admin
  13. password: password
  14. mvc:
  15. # 去掉默认的 favicon.ico
  16. favicon:
  17. enabled: false
  18. mybatis-plus:
  19. configuration:
  20. # 开启驼峰命名规则,即支持Java的驼峰命名法。
  21. map-underscore-to-camel-case: true
  22. # 扫描 Mapper 接口,注意:这里需要换成自己 DTO 的包。
  23. mapper-locations: classpath*:/mapper/**Mapper.xml

在上述代码中,我们配置了数据源、Spring Security 的用户信息(用于登录验证)、Mybatis Plus 的配置和 Mapper 接口的扫描位置。需要注意的是,这里的 mapper-locations 是 Mapper XML 文件的位置,需要根据实际情况进行配置。

4.定义 Mapper 接口

在 Mybatis Plus 中,可以使用 Mapper 接口来访问数据库。首先,需要定义一个用于表示用户信息的 DTO 类,例如:

  1. @Data
  2. public class UserDTO implements UserDetails {
  3. private Long id;
  4. private String username;
  5. private String password;
  6. private Boolean enabled;
  7. @Override
  8. public Collection<? extends GrantedAuthority> getAuthorities() {
  9. return AuthorityUtils.NO_AUTHORITIES;
  10. }
  11. @Override
  12. public boolean isAccountNonExpired() {
  13. return true;
  14. }
  15. @Override
  16. public boolean isAccountNonLocked() {
  17. return true;
  18. }
  19. @Override
  20. public boolean isCredentialsNonExpired() {
  21. return true;
  22. }
  23. @Override
  24. public boolean isEnabled() {
  25. return enabled == null || enabled;
  26. }
  27. }

然后,定义一个 Mapper 接口来访问 sys_user 表,例如:

  1. @Mapper
  2. public interface UserMapper extends BaseMapper<UserDTO> {
  3. /**
  4. * 根据用户名获取用户信息
  5. *
  6. * @param username 用户名
  7. * @return 用户信息
  8. */
  9. UserDTO findByUsername(String username);
  10. }

这里使用了 Mybatis Plus 的 BaseMapper 泛型接口来继承了基本的增、删、改、查操作,并且定义了一个新的方法来根据用户名获取用户信息。其中,@Mapper 注解表示该接口是一个 Mybatis Mapper 接口,由 Mybatis 解析并生成相应的实现类。

5.定义 Service

通过定义 DAO,我们现在已经能够使用 Mybatis Plus 来访问数据库,接下来需要定义 Service 层来对 DAO 层进行封装,提供给 Controller 层调用。例如,我们定义一个名为 UserServiceImpl 的 Service 实现类:

  1. @Service
  2. public class UserServiceImpl implements UserDetailsService {
  3. @Autowired
  4. private UserMapper userMapper;
  5. @Override
  6. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  7. UserDTO user = userMapper.findByUsername(username);
  8. if (user == null) {
  9. throw new UsernameNotFoundException("No matching user found for " + username);
  10. }
  11. return user;
  12. }
  13. }

在代码中,我们通过 @Autowired 注解将 

UserMapper注入到UserServiceImpl中,并实现了UserDetailsService接口的loadUserByUsername()` 方法,根据用户名查询用户信息并返回给 Spring Security 使用。

6.配置 Spring Security

最后,需要配置 Spring Security,使用上述 Service 实现类来进行用户认证和授权。在 Spring Boot 的配置文件中添加如下配置:

  1. @Configuration
  2. @EnableWebSecurity
  3. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  4. @Autowired
  5. private UserDetailsService userDetailsService;
  6. @Override
  7. protected void configure(HttpSecurity http) throws Exception {
  8. http.authorizeRequests()
  9. .antMatchers("/login").permitAll()
  10. .anyRequest().authenticated()
  11. .and()
  12. .formLogin()
  13. .loginPage("/login")
  14. .permitAll()
  15. .and()
  16. .logout()
  17. .permitAll();
  18. }
  19. @Autowired
  20. public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
  21. auth.userDetailsService(userDetailsService);
  22. }
  23. }

在上述代码中,我们定义了一个 WebSecurityConfig 配置类,并继承自 WebSecurityConfigurerAdapter,用于配置 Spring Security。在 configure(HttpSecurity) 方法中,我们定义了登录页面、授权规则和登录方式。在 configureGlobal(AuthenticationManagerBuilder) 方法中,我们将上述 Service 实现类注入到 AuthenticationManagerBuilder 中,使其能够在登录时调用该 Service 实现类进行认证操作。

现在,当用户在登录页面中输入用户名和密码时,Spring Security 就会自动调用上述 Service 实现类来进行用户认证。如果认证成功,用户就能够访问被授权的资源。如果认证失败,则会抛出相应的异常,例如 UsernameNotFoundExceptionBadCredentialsException 等。

以下是一个使用 Mybatis Plus、Spring Security 和 Controller 的实例:

1.定义 Controller

定义一个 UserController 类来作为 Spring Boot 的 Web 接口,例如:

  1. @RestController
  2. @RequestMapping("/api/users")
  3. public class UserController {
  4. @Autowired
  5. private UserService userService;
  6. @GetMapping("/")
  7. public List<UserDTO> findAll() {
  8. return userService.list();
  9. }
  10. @GetMapping("/{id}")
  11. public UserDTO findById(@PathVariable Long id) {
  12. return userService.getById(id);
  13. }
  14. @PostMapping("/")
  15. public UserDTO create(@RequestBody UserDTO user) {
  16. userService.save(user);
  17. return user;
  18. }
  19. @PutMapping("/{id}")
  20. public UserDTO update(@PathVariable Long id, @RequestBody UserDTO user) {
  21. user.setId(id);
  22. userService.updateById(user);
  23. return user;
  24. }
  25. @DeleteMapping("/{id}")
  26. public void delete(@PathVariable Long id) {
  27. userService.removeById(id);
  28. }
  29. }

在上述代码中,我们使用 @RestController 注解来定义一个 RESTful 风格的控制器,使用 @RequestMapping 注解来指定请求的路径。在控制器类中,我们通过 @Autowired 注解将 Service 接口注入到 Controller 中,使用 @GetMapping@PostMapping@PutMapping 和 @DeleteMapping 注解来分别定义 GET、POST、PUT 和 DELETE 请求的处理方法。

2.添加 Swagger 文档支持

为了方便地查看和测试接口,我们可以使用 Swagger UI 来生成文档和测试接口。

首先,在 Maven 中添加 Swagger2 和 Swagger UI 的依赖:

  1. <!-- pom.xml -->
  2. <dependency>
  3. <groupId>io.springfox</groupId>
  4. <artifactId>springfox-swagger2</artifactId>
  5. <version>2.10.5</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>io.springfox</groupId>
  9. <artifactId>springfox-swagger-ui</artifactId>
  10. <version>2.10.5</version>
  11. </dependency>

然后,在 Spring Boot 的配置文件中添加如下配置:

  1. @Configuration
  2. @EnableSwagger2
  3. public class SwaggerConfig {
  4. @Bean
  5. public Docket api() {
  6. return new Docket(DocumentationType.SWAGGER_2)
  7. .select()
  8. .apis(RequestHandlerSelectors.basePackage("com.example.demo.controller"))
  9. .paths(PathSelectors.any())
  10. .build();
  11. }
  12. }

最后,启动 Spring Boot 应用,访问 http://localhost:8080/swagger-ui.html 即可看到 Swagger 文档和测试接口的界面。

现在,在 Swagger UI 中可以方便地测试 CRUD 操作接口,验证 Mybatis Plus 和 Spring Security 的整合效果。

2023/4/10 20:33:00

之前你不是在controller层加注解@PreAuthorize("hasAuthority('ROLE_ADMIN')")实现过滤的吗,为何这里不需要?

重试

复制

你提到的 @PreAuthorize("hasAuthority('ROLE_ADMIN')") 注解是用来控制方法的访问权限的,可以在 Controller 层的方法上添加该注解来进行权限控制,保证只有具有相应权限的用户才能访问该接口。

在我的之前的范例中,之所以需要添加该注解是因为我们控制了访问 /admin 路径的权限,只有具有 ROLE_ADMIN 角色的用户才能访问到该路径下的接口。而在这个示例中,我没有控制任何路径的权限,只是使用了 Spring Security 来实现用户的身份认证和访问授权。

在实际开发中,根据业务需求和安全性要求,可以在 Controller 层的每个方法上添加不同的权限控制注解,以实现更加细粒度的权限控制。

2023/4/10 20:39:29

现在在Controller层加上@PreAuthorize,我想看看如何控制

重试

复制

好的,我来给你举个例子:

假设我们的应用需要实现通过用户角色来控制访问权限,例如只有拥有 ADMIN 角色的用户才能访问某些接口,我们可以在 Controller 层的方法上使用 @PreAuthorize 注解来实现权限控制。

首先,我们需要在 pom.xml 文件中添加 Spring Security 的依赖:

  1. <!-- pom.xml -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-security</artifactId>
  5. </dependency>

然后,我们可以在 WebSecurityConfig 配置类中设置拦截规则,例如:

  1. @Configuration
  2. @EnableWebSecurity
  3. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  4. @Override
  5. protected void configure(HttpSecurity http) throws Exception {
  6. http.authorizeRequests()
  7. .antMatchers("/admin/**").hasRole("ADMIN") // 只有 ADMIN 角色可以访问 /admin 路径下的接口
  8. .anyRequest().authenticated()
  9. .and().formLogin()
  10. .and().httpBasic();
  11. }
  12. }

在上述代码中,我们设置了只有拥有 ADMIN 角色的用户可以访问 /admin/** 路径下的接口,并且其他的请求都需要进行身份认证才能访问。

接着,我们可以在 Controller 层中使用 @PreAuthorize 注解来控制方法的访问权限,例如:

  1. @RestController
  2. @RequestMapping("/api/users")
  3. public class UserController {
  4. @Autowired
  5. private UserService userService;
  6. @PreAuthorize("hasRole('ADMIN')") // 只有 ADMIN 角色可以访问该接口
  7. @GetMapping("/")
  8. public List<UserDTO> findAll() {
  9. return userService.list();
  10. }
  11. @PreAuthorize("hasRole('USER') or hasRole('ADMIN')") // 只有 USER 或 ADMIN 角色可以访问该接口
  12. @GetMapping("/{id}")
  13. public UserDTO findById(@PathVariable Long id) {
  14. return userService.getById(id);
  15. }
  16. @PreAuthorize("hasRole('ADMIN')") // 只有 ADMIN 角色可以访问该接口
  17. @PostMapping("/")
  18. public UserDTO create(@RequestBody UserDTO user) {
  19. userService.save(user);
  20. return user;
  21. }
  22. @PreAuthorize("hasRole('ADMIN')") // 只有 ADMIN 角色可以访问该接口
  23. @PutMapping("/{id}")
  24. public UserDTO update(@PathVariable Long id, @RequestBody UserDTO user) {
  25. user.setId(id);
  26. userService.updateById(user);
  27. return user;
  28. }
  29. @PreAuthorize("hasRole('ADMIN')") // 只有 ADMIN 角色可以访问该接口
  30. @DeleteMapping("/{id}")
  31. public void delete(@PathVariable Long id) {
  32. userService.removeById(id);
  33. }
  34. }

在上述代码中,我们给每个需要控制访问权限的方法上添加了 @PreAuthorize 注解,并给该注解传递了相应的角色信息,例如 @PreAuthorize("hasRole('ADMIN')") 表示只有 ADMIN 角色可以访问该接口,@PreAuthorize("hasRole('USER') or hasRole('ADMIN')") 表示只有 USER 或 ADMIN 角色可以访问该接口等。

现在,我们就可以根据业务需求和安全性要求,使用 @PreAuthorize 注解来实现细粒度的方法级别权限控制。

2023/4/10 20:41:39

那么这个USER和'ADMIN'的权限我去哪里给每个用户定义呢?是在java程序里还是在mysql表里?或者说是其他方式

重试

复制

可以说在 Java 程序和 MySQL 中都可以定义用户的角色和权限。

一般来说,在 MySQL 中创建用户和角色并给予相应的权限是很常见的做法。可以在 MySQL 中创建一个用户表和角色表,然后再创建一个关联表来记录用户和角色之间的对应关系。例如:

  1. CREATE TABLE user (
  2. id BIGINT NOT NULL AUTO_INCREMENT,
  3. username VARCHAR(64) NOT NULL,
  4. password VARCHAR(256) NOT NULL,
  5. PRIMARY KEY (id)
  6. );
  7. CREATE TABLE role (
  8. id BIGINT NOT NULL AUTO_INCREMENT,
  9. name VARCHAR(64) NOT NULL,
  10. PRIMARY KEY (id)
  11. );
  12. CREATE TABLE user_role (
  13. user_id BIGINT NOT NULL,
  14. role_id BIGINT NOT NULL,
  15. PRIMARY KEY (user_id, role_id),
  16. FOREIGN KEY (user_id) REFERENCES user (id),
  17. FOREIGN KEY (role_id) REFERENCES role (id)
  18. );

然后,在 Java 程序中,可以通过 UserRepository 和 RoleRepository 来操作用户和角色等相关信息,例如:

  1. public interface UserRepository extends JpaRepository<User, Long> {
  2. User findByUsername(String username);
  3. }
  4. public interface RoleRepository extends JpaRepository<Role, Long> {
  5. Role findByName(String name);
  6. }

只要有了这些信息,就可以在 Spring Security 的配置类中将用户和角色关联起来,并授权给相应的角色。

例如,在上面提到的 WebSecurityConfig 配置类中,可以使用 UserDetailsService 来获取用户相关信息,并将用户和角色在内存中进行对应和授权:

  1. @Autowired
  2. private UserRepository userRepository;
  3. @Autowired
  4. private RoleRepository roleRepository;
  5. @Override
  6. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  7. auth.userDetailsService(username -> {
  8. User user = userRepository.findByUsername(username);
  9. if (user == null) {
  10. throw new UsernameNotFoundException("User " + username + " not found");
  11. }
  12. Set<GrantedAuthority> authorities = new HashSet<>();
  13. for (Role role : user.getRoles()) {
  14. authorities.add(new SimpleGrantedAuthority(role.getName()));
  15. }
  16. return new org.springframework.security.core.userdetails.User(
  17. user.getUsername(), user.getPassword(), authorities);
  18. });
  19. }
  20. @Override
  21. protected void configure(HttpSecurity http) throws Exception {
  22. http.authorizeRequests()
  23. .antMatchers("/admin/**").hasRole("ADMIN")
  24. .anyRequest().authenticated()
  25. .and().formLogin()
  26. .and().httpBasic();
  27. }

在上述代码中,我们使用 UserDetailsService 对象来获取用户相关信息,并将用户和角色在内存中进行对应和授权,这样用户就可以根据自己的角色来访问相应的接口了。

当然,这只是一个比较简单的示例,真实的应用场景可能会更加复杂,需要根据实际情况来灵活地设计用户和角色的关系,并进行相应的授权。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/67654
推荐阅读
相关标签
  

闽ICP备14008679号