Spring Boot与Spring Security结合MyBatis构建安全的RESTful Web服务 ...

打印 上一主题 下一主题

主题 869|帖子 869|积分 2607

为什么选择Spring Boot、Spring Security和MyBatis?

1. 简化配置和开辟: Spring Boot通过自动配置大大减少了开辟中的配置工作,而Spring Security提供了强大的安全特性。MyBatis是一种灵活的ORM框架,利用SQL语句举行数据操纵,非常适合有复杂查询需求的项目。
2. 快速构建生产级应用: Spring Boot和Spring Security集成了很多企业级的特性,如身份认证、授权、加密等,使得应用更容易部署到生产环境。MyBatis简化了复杂SQL的管理和执行,使得数据操纵更加高效。
3. 丰富的生态系统: Spring Boot与Spring Security无缝集成,提供了大量的扩展组件,方便实现各种复杂功能。MyBatis与Spring的结合也非常紧密,可以或许提供强大的数据持久化支持。
废话不多说,上代码!

1. 那么好,第一步:我们来创建一个名为 HelloController 的类来处理HTTP哀求。

  1. package com.example.demo;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. @RestController
  5. public class HelloController {
  6.     @GetMapping("/hello")
  7.     public String sayHello() {
  8.         return "Hello, Spring Boot!";
  9.     }
  10. }
复制代码
2. 第二步:我们来配置Spring Security

创建一个 SecurityConfig 类来配置Spring Security。
  1. package com.example.demo;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  5. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  6. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  7. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  8. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  9. import org.springframework.security.crypto.password.PasswordEncoder;
  10. @Configuration // 标记该类是一个配置类
  11. @EnableWebSecurity // 启用Spring Security的Web安全支持
  12. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  13.     @Autowired
  14.     private CustomUserDetailsService userDetailsService;
  15.     /**
  16.      * 配置HTTP请求的安全性
  17.      * @param http HttpSecurity对象,用于配置Web安全
  18.      * @throws Exception 抛出配置错误异常
  19.      */
  20.     @Override
  21.     protected void configure(HttpSecurity http) throws Exception {
  22.         http
  23.             .csrf().disable() // 禁用CSRF保护
  24.             .authorizeRequests()
  25.             .antMatchers("/hello").permitAll() // 对于/hello请求,不需要认证
  26.             .anyRequest().authenticated() // 其他任何请求都需要认证
  27.             .and()
  28.             .formLogin() // 启用表单登录
  29.             .and()
  30.             .httpBasic(); // 启用HTTP Basic认证
  31.     }
  32.     /**
  33.      * 配置身份验证管理器
  34.      * @param auth AuthenticationManagerBuilder对象,用于构建身份验证管理器
  35.      * @throws Exception 抛出配置错误异常
  36.      */
  37.     @Override
  38.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  39.         auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); // 使用自定义的用户身份验证服务和密码编码器
  40.     }
  41.     /**
  42.      * 定义密码编码器
  43.      * @return PasswordEncoder对象,用于加密用户密码
  44.      */
  45.     @Bean
  46.     public PasswordEncoder passwordEncoder() {
  47.         return new BCryptPasswordEncoder(); // 使用BCrypt对密码进行加密
  48.     }
  49. }
复制代码
  注解解释:
  

  • @Configuration: 标志该类为一个配置类。
  • @EnableWebSecurity: 启用Spring Security的Web安全支持。
  配置解释:
  

  • csrf().disable(): 禁用CSRF掩护,防止跨站哀求伪造攻击。
  • authorizeRequests(): 配置基于HttpServletRequest的访问限制。
  • antMatchers("/hello").permitAll(): 对/hello哀求允许所有访问,不需要认证。
  • anyRequest().authenticated(): 其他任何哀求都需要认证。
  • formLogin(): 启用表单登录。
  • httpBasic(): 启用HTTP Basic认证。
  • AuthenticationManagerBuilder: 配置身份验证管理器,利用自定义的用户身份验证服务和密码编码器。
  • BCryptPasswordEncoder: 利用BCrypt对密码举行加密,增长密码安全性。
  3. 第三步当然少不了数据库配置。配置MyBatis 

在 application.properties 文件中添加数据库的配置:
  1. spring.datasource.url=xxxx // 配置成你自己数据库的URL
  2. spring.datasource.driverClassName=xxx //配置成你自己的数据库驱动类
  3. spring.datasource.username=xxx // 数据库用户名
  4. spring.datasource.password=xxx // 数据库密码
复制代码
4. 实体肯定也不能丢啦~ 创建一个 User 实体类:

  1. package com.example.demo;
  2. public class User {
  3.     private Long id;
  4.     private String username;
  5.     private String password;
  6.     // Getters and setters
  7. }
