From ec6917145853a99ed28934001dad63d0ec1e23d5 Mon Sep 17 00:00:00 2001 From: killerber4t Date: Tue, 3 Mar 2020 16:44:05 +0100 Subject: [PATCH 1/6] add keycloak --- build.gradle | 2 + .../java/mops/gruppen2/KeycloakConfig.java | 18 +++++ .../java/mops/gruppen2/SecurityConfig.java | 81 +++++++++++++++++++ src/main/resources/application.properties | 7 ++ 4 files changed, 108 insertions(+) create mode 100644 src/main/java/mops/gruppen2/KeycloakConfig.java create mode 100644 src/main/java/mops/gruppen2/SecurityConfig.java diff --git a/build.gradle b/build.gradle index b44d451..1faa99c 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.keycloak:keycloak-spring-boot-starter:9.0.0' + implementation 'org.keycloak.bom:keycloak-adapter-bom:3.3.0.Final' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' diff --git a/src/main/java/mops/gruppen2/KeycloakConfig.java b/src/main/java/mops/gruppen2/KeycloakConfig.java new file mode 100644 index 0000000..b528805 --- /dev/null +++ b/src/main/java/mops/gruppen2/KeycloakConfig.java @@ -0,0 +1,18 @@ +package mops.gruppen2; + +import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * WORKAROUND for https://issues.redhat.com/browse/KEYCLOAK-11282 + * Bean should move into {@link SecurityConfig} once Bug has been resolved + */ + +@Configuration +public class KeycloakConfig { + @Bean + public KeycloakSpringBootConfigResolver KeycloakConfigResolver() { + return new KeycloakSpringBootConfigResolver(); + } +} \ No newline at end of file diff --git a/src/main/java/mops/gruppen2/SecurityConfig.java b/src/main/java/mops/gruppen2/SecurityConfig.java new file mode 100644 index 0000000..bffa0b2 --- /dev/null +++ b/src/main/java/mops/gruppen2/SecurityConfig.java @@ -0,0 +1,81 @@ +package mops.gruppen2; + +import org.keycloak.KeycloakPrincipal; +import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents; +import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; +import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; +import org.keycloak.representations.AccessToken; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.*; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; +import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; +import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; + +@Configuration +@EnableWebSecurity +@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) +class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) { + KeycloakAuthenticationProvider keycloakAuthenticationProvider + = keycloakAuthenticationProvider(); + keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); + auth.authenticationProvider(keycloakAuthenticationProvider); + } + + @Bean + @Override + protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { + return new RegisterSessionAuthenticationStrategy( + new SessionRegistryImpl()); + } + + @Bean + @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, + proxyMode = ScopedProxyMode.TARGET_CLASS) + public AccessToken getAccessToken() { + HttpServletRequest request = + ((ServletRequestAttributes) RequestContextHolder + .currentRequestAttributes()).getRequest(); + return ((KeycloakPrincipal) request.getUserPrincipal()) + .getKeycloakSecurityContext().getToken(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + super.configure(http); + http.authorizeRequests() + .antMatchers("/actuator/**") + .hasRole("monitoring") + .anyRequest() + .permitAll(); + } + + /** + * Declaring this class enables us to use the Spring specific + * {@link org.springframework.security.access.annotation.Secured} annotation + * or the JSR-250 Java Standard + * {@link javax.annotation.security.RolesAllowed} annotation + * for Role-based authorization + */ + @Configuration + @EnableGlobalMethodSecurity( + prePostEnabled = true, + securedEnabled = true, + jsr250Enabled = true) + public static class MethodSecurityConfig + extends GlobalMethodSecurityConfiguration { + } +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 78366c4..34d7960 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,3 +8,10 @@ spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=root spring.datasource.password=geheim spring.jpa.database-platform=org.hibernate.dialect.H2Dialect + + +keycloak.principal-attribute=preferred_username +keycloak.auth-server-url=https://keycloak.cs.hhu.de/auth +keycloak.realm=MOPS +keycloak.resource=demo +keycloak.public-client=true From ffabc5ce53aada376274c6b517a7bc777ff1bb6a Mon Sep 17 00:00:00 2001 From: killerber4t Date: Wed, 4 Mar 2020 13:42:45 +0100 Subject: [PATCH 2/6] add swagger-API and example controller --- build.gradle | 15 ++++++++++++ .../mops/gruppen2/Gruppen2Application.java | 12 ++++++++++ .../controllers/SwaggerAPIController.java | 24 +++++++++++++++++++ src/main/resources/application.properties | 6 +++++ 4 files changed, 57 insertions(+) create mode 100644 src/main/java/mops/gruppen2/controllers/SwaggerAPIController.java diff --git a/build.gradle b/build.gradle index 1faa99c..a6e65a3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,5 @@ +import com.github.spotbugs.SpotBugsTask + plugins { id 'org.springframework.boot' version '2.2.5.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE' @@ -11,7 +13,12 @@ spotbugs{ reportLevel = "high" toolVersion = '4.0.0-RC1' } +<<<<<<< Updated upstream tasks.withType(com.github.spotbugs.SpotBugsTask) { +======= + +tasks.withType(SpotBugsTask) { +>>>>>>> Stashed changes reports { html { enabled = true @@ -52,8 +59,14 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' +<<<<<<< Updated upstream implementation 'org.keycloak:keycloak-spring-boot-starter:9.0.0' implementation 'org.keycloak.bom:keycloak-adapter-bom:3.3.0.Final' +======= + implementation 'mops:styleguide:2.0.0' + compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.7.0' + compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.7.0' +>>>>>>> Stashed changes compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' @@ -62,8 +75,10 @@ dependencies { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } testImplementation 'org.springframework.security:spring-security-test' + compile('org.springframework.boot:spring-boot-starter-web') } test { useJUnitPlatform() } + diff --git a/src/main/java/mops/gruppen2/Gruppen2Application.java b/src/main/java/mops/gruppen2/Gruppen2Application.java index 91f1872..2e7599a 100644 --- a/src/main/java/mops/gruppen2/Gruppen2Application.java +++ b/src/main/java/mops/gruppen2/Gruppen2Application.java @@ -2,10 +2,22 @@ package mops.gruppen2; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; @SpringBootApplication +@EnableSwagger2 public class Gruppen2Application { public static void main(String[] args) { SpringApplication.run(Gruppen2Application.class, args); } + + @Bean + public Docket productAPI(){ + return new Docket(DocumentationType.SWAGGER_2).select() + .apis(RequestHandlerSelectors.basePackage("mops.gruppen2")).build(); + } } diff --git a/src/main/java/mops/gruppen2/controllers/SwaggerAPIController.java b/src/main/java/mops/gruppen2/controllers/SwaggerAPIController.java new file mode 100644 index 0000000..6811f25 --- /dev/null +++ b/src/main/java/mops/gruppen2/controllers/SwaggerAPIController.java @@ -0,0 +1,24 @@ +package mops.gruppen2.controllers; + + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +@RestController +public class SwaggerAPIController { + @RequestMapping(value = "/products", method = RequestMethod.GET) + public List getProducts(){ + List productList = new ArrayList<>(); + productList.add("Honey"); + productList.add("Almond"); + return productList; + } + @RequestMapping(value = "/products", method = RequestMethod.POST) + public String createProduct() { + return "Product is saved successfully"; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 34d7960..25ca83c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -9,9 +9,15 @@ spring.datasource.username=root spring.datasource.password=geheim spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +<<<<<<< Updated upstream keycloak.principal-attribute=preferred_username keycloak.auth-server-url=https://keycloak.cs.hhu.de/auth keycloak.realm=MOPS keycloak.resource=demo keycloak.public-client=true +======= +spring.security.user.name=root +spring.security.user.password=1234 +spring.security.user.roles=ADMIN +>>>>>>> Stashed changes From 89196b738ac7c7dc34b99d38fd7a75e6152d6c3a Mon Sep 17 00:00:00 2001 From: killerber4t Date: Wed, 4 Mar 2020 13:44:27 +0100 Subject: [PATCH 3/6] fix conflicts --- build.gradle | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index a6e65a3..daab77f 100644 --- a/build.gradle +++ b/build.gradle @@ -13,12 +13,9 @@ spotbugs{ reportLevel = "high" toolVersion = '4.0.0-RC1' } -<<<<<<< Updated upstream -tasks.withType(com.github.spotbugs.SpotBugsTask) { -======= + tasks.withType(SpotBugsTask) { ->>>>>>> Stashed changes reports { html { enabled = true @@ -59,14 +56,9 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' -<<<<<<< Updated upstream - implementation 'org.keycloak:keycloak-spring-boot-starter:9.0.0' - implementation 'org.keycloak.bom:keycloak-adapter-bom:3.3.0.Final' -======= implementation 'mops:styleguide:2.0.0' compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.7.0' compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.7.0' ->>>>>>> Stashed changes compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' From 13401df0ac256b7d5c750e5930dea3429098f466 Mon Sep 17 00:00:00 2001 From: killerber4t Date: Wed, 4 Mar 2020 13:45:36 +0100 Subject: [PATCH 4/6] fix more conflicts --- src/main/resources/application.properties | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 25ca83c..55b3f4a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -9,15 +9,7 @@ spring.datasource.username=root spring.datasource.password=geheim spring.jpa.database-platform=org.hibernate.dialect.H2Dialect -<<<<<<< Updated upstream -keycloak.principal-attribute=preferred_username -keycloak.auth-server-url=https://keycloak.cs.hhu.de/auth -keycloak.realm=MOPS -keycloak.resource=demo -keycloak.public-client=true -======= spring.security.user.name=root spring.security.user.password=1234 spring.security.user.roles=ADMIN ->>>>>>> Stashed changes From e1ad60ef0b710934f151341d6959848fdba266cb Mon Sep 17 00:00:00 2001 From: killerber4t <49568605+killerber4t@users.noreply.github.com> Date: Wed, 4 Mar 2020 14:11:51 +0100 Subject: [PATCH 5/6] Delete KeycloakConfig.java --- .../java/mops/gruppen2/KeycloakConfig.java | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 src/main/java/mops/gruppen2/KeycloakConfig.java diff --git a/src/main/java/mops/gruppen2/KeycloakConfig.java b/src/main/java/mops/gruppen2/KeycloakConfig.java deleted file mode 100644 index b528805..0000000 --- a/src/main/java/mops/gruppen2/KeycloakConfig.java +++ /dev/null @@ -1,18 +0,0 @@ -package mops.gruppen2; - -import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * WORKAROUND for https://issues.redhat.com/browse/KEYCLOAK-11282 - * Bean should move into {@link SecurityConfig} once Bug has been resolved - */ - -@Configuration -public class KeycloakConfig { - @Bean - public KeycloakSpringBootConfigResolver KeycloakConfigResolver() { - return new KeycloakSpringBootConfigResolver(); - } -} \ No newline at end of file From 3ce45523ba7535c1063a706cb32f489395f29994 Mon Sep 17 00:00:00 2001 From: killerber4t <49568605+killerber4t@users.noreply.github.com> Date: Wed, 4 Mar 2020 14:12:45 +0100 Subject: [PATCH 6/6] Delete SecurityConfig.java --- .../java/mops/gruppen2/SecurityConfig.java | 81 ------------------- 1 file changed, 81 deletions(-) delete mode 100644 src/main/java/mops/gruppen2/SecurityConfig.java diff --git a/src/main/java/mops/gruppen2/SecurityConfig.java b/src/main/java/mops/gruppen2/SecurityConfig.java deleted file mode 100644 index bffa0b2..0000000 --- a/src/main/java/mops/gruppen2/SecurityConfig.java +++ /dev/null @@ -1,81 +0,0 @@ -package mops.gruppen2; - -import org.keycloak.KeycloakPrincipal; -import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents; -import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; -import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; -import org.keycloak.representations.AccessToken; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.*; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; -import org.springframework.security.core.session.SessionRegistryImpl; -import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; -import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import javax.servlet.http.HttpServletRequest; - -@Configuration -@EnableWebSecurity -@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) -class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) { - KeycloakAuthenticationProvider keycloakAuthenticationProvider - = keycloakAuthenticationProvider(); - keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); - auth.authenticationProvider(keycloakAuthenticationProvider); - } - - @Bean - @Override - protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { - return new RegisterSessionAuthenticationStrategy( - new SessionRegistryImpl()); - } - - @Bean - @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, - proxyMode = ScopedProxyMode.TARGET_CLASS) - public AccessToken getAccessToken() { - HttpServletRequest request = - ((ServletRequestAttributes) RequestContextHolder - .currentRequestAttributes()).getRequest(); - return ((KeycloakPrincipal) request.getUserPrincipal()) - .getKeycloakSecurityContext().getToken(); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - super.configure(http); - http.authorizeRequests() - .antMatchers("/actuator/**") - .hasRole("monitoring") - .anyRequest() - .permitAll(); - } - - /** - * Declaring this class enables us to use the Spring specific - * {@link org.springframework.security.access.annotation.Secured} annotation - * or the JSR-250 Java Standard - * {@link javax.annotation.security.RolesAllowed} annotation - * for Role-based authorization - */ - @Configuration - @EnableGlobalMethodSecurity( - prePostEnabled = true, - securedEnabled = true, - jsr250Enabled = true) - public static class MethodSecurityConfig - extends GlobalMethodSecurityConfiguration { - } -} \ No newline at end of file