Skip to content

Commit 3bdb2e5

Browse files
authored
Merge pull request #18564 from Bipinkumar27/JAVA-46416
JAVA-46416: Changes made for restoring soap-keycloak code
2 parents c095eb9 + 4874161 commit 3bdb2e5

File tree

11 files changed

+533
-1
lines changed

11 files changed

+533
-1
lines changed

spring-boot-modules/spring-boot-keycloak-2/pom.xml

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,59 @@
7272
<version>${keycloak.version}</version>
7373
</dependency>
7474

75+
<dependency>
76+
<groupId>org.springframework.boot</groupId>
77+
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
78+
</dependency>
79+
<dependency>
80+
<groupId>org.springframework.boot</groupId>
81+
<artifactId>spring-boot-starter-data-jpa</artifactId>
82+
</dependency>
83+
<dependency>
84+
<groupId>org.springframework.boot</groupId>
85+
<artifactId>spring-boot-starter-test</artifactId>
86+
<scope>test</scope>
87+
</dependency>
88+
<dependency>
89+
<groupId>org.springframework.boot</groupId>
90+
<artifactId>spring-boot-starter-oauth2-client</artifactId>
91+
</dependency>
92+
<dependency>
93+
<groupId>org.springframework.boot</groupId>
94+
<artifactId>spring-boot-starter-security</artifactId>
95+
</dependency>
96+
<dependency>
97+
<groupId>org.springframework.boot</groupId>
98+
<artifactId>spring-boot-starter-web</artifactId>
99+
</dependency>
100+
<dependency>
101+
<groupId>org.hsqldb</groupId>
102+
<artifactId>hsqldb</artifactId>
103+
<scope>runtime</scope>
104+
</dependency>
105+
<dependency>
106+
<groupId>org.springframework.boot</groupId>
107+
<artifactId>spring-boot-starter-thymeleaf</artifactId>
108+
</dependency>
109+
<dependency>
110+
<groupId>wsdl4j</groupId>
111+
<artifactId>wsdl4j</artifactId>
112+
<version>${wsdl4j.version}</version>
113+
</dependency>
114+
<dependency>
115+
<groupId>org.springframework.boot</groupId>
116+
<artifactId>spring-boot-starter-web-services</artifactId>
117+
</dependency>
118+
<dependency>
119+
<groupId>org.springframework.security</groupId>
120+
<artifactId>spring-security-test</artifactId>
121+
<scope>test</scope>
122+
</dependency>
123+
<dependency>
124+
<groupId>org.glassfish.jaxb</groupId>
125+
<artifactId>jaxb-runtime</artifactId>
126+
<version>${jaxb-runtime.version}</version>
127+
</dependency>
75128
</dependencies>
76129

77130
<build>
@@ -80,12 +133,37 @@
80133
<groupId>org.springframework.boot</groupId>
81134
<artifactId>spring-boot-maven-plugin</artifactId>
82135
</plugin>
136+
<plugin>
137+
<groupId>org.codehaus.mojo</groupId>
138+
<artifactId>jaxb2-maven-plugin</artifactId>
139+
<version>${jaxb2-maven-plugin.version}</version>
140+
<executions>
141+
<execution>
142+
<id>xjc</id>
143+
<goals>
144+
<goal>xjc</goal>
145+
</goals>
146+
</execution>
147+
</executions>
148+
<configuration>
149+
<packageName>com.baeldung</packageName>
150+
<sources>
151+
<source>/${project.basedir}/src/main/resources/products.xsd</source>
152+
</sources>
153+
</configuration>
154+
</plugin>
83155
</plugins>
84156
</build>
85157

86158
<properties>
87159
<keycloak.version>21.0.1</keycloak.version>
88-
<start-class>com.baeldung.disablingkeycloak.App</start-class>
160+
<!--<start-class>com.baeldung.disablingkeycloak.App</start-class>-->
161+
<start-class>com.baeldung.keycloak.key.SpringBootKeycloakApp</start-class>
162+
<jaxb-runtime.version>4.0.0</jaxb-runtime.version>
163+
<wsdl4j.version>1.6.3</wsdl4j.version>
164+
<jaxb2-maven-plugin.version>3.1.0</jaxb2-maven-plugin.version>
165+
<maven.compiler.release>17</maven.compiler.release>
166+
<keycloak-adapter-bom.version>15.0.2</keycloak-adapter-bom.version>
89167
</properties>
90168

