希望大家都做得很好!我正在春季启动中实施基于JWT角色的授权。
我已经能够实现它。我关注的教程是这个
https://github.com/only2dhir/spring-security-jwt
用户已成功注册。然后,我为该用户分配ADMIN之类的角色。
现在我有了这个api @GetMapping("/users")
应由ADMIN访问。但是,当我访问此api时,会出现此错误
java.lang.NullPointerException: Cannot invoke "Object.toString()" because the return value of
"io.jsonwebtoken.Claims.get(Object)" is null
此错误来自以下方法:
JwtTokenUtil:
public static final String AUTHORITIES_KEY = "scopes";
UsernamePasswordAuthenticationToken getAuthentication(final String token, final Authentication
exsitingAuth, final UserDetails userDetails){
final JwtParser jwtParser = Jwts.parser().setSigningKey(secret);
final Jws<Claims> claimsJws = jwtParser.parseClaimsJws(token);
final Claims claims = claimsJws.getBody();
final Collection<? extends GrantedAuthority> authorities=
java.util.Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
return new UsernamePasswordAuthenticationToken(userDetails, "", authorities);
}
此行显示错误
java.util.Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
创建身份验证:
UserDetailsWithToken UserDetailsWithToken = new UserDetailsWithToken();
authenticate(authenticationRequest.getEmpID(),
authenticationRequest.getPswd());
final UserDetails userDetails =
userDetailsService.loadUserByUsername(authenticationRequest.getEmpID());
final Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
authenticationRequest.getEmpID(),
authenticationRequest.getPswd()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
final String token =
jwtTokenUtil.generateToken(userDetails,authentication);
答案 0 :(得分:0)
我想您缺少添加权限的人。
在这里查看代码...。我回答了创建令牌的答案...
public String generateToken(UserDetails userDetails, Authentication
authentication) {
List<String> roles = user.getAuthorities()
.stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
return doGenerateToken(userDetails.getUsername(), roles);
}
另一种方法
public String doGenerateToken(String username, List<String> roles) {
try {
Claims claims = Jwts.claims().setSubject(username);
claims.put("username", roles);
claims.put(AUTHORITIES_KEY, username);
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 120000))
.signWith(SignatureAlgorithm.HS512, secret).compact();
.compact();
} catch (InvalidKeyException e) {
logger.error(e.getMessage(), e);
}
return "";
}
添加授权字符串并将其传递给doGenerateToken方法。
谢谢
Atul
答案 1 :(得分:0)
在您的代码中,您没有在jwt令牌中设置权限,请尝试设置它:
return doGenerateToken(authorities, userDetails.getUsername());
...
private String doGenerateToken(String authorities, String subject) {
return
Jwts.builder()
.claim(AUTHORITIES_KEY, authorities)
.setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 120000))
.signWith(SignatureAlgorithm.HS512, secret).compact();
}
确保正确创建身份验证
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken("username", "myPassword");
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication.getPrincipal(), authentication);