Почему Spring Boot возвращает 403 Forbidden для запроса POST к защищенной конечной точке даже с действительным JWT?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Почему Spring Boot возвращает 403 Forbidden для запроса POST к защищенной конечной точке даже с действительным JWT?

Сообщение Anonymous »

Я работаю над проектом Spring Boot, в котором реализую аутентификацию на основе JWT. У меня есть конечная точка /api/game/save, которая должна принимать запрос POST с действительным JWT. Несмотря на включение токена в заголовок авторизации, я продолжаю получать ответ 403 «Запрещено»:
Конфигурация безопасности:

Код: Выделить всё

package com.clicker.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/register", "/api/auth/login").permitAll()
.requestMatchers("/api/game/**").authenticated()
.anyRequest().authenticated());

http.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

return http.build();
}
}
Утилита JWT (JwtUtil):

Код: Выделить всё

package com.clicker.component;

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Date;

import static io.jsonwebtoken.Jwts.builder;

@Component
public class JwtUtil {

private static final String SECRET_KEY = "secret_key"; // Not my real secret key ofc
private static final long EXPIRATION_TIME = 1000 * 60 * 60; // 10 hours

public String generateToken(String username) {
return builder()
.setSubject(username)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}

public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}

public String extractUsername(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}
Конечная точка контроллера:

Код: Выделить всё

package com.clicker.controller;

import com.clicker.service.GameDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/game")
public class GameDataController {

@Autowired
private GameDataService gameDataService;

@PostMapping("/save")
public ResponseEntity saveGameData(@RequestHeader("Authorization") String token,
@RequestBody String gameDataJson) {
return gameDataService.saveGameData(token, gameDataJson);
}

@PostMapping("/load")
public ResponseEntity loadGameData(@RequestHeader("Authorization") String token) {
return gameDataService.loadGameData(token);
}
}

Сервис:

Код: Выделить всё

package com.clicker.service;

import com.clicker.component.JwtUtil;
import com.clicker.entity.GameData;
import com.clicker.entity.User;
import com.clicker.repository.GameDataRepository;
import com.clicker.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

@Service
public class GameDataService {

@Autowired
private GameDataRepository gameDataRepository;

@Autowired
private UserRepository userRepository;

@Autowired
private JwtUtil jwtUtil;

public ResponseEntity  saveGameData(String token, String gameDataJson) {

String username = jwtUtil.extractUsername(token.substring(7));
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new RuntimeException("User not found!"));

GameData gameData = gameDataRepository.findByUser(user)
.orElse(new GameData());

gameData.setUser(user);
gameData.setData(gameDataJson);
gameDataRepository.save(gameData);

return ResponseEntity.ok("Game data saved successfully!");
}

public ResponseEntity loadGameData(String token) {
String username = jwtUtil.extractUsername(token.substring(7));
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new RuntimeException("User not found!"));

return gameDataRepository.findByUser(user)
.map(gameData -> ResponseEntity.ok(gameData.getData()))
.orElse(ResponseEntity.ok("{\n" +
"    \"playerStats\": { \"solarEnergy\": 0, \"multiplyCostData\": 200, \"solarEnergyPerClick\": 1, \"solarEnergyPerSecond\": 0},\n" +
"    \"planets\": {\n" +
"        \"mercury\": { \"unlocked\": false, \"cost\": 500 },\n" +
"        \"venus\": { \"unlocked\": false, \"cost\": 2500 },\n" +
"        \"earth\": { \"unlocked\": false, \"cost\": 12500 },\n" +
"        \"moon\": { \"unlocked\": false, \"cost\": 62500 }\n" +
"    }\n" +
"}"));
}

public boolean validateToken(String token) {
return jwtUtil.validateToken(token);
}
}

Когда я отправляю запрос POST в /api/game/save с действительным токеном и телом, я получаю ответ 403 Forbidden.


Подробнее здесь: https://stackoverflow.com/questions/793 ... red-endpoi
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»