Spring Security如何在接口中登录方式
时间: 2024-02-22 19:31:20 浏览: 36
Spring Security提供了多种方式来实现接口中的登录,其中常见的方式是使用token认证。以下是一个简单的示例:
1. 配置Spring Security
在Spring Security的配置文件中,需要配置一个TokenAuthenticationFilter来处理token认证。具体如下:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JwtTokenProvider jwtTokenProvider() {
return new JwtTokenProvider();
}
@Bean
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
return new TokenAuthenticationFilter();
}
}
```
2. 创建TokenAuthenticationFilter
TokenAuthenticationFilter是一个过滤器,用于在请求头中读取并验证token。具体如下:
```java
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = jwtTokenProvider.resolveToken(request);
if (token != null && jwtTokenProvider.validateToken(token)) {
Authentication auth = jwtTokenProvider.getAuthentication(token);
if (auth != null) {
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
filterChain.doFilter(request, response);
}
}
```
3. 创建JwtTokenProvider
JwtTokenProvider用于生成和验证token。具体如下:
```java
public class JwtTokenProvider {
private static final String SECRET_KEY = "secret_key";
private static final long EXPIRATION_TIME = 864_000_000; // 10 days
private static final String TOKEN_PREFIX = "Bearer ";
private static final String HEADER_STRING = "Authorization";
public String createToken(String username) {
Claims claims = Jwts.claims().setSubject(username);
Date now = new Date();
Date validity = new Date(now.getTime() + EXPIRATION_TIME);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public Authentication getAuthentication(String token) {
String username = getUsername(token);
User user = userService.loadUserByUsername(username);
return new UsernamePasswordAuthenticationToken(user, "", user.getAuthorities());
}
public String getUsername(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (SignatureException | MalformedJwtException | ExpiredJwtException | UnsupportedJwtException | IllegalArgumentException ex) {
return false;
}
}
public String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(HEADER_STRING);
if (bearerToken != null && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(TOKEN_PREFIX.length());
}
return null;
}
}
```
4. 创建登录接口
在登录接口中,需要调用JwtTokenProvider.createToken方法生成token,并将token返回给客户端。具体如下:
```java
@RestController
public class LoginController {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String token = jwtTokenProvider.createToken(loginRequest.getUsername());
return ResponseEntity.ok(new JwtResponse(token));
}
}
```
5. 测试接口
使用Postman等工具发送请求,将生成的token放入请求头中,即可访问需要登录后才能访问的接口。