身份验证后请求其他服务时如何从 JWT 令牌获取用户名?

Posted

技术标签:

【中文标题】身份验证后请求其他服务时如何从 JWT 令牌获取用户名?【英文标题】:How to get username from JWT token while requesting for another service after authentication? 【发布时间】:2019-07-01 10:33:06 【问题描述】:

我正在开发一个带有 angular6 前端的 Spring Boot 应用程序,并使用 Eureka 进行服务注册,使用 zuul 进行身份验证网关,两者都作为单独的服务。我正在使用 jwt 进行身份验证。

当我使用具有值 jwt 令牌的授权标头访问 url localhost:8080/dis/academics/complaint/getMyComplaints 时,它会转到网关服务,然后网关在网关进行有效身份验证后将其转发给学术服务。

现在我想从学术服务中的令牌中获取用户名。我怎样才能得到它?

网关服务中的控制器

@RestController
@RequestMapping("/dis")
public class AuthRestAPIs 

@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginForm loginRequest) 

    Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));

    SecurityContextHolder.getContext().setAuthentication(authentication);

    String jwt = jwtProvider.generateJwtToken(authentication);
    //UserDetails userDetails = (UserDetails) authentication.getPrincipal();
    UserPrinciple userPrincipal = (UserPrinciple) authentication.getPrincipal();
    return ResponseEntity.ok(new JwtResponse(jwt, userPrincipal.getUsername(), userPrincipal.getUserType(), userPrincipal.getAuthorities()));

 

学术服务负责人

@RestController
@RequestMapping("/complaint") 
public class ComplaintsController 
@RequestMapping(value = "/getMyComplaints", method = RequestMethod.GET)
public <T, U> Object[]  getMyComplaints(Authentication authentication)

    String username = authentication.getName();

    //System.out.println(username);

    String user_type = "student";

    List<Object> complaints = new ArrayList<>();

    if(user_type.equals("student"))
    
        Collections.addAll(complaints, cleanlinessComplaintRepository.findByCreatedBy(username));
        Collections.addAll(complaints, leComplaintRepository.findByCreatedBy(username));
        Collections.addAll(complaints, facultyComplaintRepository.findByCreatedBy(username));
        Collections.addAll(complaints, otherComplaintRepository.findByCreatedBy(username));
    

    return complaints.toArray();


我尝试过使用 Authentication 类,但得到了 null 值。我怎样才能做到这一点?

【问题讨论】:

可以添加生成的 jwt 令牌吗? 当您登录时存储详细信息(jwt 令牌)以及其他详细信息,例如用户名和您在会话存储中获得的任何数据。并从您想要的任何地方的会话存储中获取该数据。 第一个请求,客户端发送 id/passcode 交换 id/pass 以获得唯一令牌 在每个后续请求上验证令牌直到它过期是非常标准的 @kumar 我不想使用会话存储,我所做的是在身份验证之后,在每个请求中发送令牌,并且这个令牌在网关处得到解析,所以我应该如何在另一个处获取这个令牌服务? 检查这个:***.com/questions/52624699/… 【参考方案1】:

Zuul 默认不转发你的 Authorization 标头。您必须在 zuul 中显式配置才能做到这一点。 您的服务必须在不同的服务器上。 您必须更改 zuul 属性中的敏感标头设置(可能是 application.yml)。默认情况下,它采用以下输入。

zuul:
  routes:
    users:
      path: /myusers/**
      sensitiveHeaders: Cookie,Set-Cookie,Authorization
      url: https://downstream

如果您非常确定在所有服务中转发您的标头,那么只需将其更改为

zuul:
  routes:
    users:
      path: /myusers/**
      sensitiveHeaders:
      url: https://downstream

我希望这会有所帮助。

【讨论】:

以上是关于身份验证后请求其他服务时如何从 JWT 令牌获取用户名?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Rails 和 React 时如何在标头中获取 JWT 令牌

如何在 graphql 中为基于 jwt 的身份验证实现自动刷新令牌?

如何验证请求标头、JWT 令牌

JWT 签名验证

使用 React 处理 JWT 身份验证

JWT 身份验证 - 为新注册的用户请求令牌时遇到问题