📜  Spring Security Java示例(1)

📅  最后修改于: 2023-12-03 15:20:13.463000             🧑  作者: Mango

Spring Security Java 示例

Spring Security 是一个基于 Spring 框架的安全认证和访问控制框架。它提供了强大的身份验证和授权支持,帮助我们保护 Web 应用程序免受各种常见攻击。

为什么使用 Spring Security?

在 Web 应用程序中,安全是必不可少的。不仅需要验证用户的身份,还需要限制用户对资源的访问,以确保应用程序的机密性和可用性。Spring Security 提供了多种支持身份验证和授权的功能,它提供了以下优势:

  • 简化安全性配置处理
  • 支持多种身份验证机制
  • 提供了基于角色或权限的授权
  • 防止常见的攻击
如何使用 Spring Security?

在 Java 应用程序中使用 Spring Security 需要以下步骤:

  • 导入 Spring Security 依赖库
  • 配置 Spring Security
  • 编写自定义的用户认证逻辑
  • 配置 Spring Security 控制台
导入 Spring Security 依赖库

Spring Security 的核心依赖库是 spring-security-core,可以使用以下 Maven 坐标导入:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>5.5.2</version>
</dependency>

除了 spring-security-core,还需要根据需要导入其他模块,如 spring-security-webspring-security-config

配置 Spring Security

在 Spring 应用程序中启用 Spring Security 功能,需要使用 @EnableWebSecurity 注解启用 Web 安全性配置,并创建一个类来扩展 WebSecurityConfigurerAdapter。例如:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private UserDetailsService userDetailsService;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
      .antMatchers("/login").permitAll()
      .antMatchers("/**").authenticated()
    .and()
      .formLogin()
      .loginPage("/login")
    .and()
      .logout()
      .logoutSuccessUrl("/login");
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
  }

}

在上述示例中,我们使用了 configure() 方法来定义身份验证和授权规则。具体来说,我们禁止除登录页面之外的所有请求,并在表单登录成功后使用户重定向到原始请求的 URL。我们还在 AuthenticationManagerBuilder 中指定了自定义的用户详细信息服务。

编写自定义的用户认证逻辑

实际的用户身份验证逻辑通常是非常复杂的,因此 Spring Security 允许我们编写自定义的认证逻辑,以满足应用程序的需要。具体来说,我们需要实现 UserDetailsService 接口,并通过 Spring 注入到配置类中。

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

  @Autowired
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByUsername(username)
      .orElseThrow(() -> new UsernameNotFoundException("User not found"));
    return new org.springframework.security.core.userdetails.User(
      user.getUsername(),
      user.getPassword(),
      user.isEnabled(),
      user.isAccountNonExpired(),
      user.isCredentialsNonExpired(),
      user.isAccountNonLocked(),
      user.getAuthorities()
    );
  }

}

在上述示例中,我们从 UserRepository 中检索用户,并根据用户的属性创建 Spring Security 中的 User 对象。

配置 Spring Security 控制台

最后,我们可以创建一个简单的 Web 控制台来管理用户和角色。在 application.properties 文件中添加以下行:

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

然后创建一个 JSP 文件来渲染控制台:

<%@page contentType="text/html"%>
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Spring Security 控制台</title>
</head>
<body>
  <h1>Spring Security 控制台</h1>
  <p><a href="${pageContext.request.contextPath}/h2-console">H2 控制台</a></p>
  <form method="post" action="${pageContext.request.contextPath}/registration">
      <h3>新用户注册</h3>
      <label for="inputUsername">用户名:</label>
      <input type="text" id="inputUsername" name="username" required><br>
      <label for="inputPassword">密码:</label>
      <input type="password" id="inputPassword" name="password" required><br>
      <label for="inputRole">角色:</label>
      <input type="text" id="inputRole" name="role" required><br>
      <button type="submit">注册</button>
  </form>
  <h3>现有认证用户</h3>
  <table>
    <thead>
      <tr>
        <th>用户名</th>
        <th>密码</th>
        <th>角色</th>
      </tr>
    </thead>
    <tbody>
      <c:forEach var="user" items="${users}">
        <tr>
          <td>${user.username}</td>
          <td>${user.password}</td>
          <td>${user.authorities}</td>
        </tr>
      </c:forEach>
    </tbody>
  </table>
</body>
</html>

在控制器中,我们可以使用以下代码来渲染该 JSP 页面并处理用户的注册。

@Controller
public class UserController {

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private PasswordEncoder passwordEncoder;

  @GetMapping("/register")
  public String register(Model model) {
    List<User> users = userRepository.findAll();
    model.addAttribute("users", users);
    return "register";
  }

  @PostMapping("/registration")
  public String registration(@RequestParam String username, @RequestParam String password, @RequestParam String role) {
    User user = new User(username, passwordEncoder.encode(password), Arrays.asList(new SimpleGrantedAuthority(role)));
    userRepository.save(user);
    return "redirect:/register";
  }

}
总结

Spring Security 是一个功能强大的安全框架,它可以让我们轻松地实现身份验证和授权。虽然有一些复杂的配置和编程任务,但最终结果是安全性更高和更受信任的应用程序。