在 Spring Boot 项目中整合 Spring Security 并自定义登录接口可以通过以下步骤完成。这里是一个简化的指南和代码示例。
1. 添加依赖
首先,你需要在 pom.xml
文件中添加必要的依赖。以下是 Spring Boot 和 Spring Security 的常见依赖:
<dependencies> <!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot Starter Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- Spring Boot Starter Data JPA (if you are using JPA) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- H2 Database (for testing, replace with your database dependency) --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <!-- Lombok (optional, for simplifying code) --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> </dependencies>
2. 创建自定义用户详细信息
创建一个实现 UserDetails
接口的类,以便能够在认证过程中使用自定义的用户信息。
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; public class CustomUserDetails implements UserDetails { private String username; private String password; private Collection<? extends GrantedAuthority> authorities; public CustomUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities) { this.username = username; this.password = password; this.authorities = authorities; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } @Override public String getPassword() { return password; } @Override public String getUsername() { return username; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
3. 创建用户服务类
实现 UserDetailsService
接口来加载用户的详细信息。
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; @Service public class CustomUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 这里你可以通过从数据库获取用户信息来构造 CustomUserDetails 对象 // 示例中使用硬编码的用户数据 if ("user".equals(username)) { return new CustomUserDetails(username, "password", List.of(() -> "ROLE_USER")); } else { throw new UsernameNotFoundException("User not found"); } } }
4. 配置 Spring Security
创建一个 SecurityConfig
类来配置 Spring Security,包括自定义登录接口。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService userDetailsService; @Bean public CustomAuthenticationFilter customAuthenticationFilter() throws Exception { CustomAuthenticationFilter filter = new CustomAuthenticationFilter(); filter.setAuthenticationManager(authenticationManagerBean()); return filter; } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } }
5. 自定义认证过滤器
创建一个自定义的认证过滤器,处理登录请求并进行身份验证。
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { try { // 解析请求中的 JSON 数据 LoginRequest loginRequest = new ObjectMapper().readValue(request.getInputStream(), LoginRequest.class); return getAuthenticationManager().authenticate( new UsernamePasswordAuthenticationToken( loginRequest.getUsername(), loginRequest.getPassword() ) ); } catch (IOException e) { throw new RuntimeException(e); } } }
6. 创建登录请求 DTO
创建一个用于接收登录请求数据的 DTO 类。
public class LoginRequest { private String username; private String password; // Getters and setters public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
7. 测试
启动你的 Spring Boot 应用程序,并发送一个 POST 请求到 /login
接口,包含 JSON 格式的用户名和密码,例如:
1. { 2. "username": "user", 3. "password": "password" 4. }
总结
以上是一个基本的 Spring Boot 与 Spring Security 整合的自定义登录接口的实现示例。根据你的需求,你可能需要调整和扩展这些代码,例如增加用户验证逻辑、处理异常、配置 JWT 等。这个示例只是一个起点,希望能帮助你理解整体的整合过程。