【发布时间】:2020-10-14 08:10:18
【问题描述】:
我在控制器中有如下方法
@GetMapping("/hello")
@PreAuthorize("hasRole('ADMIN')")
public String hello() {
return "Hello " + JWTRequestFilter.UserClaim;
}
当具有ADMIN 角色的用户尝试访问/hello 时,将返回403。我在 websecurity 类中启用了以下功能。
@EnableGlobalMethodSecurity(prePostEnabled = true)
下面是 JWT 令牌。
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzZW50aHVyYW4iLCJSb2xlcyI6WyJBRE1JTiIsIlVTRVIiXSwiZXhwIjoxNTkzMDE0NDE5LCJpYXQiOjE1OTI5Nzg0MTl9.-7lTav3Nux8WVafUBGXjOxtXcE-r0fpfjb7wM7hrg6w
即使 JWT 令牌具有角色,但我仍然得到 403。此预授权注释是从 JWT 中看到角色还是进行数据库调用并检查用户的角色。即使我使用了 @987654327 @ 注释,但仍然得到相同的行为。如何解决这个403。下面我附上了JWTRequestFilter类。
public class JWTRequestFilter extends OncePerRequestFilter {
@Autowired
private MyUserDetailService userDetailService;
@Autowired
private JWTUtil jwtUtil;
public static String UserClaim = "";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if(authorizationHeader != null && authorizationHeader.startsWith("Bearer ")){
jwt = authorizationHeader.substring(7);
username = jwtUtil.extractUsername(jwt);
UserClaim = username;
}
if(username != null && SecurityContextHolder.getContext().getAuthentication() == null){
UserDetails userDetails= this.userDetailService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
这就是我生成 JWT 令牌和设置角色的方式。
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
Set<String> Userroles = new HashSet<>();
User user = userRepository.findByUsername(userDetails.getUsername());
for(Role role:user.getRoles()){
Userroles.add(role.getName());
}
claims.put("Roles",Userroles.toArray());
return createToken(claims, userDetails.getUsername());
}
【问题讨论】:
-
您是否将您的角色 JWT 设置为您的安全上下文声明?
-
@KavithakaranKanapathippillai 我已附加 JWTRequestFilter 类
-
@YogeshPrajapati 我需要知道 preAuthorize 是检查 JWT 还是从数据库检查用户是否具有特定角色。
-
@YogeshPrajapati 我附上了我如何生成令牌的代码。
-
试试@PreAuthorize("hasRole('ROLE_ADMIN')") 就像在这个baeldung.com/spring-security-expressions-basic
标签: spring-boot authentication spring-security jwt authorization