Commit c450151d authored by Christos Tranoris's avatar Christos Tranoris
Browse files

enabling oauth for client

parent 2f75885a
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
		</dependency>
		<dependency>
			<groupId>org.springframework.ai</groupId>
			<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
			<artifactId>spring-ai-starter-mcp-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.ai</groupId>
@@ -50,6 +50,15 @@
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<!-- security -->
		<dependency>
	        <groupId>org.springaicommunity</groupId>
	        <artifactId>mcp-client-security</artifactId>
        	<version>0.0.4</version>
	    </dependency>
        
        
	</dependencies>
	<dependencyManagement>
		<dependencies>
@@ -60,6 +69,10 @@
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			
			

		
		</dependencies>
	</dependencyManagement>

+50 −0
Original line number Diff line number Diff line
package org.etsi.osl.mcp.backend;

import io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequestCustomizer;
import org.springaicommunity.mcp.security.client.sync.AuthenticationMcpTransportContextProvider;
import org.springaicommunity.mcp.security.client.sync.oauth2.http.client.OAuth2AuthorizationCodeSyncHttpRequestCustomizer;

import org.springframework.ai.mcp.customizer.McpSyncClientCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;

/**
 * @author Daniel Garnier-Moiroux
 */
@Configuration
class McpConfiguration {

    @Bean
    McpSyncHttpClientRequestCustomizer requestCustomizer(OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager,
            ClientRegistrationRepository clientRegistrationRepository) {
        var registrationId = findUniqueClientRegistration(clientRegistrationRepository);
        return new OAuth2AuthorizationCodeSyncHttpRequestCustomizer(oAuth2AuthorizedClientManager, registrationId);
    }

    @Bean
    McpSyncClientCustomizer syncClientCustomizer() {
        return (name, syncSpec) -> syncSpec.transportContextProvider(new AuthenticationMcpTransportContextProvider());
    }

    /**
     * Returns the ID of the {@code spring.security.oauth2.client.registration}, if
     * unique.
     */
    private static String findUniqueClientRegistration(ClientRegistrationRepository clientRegistrationRepository) {
        String registrationId;
        if (!(clientRegistrationRepository instanceof InMemoryClientRegistrationRepository repo)) {
            throw new IllegalStateException("Expected an InMemoryClientRegistrationRepository");
        }
        var iterator = repo.iterator();
        var firstRegistration = iterator.next();
        if (iterator.hasNext()) {
            throw new IllegalStateException("Expected a single Client Registration");
        }
        registrationId = firstRegistration.getRegistrationId();
        return registrationId;
    }

}
 No newline at end of file
+25 −0
Original line number Diff line number Diff line
package org.etsi.osl.mcp.backend;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
@Profile("!testing")
public class WebSecurityConfigKeycloak {


  @Bean
  SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
      return http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
          .oauth2Client(Customizer.withDefaults())
          .csrf(CsrfConfigurer::disable)
          .build();
  }
}
+14 −1
Original line number Diff line number Diff line
@@ -10,7 +10,8 @@ spring:
      base-url: http://localhost:11434
      chat:
        options:
          model: gpt-oss:20b
          xmodel: gpt-oss:20b
          model: qwen3:8b
          temperature: 0.7
    mcp:
      client:
@@ -19,6 +20,18 @@ spring:
          connections:
            openslice-server:
              url: http://localhost:13015
  security:
    oauth2:
      client:
        registration:
          authserver:
            client-id: osapiWebClientId
            client-secret: secret
            authorization-grant-type: authorization_code
            provider: authserver
        provider:
          authserver:
            issuer-uri: http://keycloak:8080/auth/realms/openslice

logging:
  level: