Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何模拟JWT.decode?_Java_Spring Boot_Junit_Mockito - Fatal编程技术网

Java 如何模拟JWT.decode?

Java 如何模拟JWT.decode?,java,spring-boot,junit,mockito,Java,Spring Boot,Junit,Mockito,我在我的Spring boot应用程序中使用这个库 <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.9.0</version> </dependency> 您可以使用不同的策略/选项,所有这些都将起作用: 根本不要嘲笑JWT.decode,将其视为应该在测试中运行

我在我的Spring boot应用程序中使用这个库

<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>3.9.0</version>
</dependency>

您可以使用不同的策略/选项,所有这些都将起作用:

  • 根本不要嘲笑JWT.decode,将其视为应该在测试中运行的实用方法。它背后的直觉是,如果你的类使用
    Math.max(a,b)
    code或者一些日期时间操作,比如
    DateTime.of(…)
    ,你会在测试中模拟它吗?可能不是。。。虽然在这种情况下,您可能需要在测试中使用真正可解码的令牌

  • 使用PowerMockito模拟静态调用(我并不推荐这种方式,但如果您不想更改代码,它可以完成这项工作)

  • 执行重构,将解码功能提取到接口,并将其用作过滤器中的依赖项:


  • 使用这种方法,您可以轻松地用mockito模拟
    JwtDecoder

    谢谢。我想知道我怎么会嘲笑这个
    DecodedJWT
    类的结果
    @Component
    public class JwtAuthenticationFilter extends OncePerRequestFilter {
    
        @Value("${clientid}")
        private String clientid;
    
        @Autowired
        private AuthenticationService authenticationService;
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException, InvalidRoleException {
    
            getJwtFromRequest(request, response, filterChain);
        }
    
        private void getJwtFromRequest(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
                String bearerToken = request.getHeader("Authorization");
    
                if (!StringUtils.hasText(bearerToken) || !bearerToken.startsWith("Bearer ")) {
                    throw new AccessTokenMissingException("No access token found in request headers.");
                }
    
                try {
                    String accessToken = bearerToken.substring(7);
    
                    // this will also throw error when unable to reach auth server
                    ResponseEntity<String> result = authenticationService.getUserInfo(accessToken);
    
                    // Invalid access token
                    if (!result.getStatusCode().is2xxSuccessful()) {
                        throw new InvalidAccessTokenException("Invalid access token.");
                    }
    
                    DecodedJWT jwt = JWT.decode(accessToken);
    
                    String username = jwt.getClaim("preferred_username").asString();
                    Map<String, Object> resources = jwt.getClaim("resource_access").asMap();
    
                    Object roles = ((Map<String, Object>) resources.get(clientid)).get("roles");
    
                    List<String> rolesList = (ArrayList<String>)roles;
    
                    UserInfo user = new UserInfo();
                    user.setUsername(username);
                    user.setRole(rolesList);
    
                    // Step 3: Set username to security context
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                            user.getUsername(), null, AuthUtil.getAuthRole(user.getRole()));
    
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
    
                } catch (HttpClientErrorException.Unauthorized | JWTDecodeException e) {
                    throw new InvalidAccessTokenException("Invalid access token.");
                }
    
            filterChain.doFilter(request, response);
        }
    }
    
    public interface JWTDecoder {
       DecodedJWT decode(String token); // I assume its string for simplicity
    }
    
    @Component
    public class StdJWTDecoder implements JWTDecoder {
       public DecodedJWT decode(String token) {
           return JWT.decode(tokent);
    }
    
    public class JwtAuthenticationFilter ... {
       private final JWTDecoder jwtDecoder;
    
       public JwtAuthenticationFilter(JWTDecoder jwtDecoder) {
           this.jwtDecoder = jwtDecoder;
       }
    
        ....
       private void getJwtFromRequest(HttpServletRequest request, HttpServletResponse 
         response, FilterChain filterChain)  {
          ...
          // instead of:
          DecodedJWT jwt = JWT.decode(accessToken);  
          // use this:
          DecodedJWT jwt = jwtDecoder.decode(accessToken);
          ...
       }
    
    }