一、什么是Java Spring Security和JWT?
Java SpringSecurity是Spring框架中的一个安全工具,能够提供身份验证、授权、防止csrf攻击等功能;
JWT(JSON Web Token)是一种用于身份验证的开放标准(RFC 7519),它使用JSON格式在网络之间安全地传递信息。JWT具有轻量级、开放性、易于使用和便于传输等特点。
二、Java Spring Security和JWT的使用场景及优势
在一些需要身份验证和授权的应用场景下,Java Spring Security和JWT能够帮助我们快速实现用户登录认证、资源权限的控制等功能,并对业务系统的稳定性、安全性产生积极的影响。
Java Spring Security优势:
1.支持多种身份验证方式
2.支持自定义权限验证
3.提供防御csrf攻击的措施
4.提供了安全的cookie记住我功能
5.扩展性强,易于进行二次开发
JWT优势:
1.轻量级
2.可显示和可扩展
3.不依赖于特定的后端技术栈
4.相对于传统的cookie方式,更安全和可靠
三、Java Spring Security+JWT实现登录认证的具体步骤
1.引入Spring Security和JWT依赖
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2.编写登录认证接口
@RestController
@RequestMapping("/api")
public class LoginController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public ResultWrapper login(@RequestBody LoginRequest loginRequest) {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword()));
} catch (BadCredentialsException e) {
// 捕获登录异常
return ResultWrapper.failure(ResultCodeEnum.LOGIN_FAILED, e.getMessage());
}
// ... 根据登陆用户信息生成jwtToken
return ResultWrapper.success(token);
}
}
3.根据登录用户信息生成JwtToken
public class JwtUtil {
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return doGenerateToken(claims, userDetails.getUsername());
}
private String doGenerateToken(Map<String, Object> claims, String subject) {
Date now = new Date();
Date validity = new Date(now.getTime() + JWT_EXPIRATION_MS);
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, JWT_SECRET)
.compact();
}
}
4.编写认证拦截器
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtil jwtUserDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
final String authorizationHeader = request.getHeader(AUTHORIZATION_HEADER);
String username = null;
String jwtToken = null;
if (authorizationHeader != null && authorizationHeader.startsWith(TOKEN_PREFIX)) {
jwtToken = authorizationHeader.substring(7);
username = jwtUtil.extractUsername(jwtToken);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
5.配置Spring Security
@Configuration
@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private JwtUserDetailsService jwtUserDetailsService;
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
authenticationManagerBuilder.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/api/login").permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}
6.编写示例代码
举个例子,如果你是一个租房网站的开发人员。假设你们的网站首页需要用户登录才能访问,如果用户没有登录,应该跳转到登录页。
示例 1:登录接口
你们的租房网站提供登录接口,需要用户在请求体中传入用户名和密码:
POST /api/login HTTP/1.1
Content-Type: application/json;charset=UTF-8
{
"username": "example",
"password": "password"
}
如果用户输入的用户名和密码正确,则响应体中返回JWT Token:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"code": "0",
"message": "登录成功!",
"data": "eyJhbG..."
}
示例 2:首页请求
用户在登录成功后,系统将通过JWT Token检验用户的身份,不符合条件的用户将被重定向到登录页:
GET /api/home HTTP/1.1
Authorization: Bearer eyJhbG...
如果JWT Token验证成功,则允许用户访问首页:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"code": "0",
"message": "欢迎来到我们的租房网站!"
}
以上是Java SpringSecurity+JWT实现登录认证的完整攻略,通过以上流程,您可以成功地将Java SpringSecurity和JWT应用到您的业务系统中,实现用户的安全登录认证。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java SpringSecurity+JWT实现登录认证 - Python技术站