91169
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.baeldung.keycloak.keycloaksoap;
2+
3+
import java.util.Collection;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.stream.Collectors;
7+
8+
import org.springframework.core.convert.converter.Converter;
9+
import org.springframework.security.core.GrantedAuthority;
10+
import org.springframework.security.core.authority.SimpleGrantedAuthority;
11+
import org.springframework.security.oauth2.jwt.Jwt;
12+
13+
public class KeycloakRoleConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
14+
15+
private final String clientId;
16+
17+
public KeycloakRoleConverter(String clientId) {
18+
this.clientId = clientId;
19+
}
20+
21+
@Override
22+
@SuppressWarnings("unchecked")
23+
public Collection<GrantedAuthority> convert(Jwt jwt) {
24+
Map<String, Object> resourceAccess = jwt.getClaim("resource_access");
25+
26+
Map<String, Object> client = (Map<String, Object>) resourceAccess.get(clientId);
27+
List<String> roles = (List<String>) client.get("roles");
28+
29+
return roles.stream()
30+
.map(role -> new SimpleGrantedAuthority("ROLE_" + role))
31+
.collect(Collectors.toList());
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.baeldung.keycloak.keycloaksoap;
2+
3+
import org.springframework.beans.factory.annotation.Value;
4+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
8+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
10+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
11+
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
12+
import org.springframework.security.web.SecurityFilterChain;
13+
14+
@Configuration
15+
@EnableWebSecurity
16+
@ConditionalOnProperty(name = "keycloak.enabled", havingValue = "true")
17+
@EnableMethodSecurity(jsr250Enabled = true)
18+
public class KeycloakSecurityConfig {
19+
20+
@Value("${client.id}")
21+
private String clientId;
22+
23+
@Bean
24+
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
25+
http.csrf(AbstractHttpConfigurer::disable)
26+
.authorizeHttpRequests(auth -> auth.anyRequest()
27+
.authenticated())
28+
.oauth2ResourceServer(oauth2 -> oauth2
29+
.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter()))
30+
);
31+
return http.build();
32+
}
33+
34+
@Bean
35+
public JwtAuthenticationConverter jwtAuthenticationConverter() {
36+
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
37+
converter.setJwtGrantedAuthoritiesConverter(new KeycloakRoleConverter(clientId));
38+
return converter;
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.baeldung.keycloak.keycloaksoap;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
import org.springframework.core.env.Environment;
7+
8+
import jakarta.annotation.PostConstruct;
9+
10+
@SpringBootApplication
11+
public class KeycloakSoapServicesApplication {
12+
13+
@Autowired
14+
private Environment environment;
15+
16+
public static void main(String[] args) {
17+
SpringApplication application = new SpringApplication(KeycloakSoapServicesApplication.class);
18+
application.setAdditionalProfiles("keycloak");
19+
application.run(args);
20+
}
21+
22+
}
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.baeldung.keycloak.keycloaksoap;
2+
3+
import com.baeldung.DeleteProductRequest;
4+
import com.baeldung.DeleteProductResponse;
5+
import com.baeldung.GetProductDetailsRequest;
6+
import com.baeldung.GetProductDetailsResponse;
7+
import com.baeldung.Product;
8+
9+
import org.springframework.security.access.prepost.PreAuthorize;
10+
import org.springframework.ws.server.endpoint.annotation.Endpoint;
11+
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
12+
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
13+
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
14+
15+
import jakarta.annotation.security.RolesAllowed;
16+
import java.util.Map;
17+
18+
@Endpoint
19+
public class ProductsEndpoint {
20+
21+
private final Map<String, Product> productMap;
22+
23+
public ProductsEndpoint(Map<String, Product> productMap) {
24+
this.productMap = productMap;
25+
}
26+
27+
@RolesAllowed("user")
28+
@PayloadRoot(namespace = "http://www.baeldung.com/springbootsoap/keycloak", localPart = "getProductDetailsRequest")
29+
@ResponsePayload
30+
public GetProductDetailsResponse getProductDetails(@RequestPayload GetProductDetailsRequest request) {
31+
GetProductDetailsResponse response = new GetProductDetailsResponse();
32+
response.setProduct(productMap.get(request.getId()));
33+
return response;
34+
}
35+
36+
@RolesAllowed("admin")
37+
@PayloadRoot(namespace = "http://www.baeldung.com/springbootsoap/keycloak", localPart = "deleteProductRequest")
38+
@ResponsePayload
39+
public DeleteProductResponse deleteProduct(@RequestPayload DeleteProductRequest request) {
40+
DeleteProductResponse response = new DeleteProductResponse();
41+
response.setMessage("Success! Deleted the product with the id - "+request.getId());
42+
return response;
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.baeldung.keycloak.keycloaksoap;
2+
3+
import com.baeldung.Product;
4+
import org.springframework.beans.factory.annotation.Value;
5+
import org.springframework.boot.web.servlet.ServletRegistrationBean;
6+
import org.springframework.context.ApplicationContext;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.context.annotation.Configuration;
9+
import org.springframework.core.io.ClassPathResource;
10+
import org.springframework.ws.config.annotation.EnableWs;
11+
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
12+
import org.springframework.ws.transport.http.MessageDispatcherServlet;
13+
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
14+
import org.springframework.xml.xsd.SimpleXsdSchema;
15+
import org.springframework.xml.xsd.XsdSchema;
16+
17+
import java.util.HashMap;
18+
import java.util.Map;
19+
20+
@EnableWs
21+
@Configuration
22+
public class WebServiceConfig extends WsConfigurerAdapter {
23+
24+
@Value("${ws.api.path:/ws/api/v1/*}")
25+
private String webserviceApiPath;
26+
@Value("${ws.port.type.name:ProductsPort}")
27+
private String webservicePortTypeName;
28+
@Value("${ws.target.namespace:http://www.baeldung.com/springbootsoap/keycloak}")
29+
private String webserviceTargetNamespace;
30+
@Value("${ws.location.uri:http://localhost:18080/ws/api/v1/}")
31+
private String locationUri;
32+
33+
@Bean
34+
public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(ApplicationContext applicationContext) {
35+
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
36+
servlet.setApplicationContext(applicationContext);
37+
servlet.setTransformWsdlLocations(true);
38+
return new ServletRegistrationBean<>(servlet, webserviceApiPath);
39+
}
40+
41+
@Bean(name = "products")
42+
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema productsSchema) {
43+
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
44+
wsdl11Definition.setPortTypeName(webservicePortTypeName);
45+
wsdl11Definition.setTargetNamespace(webserviceTargetNamespace);
46+
wsdl11Definition.setLocationUri(locationUri);
47+
wsdl11Definition.setSchema(productsSchema);
48+
return wsdl11Definition;
49+
}
50+
51+
@Bean
52+
public XsdSchema productsSchema() {
53+
return new SimpleXsdSchema(new ClassPathResource("products.xsd"));
54+
}
55+
56+
@Bean
57+
public Map<String, Product> getProducts()
58+
{
59+
Map<String, Product> map = new HashMap<>();
60+
Product foldsack= new Product();
61+
foldsack.setId("1");
62+
foldsack.setName("Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops");
63+
foldsack.setDescription("Your perfect pack for everyday use and walks in the forest. ");
64+
65+
Product shirt= new Product();
66+
shirt.setId("2");
67+
shirt.setName("Mens Casual Premium Slim Fit T-Shirts");
68+
shirt.setDescription("Slim-fitting style, contrast raglan long sleeve, three-button henley placket.");
69+
70+
map.put("1", foldsack);
71+
map.put("2", shirt);
72+
return map;
73+
}
74+
75+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
server.port=18080
2+
3+
keycloak.enabled=true
4+
5+
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/realms/baeldung-soap-services
6+
7+
# Custom properties begin here
8+
ws.api.path=/ws/api/v1/*
9+
ws.port.type.name=ProductsPort
10+
ws.target.namespace=http://www.baeldung.com/springbootsoap/keycloak
11+
ws.location.uri=http://localhost:18080/ws/api/v1/
12+
13+
logging.level.root=DEBUG
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.baeldung.com/springbootsoap/keycloak"
3+
targetNamespace="http://www.baeldung.com/springbootsoap/keycloak" elementFormDefault="qualified">
4+
5+
<xs:element name="getProductDetailsRequest">
6+
<xs:complexType>
7+
<xs:sequence>
8+
<xs:element name="id" type="xs:string"/>
9+
</xs:sequence>
10+
</xs:complexType>
11+
</xs:element>
12+
<xs:element name="deleteProductRequest">
13+
<xs:complexType>
14+
<xs:sequence>
15+
<xs:element name="id" type="xs:string"/>
16+
</xs:sequence>
17+
</xs:complexType>
18+
</xs:element>
19+
<xs:element name="getProductDetailsResponse">
20+
<xs:complexType>
21+
<xs:sequence>
22+
<xs:element name="product" type="tns:product"/>
23+
</xs:sequence>
24+
</xs:complexType>
25+
</xs:element>
26+
<xs:element name="deleteProductResponse">
27+
<xs:complexType>
28+
<xs:sequence>
29+
<xs:element name="message" type="xs:string"/>
30+
</xs:sequence>
31+
</xs:complexType>
32+
</xs:element>
33+
34+
<!-- Define the complex object Product -->
35+
36+
<xs:complexType name="product">
37+
<xs:sequence>
38+
<xs:element name="id" type="xs:string"/>
39+
<xs:element name="name" type="xs:string"/>
40+
<xs:element name="description" type="xs:string"/>
41+
</xs:sequence>
42+
</xs:complexType>
43+
44+
45+
</xs:schema>

0 commit comments

Comments
 (0)