首页 > 解决方案 > 身份验证后请求其他服务时如何从 JWT 令牌获取用户名?

问题描述

我正在开发一个带有 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 类但获得空值。我怎样才能做到这一点?

标签: spring-bootauthenticationjwtnetflix-eurekanetflix-zuul

解决方案


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

我希望这有帮助。


推荐阅读