Я хочу, чтобы определенная конечная точка /public/info была доступна без аутентификации.
Мое приложение.yaml
spring:
application:
name: team1
security:
oauth2:
client:
provider:
# provider name used for registration
demo:
# Keycloak realm URL: "{keycloak-url}/realms/{realm-name}"
issuer-uri:
registration:
# client-id from Keycloak client configuration
demo-client:
# provider from above
provider: demo
# client-id from Keycloak client configuration
client-id:
client-secret:
scope: openid
authorization-grant-type: authorization_code
redirect-uri:
server:
port: 8080
Моя конфигурация безопасности:
@Configuration
@EnableWebSecurity
class SecurityConfiguration{
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> {
authorize.requestMatchers("/public/info").permitAll();
authorize.anyRequest().authenticated();}
).oauth2Login(Customizer.withDefaults());
return http.build();
}
}
Разве /public/info не должен быть доступен без аутентификации? Меня всегда перенаправляют на keycloak.
Конечная точка /public/info:
@GetMapping(path = "/public/info")
public String hello() {
return "Hello";
}
Мой build.gradle - возможно, здесь может быть проблема с использованием неправильной версии.
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.0'
id 'io.spring.dependency-management' version '1.1.5'
}
group = 'at.ac.fhwn'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}




То, что вы показываете, верно. Должно быть, вы скрываете что-то, что ломает ваше приложение.
Хороший вопрос должен содержать:
DEBUG или TRACE журналы, показывающие проблемуПолное приложение (которое работает):
<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Configuration
@EnableWebSecurity
static class SecurityConfiguration {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorize -> {
authorize.requestMatchers("/public/info").permitAll();
authorize.anyRequest().authenticated();
}).oauth2Login(Customizer.withDefaults());
return http.build();
}
}
@RestController
static class PublicController {
@GetMapping(path = "/public/info")
public String hello() {
return "Hello";
}
}
@RestController
static class PrivateController {
@GetMapping(path = "/private/info")
public String hello(Authentication auth) {
return "Hello %s".formatted(auth.getName());
}
}
}
spring:
application:
name: demo
security:
oauth2:
client:
provider:
demo:
issuer-uri: https://oidc.c4-soft.com/auth/realms/quiz
registration:
demo-client:
provider: demo
client-id: change-me
client-secret: change-me
scope: openid
authorization-grant-type: authorization_code
server:
port: 8080
logging:
level:
root: INFO
org:
springframework:
security: DEBUG
boot: INFO
И прохождение интеграционных тестов показало, что все работает как положено:
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Login;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithAnonymousUser;
import org.springframework.test.web.servlet.MockMvc;
@SpringBootTest
@AutoConfigureMockMvc
class DemoApplicationTests {
@Autowired
MockMvc api;
@Test
@WithAnonymousUser
void givenRequestIsAnonymous_whenGetPublicInfo_thenOk() throws Exception {
api.perform(get("/public/info")).andExpect(status().isOk());
}
@Test
@WithAnonymousUser
void givenRequestIsAnonymous_whenGetPrivateInfo_thenRedirectToLogin() throws Exception {
api.perform(get("/private/info")).andExpect(status().is3xxRedirection());
}
@Test
void givenUserIsAuthenticated_whenGetPrivateInfo_thenOk() throws Exception {
api.perform(get("/private/info").with(oauth2Login())).andExpect(status().isOk());
}
}
Это может быть другая цепочка фильтров в конфигурации Java или отсутствие @RestController в классе, содержащем @GetMapping(path = "/public/info"), или что-то еще, чего я не вижу в вашем коде. Поскольку вы, похоже, не готовы поделиться воспроизводимым образцом, вам придется начать с того, что я предоставил, и постепенно изменять его.
Спасибо за ответ, это было почти полное моё приложение, в application.yaml больше не было конфигов. Я обновил свой вопрос с помощью build.gradle, возможно, есть проблема.