为什么在 Java Spring Boot 中调用我的微服务会返回 403 Forbidden?

问题描述 投票:0回答:1

我正在将

SpringBoot
Eureka
服务器一起使用。我有一个用户
microservice
、一个
eureka server
和一个
springcloud apigateway
文件夹。 这里是完整的源代码

在我的

users microservice's controller
中,我有以下代码

@RestController
@RequestMapping("/users")
public class UsersController {

    @Autowired
    private Environment env;

    @Autowired
    UsersService usersService;

    @GetMapping("/status/check")
    public String status(){
        System.out.println("hereeeeeeeeeee");
        return "Working "+env.getProperty("local.server.port");
    }

    @PostMapping
    public ResponseEntity<CreateUserResponseModel> createUser(@Valid @RequestBody CreateUserRequestModel userDetails) {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        UserDto userDto = modelMapper.map(userDetails, UserDto.class);
        UserDto createdUser = usersService.createUser(userDto);
        CreateUserResponseModel body = modelMapper.map(createdUser, CreateUserResponseModel.class);
        return  ResponseEntity.status(HttpStatus.CREATED).body(body);
    }
    
}

现在 Get api 端点返回 403 Forbidden ,post 端点工作正常

以下是错误截图

enter image description here

我在

AuthorizationHeaderFilter
中定义了
apigateway
类,用于解码
jwt
,我在 GET Api 端点中发送该类,它可以正确解码
JWT

@Component
public class AuthorizationHeaderFilter extends AbstractGatewayFilterFactory<AuthorizationHeaderFilter.Config>{

    @Autowired
    private Environment environment;

    public AuthorizationHeaderFilter(){
        super(Config.class);
    }

    public static class Config{

    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange,chain)->{
            ServerHttpRequest request = exchange.getRequest();
            if(!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)){
                return onError(exchange,"No authorization header",HttpStatus.UNAUTHORIZED);
            }
            String authorizationHeader = request.getHeaders().get(HttpHeaders.AUTHORIZATION).get(0);
            String jwt = authorizationHeader.replace("Bearer ", ""); //Make sure you add space
            if(!isJwtValid(jwt)){
                return onError(exchange, "Jwt token is invalid",HttpStatus.UNAUTHORIZED);
            }
            return chain.filter(exchange);
        };
    }

    private Mono<Void> onError(ServerWebExchange exchange,String err,HttpStatus httpStatus){
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(httpStatus);
        return response.setComplete();
    }

    private boolean isJwtValid(String jwt){
        System.out.println("1");
        boolean isValid = false;
        String subject = null;
        String tokenSecret = environment.getProperty("token.secret");
        System.out.println("2 "+tokenSecret);
        SecretKey secretKey = Keys.hmacShaKeyFor(tokenSecret.getBytes());

        JwtParser jwtParser = Jwts.parser().verifyWith(secretKey).build();
        try{
            // Jwt<Header,Claims> parsedToken = jwtParser.parse(jwt);
            subject = jwtParser.parseSignedClaims(jwt).getPayload().get("userId").toString();
            System.out.println("3 "+subject);
        } catch(Exception ex){
            isValid = false;
            System.out.println("4 "+ex.getLocalizedMessage());
        }

        if(subject == null || subject.isEmpty()){
            isValid = false;
        } else {
            isValid = true;
        }
        System.out.println("5 ");
        return isValid;
    }

  
}

这是我的

application.properties
apigateway

spring.application.name=api-gateway
server.port=8082
eureka.client.service-url.defaultZone=http://localhost:8010/eureka

spring.cloud.gateway.routes[0].id=users-status-check
spring.cloud.gateway.routes[0].uri=lb://users-ws
spring.cloud.gateway.routes[0].predicates[0]=Path=/users-ws/users/status/check
spring.cloud.gateway.routes[0].predicates[1]=Method=GET
spring.cloud.gateway.routes[0].predicates[2]=Header=Authorization, Bearer (.*)
spring.cloud.gateway.routes[0].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[0].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}
spring.cloud.gateway.routes[0].filters[2]=AuthorizationHeaderFilter

spring.cloud.gateway.routes[1].id=users-ws
spring.cloud.gateway.routes[1].uri=lb://users-ws
spring.cloud.gateway.routes[1].predicates[0]=Path=/users-ws/users
spring.cloud.gateway.routes[1].predicates[1]=Method=POST
spring.cloud.gateway.routes[1].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[1].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}

spring.cloud.gateway.routes[2].id=users-ws-h2-console
spring.cloud.gateway.routes[2].uri=lb://users-ws
spring.cloud.gateway.routes[2].predicates[0]=Path=/users-ws/h2-console
spring.cloud.gateway.routes[2].predicates[1]=Method=GET
spring.cloud.gateway.routes[2].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[2].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}

spring.cloud.gateway.routes[3].id=users-ws-login
spring.cloud.gateway.routes[3].uri=lb://users-ws
spring.cloud.gateway.routes[3].predicates[0]=Path=/users-ws/users/login
spring.cloud.gateway.routes[3].predicates[1]=Method=POST
spring.cloud.gateway.routes[3].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[3].filters[1]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}

spring.cloud.gateway.routes[4].id=users-ws-get-update-delete
spring.cloud.gateway.routes[4].uri=lb://users-ws
spring.cloud.gateway.routes[4].predicates[0]=Path=/users-ws/users/**
spring.cloud.gateway.routes[4].predicates[1]=Method=GET,PUT,DELETE
spring.cloud.gateway.routes[4].predicates[2]=Header=Authorization, Bearer (.*)
spring.cloud.gateway.routes[4].filters[0]=RemoveRequestHeader=Cookie
spring.cloud.gateway.routes[4].filters[1]=AuthorizationHeaderFilter
spring.cloud.gateway.routes[4].filters[2]=RewritePath=/users-ws/(?<segment>.*), /$\{segment}

token.secret=1aBcD3eF4gH5iJ6kL7mN8oP9qRsTuVwXyZ0A1bCdEfG2hI3jK4lM5nO6pQ7rStU8vW9xYz
java spring-boot microservices spring-cloud netflix-eureka
1个回答
0
投票

使用@ResponseBody注释控制器中的方法。

@GetMapping("/status/check")
@ResponseBody
public String status()
{
    System.out.println("hereeeeeeeeeee");
    return "Working "+env.getProperty("local.server.port");
}
© www.soinside.com 2019 - 2024. All rights reserved.