diff --git a/oauth-jwt/jwt-auth-server/pom.xml b/oauth-jwt/jwt-auth-server/pom.xml index cb9f98c05..18a441c5b 100644 --- a/oauth-jwt/jwt-auth-server/pom.xml +++ b/oauth-jwt/jwt-auth-server/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.6.7 + 3.1.1 @@ -35,12 +35,12 @@ runtime - - org.jboss.resteasy - resteasy-jackson2-provider - ${resteasy.version} - - + + org.jboss.resteasy + resteasy-jackson2-provider + ${resteasy.version} + + org.keycloak keycloak-dependencies-server-all ${keycloak.version} @@ -127,12 +127,12 @@ UTF-8 - 13 - 18.0.0 + 17 + 22.0.0 13.0.8.Final - 3.15.1.Final + 6.2.4.Final \ No newline at end of file diff --git a/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/EmbeddedKeycloakConfig.java b/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/EmbeddedKeycloakConfig.java index e34602fe1..8a764d105 100644 --- a/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/EmbeddedKeycloakConfig.java +++ b/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/EmbeddedKeycloakConfig.java @@ -52,7 +52,7 @@ FilterRegistrationBean keycloakSessionManagement( } private void mockJndiEnvironment(DataSource dataSource) throws NamingException { - NamingManager.setInitialContextFactoryBuilder((env) -> (environment) -> new InitialContext() { + NamingManager.setInitialContextFactoryBuilder(env -> environment -> new InitialContext() { @Override public Object lookup(Name name) { diff --git a/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/EmbeddedKeycloakRequestFilter.java b/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/EmbeddedKeycloakRequestFilter.java index 913a80751..a63b4f341 100644 --- a/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/EmbeddedKeycloakRequestFilter.java +++ b/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/EmbeddedKeycloakRequestFilter.java @@ -2,11 +2,11 @@ import java.io.UnsupportedEncodingException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import org.keycloak.common.ClientConnection; import org.keycloak.services.filters.AbstractRequestFilter; @@ -18,7 +18,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo servletRequest.setCharacterEncoding("UTF-8"); ClientConnection clientConnection = createConnection((HttpServletRequest) servletRequest); - filter(clientConnection, (session) -> { + filter(clientConnection, session -> { try { filterChain.doFilter(servletRequest, servletResponse); } catch (Exception e) { diff --git a/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/Resteasy3Provider.java b/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/Resteasy3Provider.java index ce96a84fa..a42e9920d 100644 --- a/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/Resteasy3Provider.java +++ b/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/Resteasy3Provider.java @@ -1,37 +1,35 @@ package com.baeldung.jwt.config; -import org.jboss.resteasy.core.Dispatcher; -import org.jboss.resteasy.spi.ResteasyProviderFactory; +import java.util.HashMap; +import java.util.Map; + +import org.jboss.resteasy.core.ResteasyContext; import org.keycloak.common.util.ResteasyProvider; public class Resteasy3Provider implements ResteasyProvider { @Override public R getContextData(Class type) { - ResteasyProviderFactory.getInstance(); - return ResteasyProviderFactory.getContextData(type); + return ResteasyContext.getContextData(type); } @SuppressWarnings("rawtypes") @Override public void pushDefaultContextObject(Class type, Object instance) { - ResteasyProviderFactory.getInstance(); - ResteasyProviderFactory.getContextData(Dispatcher.class) - .getDefaultContextObjects() - .put(type, instance); + Map, Object> map = new HashMap<>(); + map.put(type, instance); + ResteasyContext.pushContextDataMap(map); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public void pushContext(Class type, Object instance) { - ResteasyProviderFactory.getInstance(); - ResteasyProviderFactory.pushContext(type, instance); + ResteasyContext.pushContext(type, instance); } @Override public void clearContextData() { - ResteasyProviderFactory.getInstance(); - ResteasyProviderFactory.clearContextData(); + ResteasyContext.clearContextData(); } } \ No newline at end of file diff --git a/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/SimplePlatformProvider.java b/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/SimplePlatformProvider.java index c10ea51d6..6f922f3b5 100644 --- a/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/SimplePlatformProvider.java +++ b/oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/SimplePlatformProvider.java @@ -2,6 +2,7 @@ import java.io.File; +import org.keycloak.Config; import org.keycloak.platform.PlatformProvider; import org.keycloak.services.ServicesLogger; @@ -9,7 +10,12 @@ public class SimplePlatformProvider implements PlatformProvider { Runnable shutdownHook; - @Override + @Override + public String name() { + return "SimplePlatformProvider"; + } + + @Override public void onStartup(Runnable startupHook) { startupHook.run(); } @@ -26,16 +32,16 @@ public void exit(Throwable cause) { } private void exit(int status) { - new Thread() { - @Override - public void run() { - System.exit(status); - } - }.start(); + new Thread(() -> System.exit(status)).start(); } @Override public File getTmpDirectory() { return new File(System.getProperty("java.io.tmpdir")); } + + @Override + public ClassLoader getScriptEngineClassLoader(Config.Scope scope) { + return null; + } } \ No newline at end of file diff --git a/oauth-jwt/jwt-resource-server/pom.xml b/oauth-jwt/jwt-resource-server/pom.xml index eca9cad20..1aa89f1ba 100644 --- a/oauth-jwt/jwt-resource-server/pom.xml +++ b/oauth-jwt/jwt-resource-server/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.4 + 3.1.1 @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.3.5.RELEASE + 2.5.2.RELEASE @@ -90,7 +90,7 @@ UTF-8 - 13 + 17 \ No newline at end of file diff --git a/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/JWTResourceServerApp.java b/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/JWTResourceServerApp.java index 385b1c9f1..3217eda69 100644 --- a/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/JWTResourceServerApp.java +++ b/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/JWTResourceServerApp.java @@ -6,8 +6,7 @@ @SpringBootApplication public class JWTResourceServerApp { - public static void main(String[] args) throws Exception { + public static void main(String[] args) { SpringApplication.run(JWTResourceServerApp.class, args); } - } diff --git a/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/model/Foo.java b/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/model/Foo.java index 4b912a235..d10c500c6 100644 --- a/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/model/Foo.java +++ b/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/model/Foo.java @@ -1,9 +1,9 @@ package com.baeldung.jwt.persistence.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Foo { diff --git a/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/repository/IFooRepository.java b/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/repository/IFooRepository.java index 4a1a1980d..edd14be45 100644 --- a/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/repository/IFooRepository.java +++ b/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/repository/IFooRepository.java @@ -1,8 +1,8 @@ package com.baeldung.jwt.persistence.repository; -import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.CrudRepository; import com.baeldung.jwt.persistence.model.Foo; -public interface IFooRepository extends PagingAndSortingRepository { +public interface IFooRepository extends CrudRepository { } diff --git a/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/spring/SecurityConfig.java b/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/spring/SecurityConfig.java index 20fecbaa9..8b7cf38d9 100644 --- a/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/spring/SecurityConfig.java +++ b/oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/spring/SecurityConfig.java @@ -1,36 +1,35 @@ package com.baeldung.jwt.spring; -import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { +public class SecurityConfig { - @Override - protected void configure(HttpSecurity http) throws Exception {// @formatter:off - http.cors() - .and() - .authorizeRequests() - .antMatchers(HttpMethod.GET, "/user/info", "/api/foos/**") - .hasAuthority("SCOPE_read") - .antMatchers(HttpMethod.POST, "/api/foos") - .hasAuthority("SCOPE_write") - .anyRequest() - .authenticated() - .and() - .oauth2ResourceServer() - .jwt(); + @Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}") + private String issuerUri; + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {// @formatter:off + http.cors(httpSecurityCorsConfigurer -> httpSecurityCorsConfigurer.configure(http)) + .authorizeHttpRequests(authorizeRequest -> + authorizeRequest.requestMatchers(HttpMethod.GET, "/user/info", "/api/foos/**").hasAuthority("SCOPE_read") + .requestMatchers(HttpMethod.POST, "/api/foos").hasAuthority("SCOPE_write") + .anyRequest().authenticated()) + .oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer.jwt(jwtConfigurer -> jwtConfigurer.decoder(jwtDecoder()))); + + return http.build(); }// @formatter:on @Bean - JwtDecoder jwtDecoder(OAuth2ResourceServerProperties properties) { - NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri(properties.getJwt().getJwkSetUri()).build(); + JwtDecoder jwtDecoder() { + NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri(issuerUri).build(); jwtDecoder.setClaimSetConverter(new OrganizationSubClaimAdapter()); return jwtDecoder; } diff --git a/oauth-jwt/jwt-resource-server/src/test/java/com/baeldung/jwt/ContextIntegrationTest.java b/oauth-jwt/jwt-resource-server/src/test/java/com/baeldung/jwt/ContextIntegrationTest.java index 1a0b5bda5..eb26a3846 100644 --- a/oauth-jwt/jwt-resource-server/src/test/java/com/baeldung/jwt/ContextIntegrationTest.java +++ b/oauth-jwt/jwt-resource-server/src/test/java/com/baeldung/jwt/ContextIntegrationTest.java @@ -5,14 +5,12 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; -import com.baeldung.jwt.JWTResourceServerApp; - @ExtendWith(SpringExtension.class) @SpringBootTest(classes = { JWTResourceServerApp.class }) -public class ContextIntegrationTest { +class ContextIntegrationTest { @Test - public void whenLoadApplication_thenSuccess() { + void whenLoadApplication_thenSuccess() { } diff --git a/oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/package-lock.json b/oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/package-lock.json index bf4f06567..0015ba95d 100644 --- a/oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/package-lock.json +++ b/oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/package-lock.json @@ -1067,7 +1067,6 @@ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, - "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -2102,8 +2101,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "constants-browserify": { "version": "1.0.0", @@ -2470,8 +2468,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true + "dev": true }, "depd": { "version": "1.1.2", @@ -3269,8 +3266,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -3291,14 +3287,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3313,20 +3307,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -3443,8 +3434,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -3456,7 +3446,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3471,7 +3460,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3479,14 +3467,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3505,7 +3491,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3586,8 +3571,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -3599,7 +3583,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3685,8 +3668,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -3722,7 +3704,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3742,7 +3723,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3786,14 +3766,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -3802,7 +3780,6 @@ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "dev": true, - "optional": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -3815,7 +3792,6 @@ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, - "optional": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -3853,8 +3829,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true, - "optional": true + "dev": true }, "get-stream": { "version": "3.0.0", @@ -3991,8 +3966,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true + "dev": true }, "has-value": { "version": "1.0.0", @@ -4711,8 +4685,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true, - "optional": true + "dev": true }, "is-windows": { "version": "1.0.2", @@ -5008,7 +4981,6 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, - "optional": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", @@ -5021,8 +4993,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "optional": true + "dev": true } } }, @@ -5281,8 +5252,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true, - "optional": true + "dev": true }, "map-visit": { "version": "1.0.0", @@ -5926,7 +5896,6 @@ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, - "optional": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -6778,7 +6747,6 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, - "optional": true, "requires": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", @@ -6790,7 +6758,6 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, - "optional": true, "requires": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", @@ -6801,8 +6768,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "optional": true + "dev": true } } }, @@ -6811,7 +6777,6 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, - "optional": true, "requires": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" @@ -6822,7 +6787,6 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, - "optional": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" @@ -6833,7 +6797,6 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, - "optional": true, "requires": { "pinkie-promise": "^2.0.0" } @@ -7969,7 +7932,6 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, - "optional": true, "requires": { "is-utf8": "^0.2.0" } @@ -9305,7 +9267,6 @@ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, - "optional": true, "requires": { "string-width": "^1.0.2 || 2" } diff --git a/oauth-rest/keycloak-custom-providers/pom.xml b/oauth-rest/keycloak-custom-providers/pom.xml index 60e5d79b6..9668f5559 100644 --- a/oauth-rest/keycloak-custom-providers/pom.xml +++ b/oauth-rest/keycloak-custom-providers/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.6.RELEASE + 3.1.1 @@ -53,6 +53,12 @@ oauth-authorization-server 0.1.0-SNAPSHOT test + + + org.keycloak + keycloak-dependencies-server-all + + @@ -69,7 +75,6 @@ test - io.rest-assured rest-assured @@ -94,9 +99,9 @@ UTF-8 - 11 + 17 - 21.1.2 + 22.0.0 diff --git a/oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUser.java b/oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUser.java index b9220613b..240465a93 100644 --- a/oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUser.java +++ b/oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUser.java @@ -8,6 +8,7 @@ import org.keycloak.component.ComponentModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; +import org.keycloak.models.SubjectCredentialManager; import org.keycloak.models.UserModel; import org.keycloak.storage.adapter.AbstractUserAdapter; @@ -56,6 +57,11 @@ public String getEmail() { return email; } + @Override + public SubjectCredentialManager credentialManager() { + return null; + } + public Date getBirthDate() { return birthDate; } diff --git a/oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUserStorageProvider.java b/oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUserStorageProvider.java index 9d2995b3f..85d67ebda 100644 --- a/oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUserStorageProvider.java +++ b/oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUserStorageProvider.java @@ -11,10 +11,9 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.stream.Stream; import org.keycloak.component.ComponentModel; import org.keycloak.credential.CredentialInput; @@ -51,14 +50,14 @@ public void close() { } @Override - public UserModel getUserById(String id, RealmModel realm) { + public UserModel getUserById(RealmModel realm, String id) { log.info("[I35] getUserById({})",id); StorageId sid = new StorageId(id); - return getUserByUsername(sid.getExternalId(),realm); + return getUserByUsername(realm, sid.getExternalId()); } @Override - public UserModel getUserByUsername(String username, RealmModel realm) { + public UserModel getUserByUsername(RealmModel realm, String username) { log.info("[I41] getUserByUsername({})",username); try ( Connection c = DbUtil.getConnection(this.model)) { PreparedStatement st = c.prepareStatement("select username, firstName,lastName, email, birthDate from users where username = ?"); @@ -78,7 +77,7 @@ public UserModel getUserByUsername(String username, RealmModel realm) { } @Override - public UserModel getUserByEmail(String email, RealmModel realm) { + public UserModel getUserByEmail(RealmModel realm, String email) { log.info("[I48] getUserByEmail({})",email); try ( Connection c = DbUtil.getConnection(this.model)) { PreparedStatement st = c.prepareStatement("select username, firstName,lastName, email, birthDate from users where email = ?"); @@ -155,12 +154,10 @@ public int getUsersCount(RealmModel realm) { } } - @Override public List getUsers(RealmModel realm) { return getUsers(realm,0, 5000); // Keep a reasonable maxResults } - @Override public List getUsers(RealmModel realm, int firstResult, int maxResults) { log.info("[I113] getUsers: realm={}", realm.getName()); @@ -180,59 +177,6 @@ public List getUsers(RealmModel realm, int firstResult, int maxResult throw new RuntimeException("Database error:" + ex.getMessage(),ex); } } - - @Override - public List searchForUser(String search, RealmModel realm) { - return searchForUser(search,realm,0,5000); - } - - @Override - public List searchForUser(String search, RealmModel realm, int firstResult, int maxResults) { - log.info("[I139] searchForUser: realm={}", realm.getName()); - - try ( Connection c = DbUtil.getConnection(this.model)) { - PreparedStatement st = c.prepareStatement("select username, firstName,lastName, email, birthDate from users where username like ? order by username limit ? offset ?"); - st.setString(1, search); - st.setInt(2, maxResults); - st.setInt(3, firstResult); - st.execute(); - ResultSet rs = st.getResultSet(); - List users = new ArrayList<>(); - while(rs.next()) { - users.add(mapUser(realm,rs)); - } - return users; - } - catch(SQLException ex) { - throw new RuntimeException("Database error:" + ex.getMessage(),ex); - } - } - - @Override - public List searchForUser(Map params, RealmModel realm) { - return searchForUser(params,realm,0,5000); - } - - @Override - public List searchForUser(Map params, RealmModel realm, int firstResult, int maxResults) { - return getUsers(realm, firstResult, maxResults); - } - - @Override - public List getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) { - return Collections.emptyList(); - } - - @Override - public List getGroupMembers(RealmModel realm, GroupModel group) { - return Collections.emptyList(); - } - - @Override - public List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) { - return Collections.emptyList(); - } - //------------------- Implementation private UserModel mapUser(RealmModel realm, ResultSet rs) throws SQLException { @@ -247,4 +191,19 @@ private UserModel mapUser(RealmModel realm, ResultSet rs) throws SQLException { return user; } + + @Override + public Stream searchForUserStream(RealmModel realmModel, Map map, Integer integer, Integer integer1) { + return null; + } + + @Override + public Stream getGroupMembersStream(RealmModel realmModel, GroupModel groupModel, Integer integer, Integer integer1) { + return null; + } + + @Override + public Stream searchForUserByUserAttributeStream(RealmModel realmModel, String s, String s1) { + return null; + } } diff --git a/oauth-rest/keycloak-custom-providers/src/test/java/com/baeldung/auth/provider/user/ContextIntegrationLiveTest.java b/oauth-rest/keycloak-custom-providers/src/test/java/com/baeldung/auth/provider/user/ContextIntegrationLiveTest.java index dc7f32c72..5c560032f 100644 --- a/oauth-rest/keycloak-custom-providers/src/test/java/com/baeldung/auth/provider/user/ContextIntegrationLiveTest.java +++ b/oauth-rest/keycloak-custom-providers/src/test/java/com/baeldung/auth/provider/user/ContextIntegrationLiveTest.java @@ -8,8 +8,7 @@ import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.io.ClassPathResource; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -18,8 +17,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.client.RestTemplate; -import com.baeldung.auth.AuthorizationServerApp; - import static org.junit.jupiter.api.Assertions.*; import javax.sql.DataSource; @@ -30,16 +27,15 @@ @SpringBootTest(classes = { AuthorizationServerApp.class }, webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") public class ContextIntegrationLiveTest { - + private static final Logger log = LoggerFactory.getLogger(ContextIntegrationLiveTest.class); - + @LocalServerPort int serverPort; - - + @Autowired private RestTemplate restTemplate; - + @BeforeAll public static void populateTestDatabase() throws Exception { log.info("Populating database..."); @@ -53,21 +49,20 @@ public static void populateTestDatabase() throws Exception { ResourceDatabasePopulator populator = new ResourceDatabasePopulator(false, false, "UTF-8", new ClassPathResource("custom-database-data.sql")); populator.execute(ds); - } - + @Test public void whenLoadApplication_thenSuccess() throws InterruptedException { log.info("Server port: {}", serverPort); - + String baseUrl = "http://localhost:" + serverPort; ResponseEntity response = restTemplate.getForEntity( baseUrl + "/auth" , String.class); assertNotNull(response); assertEquals(HttpStatus.OK, response.getStatusCode()); - + log.info("Keycloak test server available at {}/auth", baseUrl); log.info("To test a custom provider user login, go to {}/auth/realms/baeldung/account",baseUrl); - + Thread.sleep(15*60*1000); } diff --git a/oauth-rest/oauth-authorization-server/pom.xml b/oauth-rest/oauth-authorization-server/pom.xml index dd7c32c83..fee4baaf4 100644 --- a/oauth-rest/oauth-authorization-server/pom.xml +++ b/oauth-rest/oauth-authorization-server/pom.xml @@ -3,16 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung oauth-authorization-server - oauth-authorization-server 0.1.0-SNAPSHOT jar org.springframework.boot spring-boot-starter-parent - 2.7.9 + 3.1.1 @@ -74,13 +72,13 @@ keycloak-services ${keycloak.version} - + org.keycloak keycloak-rest-admin-ui-ext ${keycloak.version} - + org.liquibase liquibase-core @@ -96,7 +94,7 @@ - + org.springframework.boot @@ -164,11 +162,11 @@ UTF-8 - 13 - 21.1.2 + 17 + 22.0.0 - 4.7.7.Final + 6.2.3.Final 4.16.1 14.0.6.Final diff --git a/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/AuthorizationServerApp.java b/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/AuthorizationServerApp.java index 9380fbbf2..11a0d8b74 100644 --- a/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/AuthorizationServerApp.java +++ b/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/AuthorizationServerApp.java @@ -19,7 +19,7 @@ public class AuthorizationServerApp { private static final Logger LOG = LoggerFactory.getLogger(AuthorizationServerApp.class); - public static void main(String[] args) throws Exception { + public static void main(String[] args) { SpringApplication.run(AuthorizationServerApp.class, args); } diff --git a/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/EmbeddedKeycloakRequestFilter.java b/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/EmbeddedKeycloakRequestFilter.java index b824d614b..adb88c467 100644 --- a/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/EmbeddedKeycloakRequestFilter.java +++ b/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/EmbeddedKeycloakRequestFilter.java @@ -2,11 +2,11 @@ import java.io.UnsupportedEncodingException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import org.keycloak.common.ClientConnection; import org.keycloak.services.filters.AbstractRequestFilter; @@ -18,7 +18,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo servletRequest.setCharacterEncoding("UTF-8"); ClientConnection clientConnection = createConnection((HttpServletRequest) servletRequest); - filter(clientConnection, (session) -> { + filter(clientConnection, session -> { try { filterChain.doFilter(servletRequest, servletResponse); } catch (Exception e) { diff --git a/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/SimplePlatformProvider.java b/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/SimplePlatformProvider.java index 345f62dc9..eef8a3a2e 100644 --- a/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/SimplePlatformProvider.java +++ b/oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/SimplePlatformProvider.java @@ -17,7 +17,7 @@ public SimplePlatformProvider() { Runnable shutdownHook; - @Override + @Override public void onStartup(Runnable startupHook) { startupHook.run(); } diff --git a/oauth-rest/oauth-authorization-server/src/test/java/com/baeldung/auth/ContextIntegrationTest.java b/oauth-rest/oauth-authorization-server/src/test/java/com/baeldung/auth/ContextIntegrationTest.java index ecbf848e0..c1e973ec9 100644 --- a/oauth-rest/oauth-authorization-server/src/test/java/com/baeldung/auth/ContextIntegrationTest.java +++ b/oauth-rest/oauth-authorization-server/src/test/java/com/baeldung/auth/ContextIntegrationTest.java @@ -5,14 +5,12 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; -import com.baeldung.auth.AuthorizationServerApp; - @ExtendWith(SpringExtension.class) @SpringBootTest(classes = { AuthorizationServerApp.class }) -public class ContextIntegrationTest { +class ContextIntegrationTest { @Test - public void whenLoadApplication_thenSuccess() { + void whenLoadApplication_thenSuccess() { } diff --git a/oauth-rest/oauth-client-spring/pom.xml b/oauth-rest/oauth-client-spring/pom.xml index 874e285f6..ae16e492d 100644 --- a/oauth-rest/oauth-client-spring/pom.xml +++ b/oauth-rest/oauth-client-spring/pom.xml @@ -52,6 +52,7 @@ org.thymeleaf.extras thymeleaf-extras-springsecurity5 + 3.1.1.RELEASE @@ -111,7 +112,7 @@ UTF-8 - 13 + 17 diff --git a/oauth-rest/oauth-client-spring/src/main/java/com/baeldung/client/spring/ClientSecurityConfig.java b/oauth-rest/oauth-client-spring/src/main/java/com/baeldung/client/spring/ClientSecurityConfig.java index 9929a5666..f6b654361 100644 --- a/oauth-rest/oauth-client-spring/src/main/java/com/baeldung/client/spring/ClientSecurityConfig.java +++ b/oauth-rest/oauth-client-spring/src/main/java/com/baeldung/client/spring/ClientSecurityConfig.java @@ -1,6 +1,9 @@ package com.baeldung.client.spring; +import static org.springframework.web.reactive.function.server.HandlerStrategies.withDefaults; + import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; @@ -10,15 +13,17 @@ import org.springframework.web.reactive.function.client.WebClient; @EnableWebSecurity +@Configuration public class ClientSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {// @formatter:off - http.authorizeHttpRequests(authorize -> authorize.antMatchers("/").permitAll() - .anyRequest().authenticated()) - .oauth2Login() - .and() - .logout().logoutSuccessUrl("/"); + http.authorizeHttpRequests(authorize -> + authorize.requestMatchers("/").permitAll() + .anyRequest().authenticated()) + .oauth2Login(httpSecurityOAuth2LoginConfigurer -> withDefaults()) + .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.logoutSuccessUrl("/")); + return http.build(); }// @formatter:on diff --git a/oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/ClientContextIntegrationTest.java b/oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/ClientContextIntegrationTest.java index c84e92544..a89aa5d62 100644 --- a/oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/ClientContextIntegrationTest.java +++ b/oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/ClientContextIntegrationTest.java @@ -4,10 +4,10 @@ import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest(classes = { ClientSpringApp.class }) -public class ClientContextIntegrationTest { +class ClientContextIntegrationTest { @Test - public void whenLoadApplication_thenSuccess() { + void whenLoadApplication_thenSuccess() { } diff --git a/oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/Oauth2ClientIntegrationTest.java b/oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/Oauth2ClientIntegrationTest.java index f640e8e54..566fe7b55 100644 --- a/oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/Oauth2ClientIntegrationTest.java +++ b/oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/Oauth2ClientIntegrationTest.java @@ -1,6 +1,7 @@ package com.baeldung.client; import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.endsWith; import static org.hamcrest.CoreMatchers.startsWith; @@ -43,7 +44,7 @@ public class Oauth2ClientIntegrationTest { private final static Pair RESOURCE_SERVER_PROP = Pair.of("resourceserver.api.foo.url", "http://localhost:{PORT}/resource-server/api/foos/"); private final String CLIENT_SECURED_URL = "/foos"; - private String REDIRECT_URI = "/login/oauth2/code/custom?state=%s&code=%s"; + private final String REDIRECT_URI = "/login/oauth2/code/custom?state=%s&code=%s"; @Value("${spring.security.oauth2.client.provider.custom.authorization-uri}") private String authServerAuthorizationURL; @@ -95,14 +96,14 @@ public static void tearDown() throws Exception { } @BeforeEach - public void beforeEach() throws Exception { + public void beforeEach() { webTestClient = webTestClient.mutate() .responseTimeout(Duration.ofMillis(300000)) .build(); } @Test - public void givenAuthServerAndResourceServer_whenPerformClientLoginProcess_thenProcessExecutesOk() throws Exception { + void givenAuthServerAndResourceServer_whenPerformClientLoginProcess_thenProcessExecutesOk() throws Exception { // mimic login button action ExchangeResult result = this.webTestClient.get() .uri(CLIENT_SECURED_URL) @@ -165,7 +166,7 @@ public void givenAuthServerAndResourceServer_whenPerformClientLoginProcess_thenP .expectStatus() .isFound() .expectHeader() - .value(HttpHeaders.LOCATION, endsWith(CLIENT_SECURED_URL)) + .value(HttpHeaders.LOCATION, containsString(CLIENT_SECURED_URL)) .returnResult(Void.class); // assert that Access Token Endpoint was requested as expected @@ -222,7 +223,7 @@ public void givenAuthServerAndResourceServer_whenPerformClientLoginProcess_thenP } @Test - public void whenUnauthorized_thenRedirect() throws Exception { + void whenUnauthorized_thenRedirect() { this.webTestClient.get() .uri(CLIENT_SECURED_URL) .exchange() diff --git a/oauth-rest/oauth-resource-server/pom.xml b/oauth-rest/oauth-resource-server/pom.xml index de20aae52..9ae32ef2f 100644 --- a/oauth-rest/oauth-resource-server/pom.xml +++ b/oauth-rest/oauth-resource-server/pom.xml @@ -96,7 +96,7 @@ UTF-8 - 13 + 17 diff --git a/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/ResourceServerApp.java b/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/ResourceServerApp.java index b2a0411ac..e0552f7eb 100644 --- a/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/ResourceServerApp.java +++ b/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/ResourceServerApp.java @@ -6,8 +6,7 @@ @SpringBootApplication public class ResourceServerApp { - public static void main(String[] args) throws Exception { + public static void main(String[] args) { SpringApplication.run(ResourceServerApp.class, args); } - } diff --git a/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/model/Foo.java b/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/model/Foo.java index 33c706b72..ec49dc31b 100644 --- a/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/model/Foo.java +++ b/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/model/Foo.java @@ -1,9 +1,9 @@ package com.baeldung.resource.persistence.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Foo { diff --git a/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/repository/IFooRepository.java b/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/repository/IFooRepository.java index a4885871a..d0c975502 100644 --- a/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/repository/IFooRepository.java +++ b/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/repository/IFooRepository.java @@ -1,8 +1,8 @@ package com.baeldung.resource.persistence.repository; -import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.CrudRepository; import com.baeldung.resource.persistence.model.Foo; -public interface IFooRepository extends PagingAndSortingRepository { +public interface IFooRepository extends CrudRepository { } diff --git a/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/spring/SecurityConfig.java b/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/spring/SecurityConfig.java index bd918b9f6..2bbfa7f88 100644 --- a/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/spring/SecurityConfig.java +++ b/oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/spring/SecurityConfig.java @@ -1,28 +1,34 @@ package com.baeldung.resource.spring; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { + @Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}") + private String issuerUri; + @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.cors() - .and() - .authorizeRequests() - .antMatchers(HttpMethod.GET, "/user/info", "/api/foos/**") - .hasAuthority("SCOPE_read") - .antMatchers(HttpMethod.POST, "/api/foos") - .hasAuthority("SCOPE_write") - .anyRequest() - .authenticated() - .and() - .oauth2ResourceServer() - .jwt(); + http.cors(httpSecurityCorsConfigurer -> httpSecurityCorsConfigurer.configure(http)) + .authorizeHttpRequests(expressionInterceptUrlRegistry -> + expressionInterceptUrlRegistry + .requestMatchers(HttpMethod.GET, "/user/info", "/api/foos/**").hasAuthority("SCOPE_read") + .requestMatchers(HttpMethod.POST, "/api/foos").hasAuthority("SCOPE_write") + .anyRequest().authenticated()) + .oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer -> httpSecurityOAuth2ResourceServerConfigurer.jwt(jwtConfigurer -> jwtConfigurer.decoder(jwtDecoder()))); return http.build(); } + + @Bean + JwtDecoder jwtDecoder() { + return NimbusJwtDecoder.withJwkSetUri(issuerUri).build(); + } } \ No newline at end of file diff --git a/oauth-rest/pom.xml b/oauth-rest/pom.xml index 42dbd5d33..8ffe8996f 100644 --- a/oauth-rest/pom.xml +++ b/oauth-rest/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.5 + 3.1.1 @@ -21,7 +21,6 @@ oauth-ui-authorization-code-angular oauth-ui-authorization-code-angular-zuul oauth-client-spring - keycloak-custom-protocol-mapper