springSecurity整合Jwt并对其校验密码是否正确代码
时间: 2024-03-19 07:45:49 浏览: 20
以下是一个简单的示例代码,用于演示Spring Security整合Jwt并对其进行密码校验。
1. 添加Spring Security和Jwt的依赖
```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
```
2. 创建Jwt的工具类
```
public class JwtUtils {
private static final String SECRET_KEY = "mySecretKey";
private static final long EXPIRATION_TIME = 86400000; // 24 hours
public static String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put("username", userDetails.getUsername());
claims.put("authorities", userDetails.getAuthorities().stream()
.map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
public static Authentication getAuthentication(String token) {
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
Collection<? extends GrantedAuthority> authorities =
Arrays.stream(claims.get("authorities").toString().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
UserDetails userDetails = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(userDetails, "", authorities);
}
}
```
3. 创建一个实现了UserDetailsService接口的类
```
@Service
public class UserDetailsServiceImpl 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: " + username);
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
}
}
```
4. 创建JwtAuthenticationFilter类
```
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
try {
Authentication authentication = JwtUtils.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception e) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().write(e.getMessage());
return;
}
}
filterChain.doFilter(request, response);
}
}
```
5. 创建JwtAuthorizationFilter类
```
public class JwtAuthorizationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
try {
Claims claims = Jwts.parser()
.setSigningKey("mySecretKey")
.parseClaimsJws(token)
.getBody();
String username = claims.get("username", String.class);
if (username != null) {
List<String> authorities = claims.get("authorities", List.class);
List<SimpleGrantedAuthority> grantedAuthorities = authorities.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, grantedAuthorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception e) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().write(e.getMessage());
return;
}
}
filterChain.doFilter(request, response);
}
}
```
6. 在Spring Security的配置类中添加JwtAuthenticationFilter和JwtAuthorizationFilter,并配置相应的拦截规则
```
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Autowired
private JwtAuthorizationFilter jwtAuthorizationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
}
}
```
7. 在登录时,使用PasswordEncoder对密码进行加密,并将加密后的密码与数据库中存储的密码进行比对
```
@Service
public class AuthServiceImpl implements AuthService {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public String login(LoginRequest loginRequest) {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());
return jwtUtils.generateToken(userDetails);
} catch (Exception e) {
throw new BadCredentialsException("Invalid username or password");
}
}
@Override
public User register(RegisterRequest registerRequest) {
User user = new User();
user.setUsername(registerRequest.getUsername());
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
return userRepository.save(user);
}
}
```
8. 在注册时,使用PasswordEncoder对密码进行加密,并将加密后的密码存储到数据库中
```
public class RegisterRequest {
private String username;
private String password;
// getters and setters
}
```
```
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthService authService;
@PostMapping("/login")
public String login(@RequestBody LoginRequest loginRequest) {
return authService.login(loginRequest);
}
@PostMapping("/register")
public User register(@RequestBody RegisterRequest registerRequest) {
return authService.register(registerRequest);
}
}
```
以上是一个简单的示例代码,用于演示Spring Security整合Jwt并对其进行密码校验。需要注意的是,这只是一个示例代码,实际应用中需要根据具体需求进行修改和扩展。