Резюме
Я работаю с Keycloak. все запросы "Get" работают нормально, т. е. @GetMapping ("/") в микросервисе ресурсов.
Но "@Postmapping (/ add)" не контролируется и пытается потреблять из дома. html или index. html, выпускной. 403 запрещено.
Фактическое поведение
Когда я пытался использовать проблему @PostMapping ("/ message"). 403 запрещено.
Ожидаемое поведение
Ожидаемое успешное сообщение @PostMapping ("/ message") и возвращаемое сообщение.
Конфигурация
В микросервисе ресурсов
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
http.authorizeRequests().anyRequest().authenticated();
http.headers().frameOptions().sameOrigin();
}
private JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(new KeycloakRealmRoleConverter());
return jwtAuthenticationConverter;
}
@Bean
public JwtDecoder jwtDecoderByIssuerUri(OAuth2ResourceServerProperties properties) {
String issuerUri = properties.getJwt().getIssuerUri();
NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromIssuerLocation(issuerUri);
jwtDecoder.setClaimSetConverter(new UsernameSubClaimAdapter());
return jwtDecoder;
}
}
class UsernameSubClaimAdapter implements Converter<Map<String, Object>, Map<String, Object>> {
private final MappedJwtClaimSetConverter delegate = MappedJwtClaimSetConverter.withDefaults(Collections.emptyMap());
@Override
public Map<String, Object> convert(Map<String, Object> claims) {
Map<String, Object> convertedClaims = this.delegate.convert(claims);
String username = (String) convertedClaims.get("preferred_username");
convertedClaims.put("sub", username);
return convertedClaims;
}
}
class KeycloakRealmRoleConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
@Override
@SuppressWarnings("unchecked")
public Collection<GrantedAuthority> convert(final Jwt jwt) {
final Map<String, Object> realmAccess = (Map<String, Object>) jwt.getClaims().get("realm_access");
return ((List<String>) realmAccess.get("roles")).stream()
.map(roleName -> "ROLE_" + roleName)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
}
В контроллере
@SpringBootApplication
@Controller
public class HotelsApplication {
public static void main(String[] args) {
SpringApplication.run(HotelsApplication.class, args);
}
@GetMapping("/whoami")
@ResponseBody
public Authentication whoami(Authentication auth) {
return auth;
}
/* newly added post method
* which is not working as expected , it sis ending up with error
* Failed to load resource: the server responded with a status of 403 (Forbidden)
*/
@PostMapping("/message")
public String createMessage(@RequestBody String message) {
return String.format("Message was created. Content: %s", message);
}
}
YML-файл
server:
port: 8081
spring:
application:
name: sample-service
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8090/auth/realms/spring-cloud-realm
Версия
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
<springBootVersion>2.2.4.RELEASE</springBootVersion>
Шлюз ServiceConfig
public class PbsiGatewayConfig {
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,
ReactiveClientRegistrationRepository clientRegistrationRepository) {
http.oauth2Login();
http.logout(logout -> logout.logoutSuccessHandler(new OidcClientInitiatedServerLogoutSuccessHandler(
clientRegistrationRepository)));
http.authorizeExchange().anyExchange().authenticated();
http.headers().frameOptions().mode(Mode.SAMEORIGIN);
// Disable CSRF in the gateway to prevent conflicts with proxied service CSRF
http.csrf().disable();
return http.build();
}
Заранее спасибо.