要保护一个Spring Boot 2 API,你可以使用Spring Security来实现认证和授权。下面是一个简单的示例:
首先,添加Spring Security和Spring Security JWT依赖到你的项目中。在pom.xml
文件中添加以下代码:
org.springframework.boot
spring-boot-starter-security
io.jsonwebtoken
jjwt
0.9.1
然后,创建一个SecurityConfig
类来配置Spring Security:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/public").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
在上面的配置中,我们配置了以下内容:
接下来,创建一个自定义的UserDetailsService
实现类来获取用户信息:
@Service
public class UserService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
}
}
在上面的代码中,我们通过UserRepository
获取用户信息,并返回一个实现了UserDetails
接口的对象。
接下来,创建一个JwtUtil
类来生成和解析JWT:
@Component
public class JwtUtil {
private final String secret = "your-secret-key";
public String generateToken(String username) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + 86400000); // 24 hours
return Jwts.builder()
.setSubject(username)
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public String getUsernameFromToken(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
在上面的代码中,我们使用了一个密钥来生成和解析JWT。你可以根据实际需求修改密钥。
最后,创建一个JwtRequestFilter
类来验证请求中的JWT:
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private UserService userService;
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
username = jwtUtil.getUsernameFromToken(jwt);
}
if (username != null &&