下面就来详细讲解“SpringBoot结合JWT登录权限控制的实现”的攻略。
第一步:添加Maven依赖
在pom.xml
文件中添加以下Maven
依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
第二步:配置JWT工具类
创建一个JWT工具类,用于生成和解析JWT Token,例如:
@Component
public class JwtUtils {
/**
* JWT加密密钥
*/
private static final String SECRET_KEY = "123456";
/**
* 过期时间,单位毫秒
*/
private static final long EXPIRATION_TIME = 86400000;
/**
* 生成JWT Token
*
* @param id 用户ID
* @param username 用户名
* @param authorities 用户角色
* @return JWT Token
*/
public String generateToken(Long id, String username, List<String> authorities) {
return Jwts.builder()
.setSubject(username)
.claim("id", id)
.claim("authorities", authorities)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
/**
* 解析JWT Token
*
* @param token JWT Token
* @return
* @throws JwtException
*/
public Claims parseToken(String token) throws JwtException {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
}
第三步:实现登录功能
在UserController
中实现登录API接口,校验登录信息,若登录成功生成JWT Token并返回给客户端,例如:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private JwtUtils jwtUtils;
/**
* 用户登录API接口
*/
@PostMapping("/login")
public Result login(String username, String password) {
// 校验用户名和密码是否正确
if ("admin".equals(username) && "123456".equals(password)) {
// 登录成功,生成JWT Token
List<String> authorities = new ArrayList<>();
authorities.add("ADMIN");
String token = jwtUtils.generateToken(1L, username, authorities);
// 返回JWT Token
return Result.success(token, "登录成功");
} else {
// 登录失败
return Result.failure("用户名或密码错误");
}
}
}
第四步:实现权限控制
在WebSecurityConfig
中实现权限控制逻辑,先排除登录接口路径,将其他路径都设置为需要进行认证,例如:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
// 排除登录接口路径
http.authorizeRequests().antMatchers("/user/login").permitAll()
// 其他路径都需要进行认证
.anyRequest().authenticated()
.and().csrf().disable()
.addFilterAt(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
然后实现一个JwtAuthenticationFilter
类,用于从JWT Token中获取用户信息并进行权限校验,例如:
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String header = request.getHeader("Authorization");
if (StringUtils.isNotEmpty(header) && header.startsWith("Bearer ")) {
String token = header.substring(7);
try {
Claims claims = jwtUtils.parseToken(token);
String username = claims.getSubject();
Long id = Long.valueOf(claims.get("id").toString());
List<String> authorities = (List<String>) claims.get("authorities");
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(id, username, authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
} catch (JwtException e) {
throw new JwtAuthenticationException(e.getMessage());
}
}
chain.doFilter(request, response);
}
}
在JwtAuthenticationFilter
中,首先从Authorization
请求头中获取JWT Token,然后解析出用户信息和角色信息,最后将用户信息封装成UsernamePasswordAuthenticationToken
对象并设置到SecurityContextHolder
中。
示例一:调用登录接口获取Token
通过调用登录接口,获取JWT Token,例如:
curl --location --request POST 'http://localhost:8080/user/login' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=admin' \
--data-urlencode 'password=123456'
返回示例:
{
"code": 200,
"message": "登录成功",
"data": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlkIjoxLCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJleHAiOjE2MzE2MjU1MzF9.eD6m3uowKnl04go5xK2tYZTjZrmGHj-qK8vFv7BjOoY"
}
示例二:调用需要身份认证的接口
通过携带上文获得的JWT Token,访问需要身份认证的API接口,例如:
curl --location --request GET 'http://localhost:8080/user/info' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlkIjoxLCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJleHAiOjE2MzE2MjU1MzF9.eD6m3uowKnl04go5xK2tYZTjZrmGHj-qK8vFv7BjOoY'
这时候,如果JWT Token有效,接口将会返回用户信息。
以上就是“SpringBoot结合JWT登录权限控制的实现”的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot结合JWT登录权限控制的实现 - Python技术站