复制代码
5. 数据库查询肯定也要撒。创建一个MyBatis的Mapper接口 UserMapper:

  1. package com.example.demo;
  2. import org.apache.ibatis.annotations.*;
  3. @Mapper // 标记这是一个MyBatis的Mapper接口
  4. public interface UserMapper {
  5.     @Select("SELECT * FROM users WHERE username = #{username}")
  6.     User findByUsername(String username); // 通过用户名查找用户
  7.     @Insert("INSERT INTO users(username, password) VALUES(#{username}, #{password})")
  8.     @Options(useGeneratedKeys = true, keyProperty = "id") // 自动生成主键
  9.     void insert(User user); // 插入新用户
  10. }
复制代码
6. 业务逻辑层肯定需要的不。创建一个 UserService 类:

  1. package com.example.demo;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.security.crypto.password.PasswordEncoder;
  4. import org.springframework.stereotype.Service;
  5. @Service // 标记这是一个服务类
  6. public class UserService {
  7.     @Autowired
  8.     private UserMapper userMapper;
  9.     @Autowired
  10.     private PasswordEncoder passwordEncoder;
  11.     /**
  12.      * 通过用户名查找用户
  13.      * @param username 用户名
  14.      * @return User对象
  15.      */
  16.     public User findByUsername(String username) {
  17.         return userMapper.findByUsername(username);
  18.     }
  19.     /**
  20.      * 保存用户
  21.      * @param user User对象
  22.      */
  23.     public void save(User user) {
  24.         user.setPassword(passwordEncoder.encode(user.getPassword())); // 加密用户密码
  25.         userMapper.insert(user); // 插入用户到数据库
  26.     }
  27. }
复制代码
7. 验证你在系统的身份信息肯定也少不了啦,用户身份验证服务

创建一个 CustomUserDetailsService 类来实现用户身份验证。
  1. package com.example.demo;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.security.core.userdetails.UserDetails;
  4. import org.springframework.security.core.userdetails.UserDetailsService;
  5. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  6. import org.springframework.stereotype.Service;
  7. @Service // 标记这是一个服务类
  8. public class CustomUserDetailsService implements UserDetailsService {
  9.     @Autowired
  10.     private UserService userService;
  11.     /**
  12.      * 根据用户名加载用户
  13.      * @param username 用户名
  14.      * @return UserDetails对象
  15.      * @throws UsernameNotFoundException 当用户未找到时抛出异常
  16.      */
  17.     @Override
  18.     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  19.         User user = userService.findByUsername(username);
  20.         if (user == null) {
  21.             throw new UsernameNotFoundException("用户不存在");
  22.         }
  23.         return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
  24.     }
  25. }
复制代码
  方法解释:
  

  • loadUserByUsername: 这个方法是根据用户名加载用户信息,假如用户不存在则抛出异常,返回一个UserDetails对象,包含用户名、密码和权限信息。
  8. 追求优雅,错误处理肯定要啦!

当然了,为了美满我们的应用,我们需要处理可能发生的错误。毕竟我们程序员追求的就是优雅!

例如,当用户未找到时返回恰当的错误信息。
创建一个 ResourceNotFoundException 类:
  1. package com.example.demo;
  2. public class ResourceNotFoundException extends RuntimeException {
  3.     public ResourceNotFoundException(String message) {
  4.         super(message);
  5.     }
  6. }
复制代码
创建一个 GlobalExceptionHandler 类来处理全局异常:
  1. package com.example.demo;
  2. import org.springframework.http.HttpStatus;
  3. import org.springframework.http.ResponseEntity;
  4. import org.springframework.web.bind.annotation.ExceptionHandler;
  5. import org.springframework.web.bind.annotation.RestControllerAdvice;
  6. @RestControllerAdvice // 标记这是一个全局异常处理类
  7. public class GlobalExceptionHandler {
  8.     /**
  9.      * 处理ResourceNotFoundException异常
  10.      * @param ex ResourceNotFoundException对象
  11.      * @return ResponseEntity对象,包含错误信息和HTTP状态码
  12.      */
  13.     @ExceptionHandler(ResourceNotFoundException.class)
  14.     public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
  15.         return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
  16.     }
  17. }
复制代码
  注解解释:
  

  • @RestControllerAdvice: 标志这是一个全局异常处理类,处理控制器中的异常。
  • @ExceptionHandler: 定义异常处理方法,当抛出 ResourceNotFoundException 时返回404状态码和错误信息。
  方法解释:
  

  • handleResourceNotFoundException: 处理 ResourceNotFoundException 异常,返回包含错误信息和404状态码的响应。
  带来的好处:
  

  • 一致性:所有异常都由同一的处理器处理,返回一致的错误信息。
  • 易于调试:更清晰的错误信息有助于快速定位问题。
  好了好了,通过以上示例,我们展示了如何结合Spring Boot、Spring Security和MyBatis构建一个安全的RESTful Web服务,并先容了自动配置、数据访问、和异常处理等关键概念。

创作不易,希望以上代码能给你带来资助!



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万有斥力

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表