├── .dependabot └── config.yml ├── .github └── ISSUE_TEMPLATE │ └── issue_report.md ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── clients-SPA-legacy ├── clients-js-only-react-legacy │ ├── .gitignore │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── clientjsonlyreact │ │ │ │ └── ClientJsOnlyReactApplication.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── static │ │ │ ├── common │ │ │ ├── images │ │ │ │ └── default-profile.png │ │ │ └── js │ │ │ │ ├── code_challenge_functions.js │ │ │ │ ├── code_verifier_functions.js │ │ │ │ ├── common_functions.js │ │ │ │ ├── components │ │ │ │ └── spinner.js │ │ │ │ └── provider_configs.js │ │ │ ├── index.html │ │ │ ├── landing-page.css │ │ │ ├── pkce-realcase │ │ │ ├── css │ │ │ │ └── bael-oauth-pkce-styles.css │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ ├── components │ │ │ │ │ ├── app.js │ │ │ │ │ ├── navbar │ │ │ │ │ │ └── navbar.js │ │ │ │ │ ├── pages │ │ │ │ │ │ ├── listing.js │ │ │ │ │ │ ├── listing_item.js │ │ │ │ │ │ └── profile.js │ │ │ │ │ └── popup │ │ │ │ │ │ └── popup_window.js │ │ │ │ └── resource_configs.js │ │ │ └── popup_code_handler.html │ │ │ ├── pkce-simple │ │ │ ├── callback.html │ │ │ ├── index.html │ │ │ └── js │ │ │ │ └── components │ │ │ │ └── app.js │ │ │ └── pkce-stepbystep │ │ │ ├── css │ │ │ └── bael-oauth-pkce-styles.css │ │ │ ├── index.html │ │ │ ├── js │ │ │ └── components │ │ │ │ ├── app.js │ │ │ │ ├── popup │ │ │ │ └── popup_window.js │ │ │ │ └── steps │ │ │ │ ├── step0.js │ │ │ │ ├── step1.js │ │ │ │ ├── step2.js │ │ │ │ └── step3.js │ │ │ └── popup_code_handler.html │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── clientjsonlyreact │ │ └── ApplicationContextIntegrationTest.java └── oauth-resource-server-auth0-legacy │ ├── .gitignore │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── baeldung │ │ │ └── resourceserverauth0 │ │ │ ├── OauthResourceServerAuth0Application.java │ │ │ ├── configs │ │ │ └── WebSecurityConfig.java │ │ │ ├── dao │ │ │ └── ColorRepository.java │ │ │ ├── model │ │ │ └── Color.java │ │ │ └── web │ │ │ └── controllers │ │ │ └── ColorsRestController.java │ └── resources │ │ ├── application.yml │ │ └── data.sql │ └── test │ └── java │ └── com │ └── baeldung │ └── resourceserverauth0 │ └── OauthResourceServerAuth0ApplicationTests.java ├── oauth-authorization-server ├── README.md ├── client-server │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── baeldung │ │ │ ├── OAuth2ClientApplication.java │ │ │ ├── config │ │ │ ├── SecurityConfig.java │ │ │ └── WebClientConfig.java │ │ │ └── web │ │ │ └── ArticlesController.java │ │ └── resources │ │ └── application.yml ├── pom.xml ├── resource-server │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── baeldung │ │ │ ├── OAuth2ResourceServerApplication.java │ │ │ ├── config │ │ │ └── ResourceServerConfig.java │ │ │ └── web │ │ │ └── ArticlesController.java │ │ └── resources │ │ └── application.yml └── spring-authorization-server │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── com │ │ └── baeldung │ │ ├── OAuth2AuthorizationServerApplication.java │ │ └── config │ │ └── DefaultSecurityConfig.java │ └── resources │ └── application.yml ├── oauth-jws-jwk-legacy ├── README.md ├── oauth-authorization-server-jws-jwk-legacy │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ ├── AuthServerApp.java │ │ │ │ ├── config │ │ │ │ ├── JwkAuthorizationServerConfiguration.java │ │ │ │ └── JwtCustomHeadersAccessTokenConverter.java │ │ │ │ └── web │ │ │ │ └── JwkSetRestController.java │ │ └── resources │ │ │ ├── .keystore-oauth2-demo │ │ │ ├── bael-jwt.jks │ │ │ └── filtered │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ ├── SpringContextIntegrationTest.java │ │ └── web │ │ └── JwkSetRestControllerIntegrationTest.java └── oauth-resource-server-jws-jwk-legacy │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── baeldung │ │ │ ├── ResourceServerApplication.java │ │ │ └── web │ │ │ ├── controller │ │ │ └── FooController.java │ │ │ └── dto │ │ │ └── Foo.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── baeldung │ ├── SpringContextIntegrationTest.java │ └── web │ └── FooControllerLiveTest.java ├── oauth-jwt ├── README.md ├── jwt-auth-server │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── jwt │ │ │ │ ├── JWTAuthorizationServerApp.java │ │ │ │ └── config │ │ │ │ ├── EmbeddedKeycloakApplication.java │ │ │ │ ├── EmbeddedKeycloakConfig.java │ │ │ │ ├── EmbeddedKeycloakRequestFilter.java │ │ │ │ ├── KeycloakServerProperties.java │ │ │ │ ├── RegularJsonConfigProviderFactory.java │ │ │ │ ├── Resteasy3Provider.java │ │ │ │ └── SimplePlatformProvider.java │ │ └── resources │ │ │ ├── META-INF │ │ │ ├── keycloak-server.json │ │ │ └── services │ │ │ │ ├── org.keycloak.common.util.ResteasyProvider │ │ │ │ ├── org.keycloak.config.ConfigProviderFactory │ │ │ │ └── org.keycloak.platform.PlatformProvider │ │ │ ├── application.yml │ │ │ ├── baeldung-realm.json │ │ │ ├── mytest.jks │ │ │ └── themes │ │ │ └── custom │ │ │ ├── account │ │ │ ├── resources │ │ │ │ ├── css │ │ │ │ │ └── account.css │ │ │ │ └── img │ │ │ │ │ ├── baeldung.png │ │ │ │ │ ├── favicon.ico │ │ │ │ │ ├── icon-sidebar-active.png │ │ │ │ │ ├── keycloak-logo.png │ │ │ │ │ └── logo.png │ │ │ └── theme.properties │ │ │ ├── login │ │ │ ├── messages │ │ │ │ └── messages_en.properties │ │ │ ├── register.ftl │ │ │ ├── resources │ │ │ │ ├── css │ │ │ │ │ └── login.css │ │ │ │ └── img │ │ │ │ │ ├── favicon.ico │ │ │ │ │ ├── feedback-error-arrow-down.png │ │ │ │ │ ├── feedback-error-sign.png │ │ │ │ │ ├── feedback-success-arrow-down.png │ │ │ │ │ ├── feedback-success-sign.png │ │ │ │ │ ├── feedback-warning-arrow-down.png │ │ │ │ │ ├── feedback-warning-sign.png │ │ │ │ │ ├── keycloak-bg.png │ │ │ │ │ ├── keycloak-logo-text.png │ │ │ │ │ └── keycloak-logo.png │ │ │ ├── template.ftl │ │ │ └── theme.properties │ │ │ └── welcome │ │ │ ├── index.ftl │ │ │ ├── resources │ │ │ ├── admin-console.png │ │ │ ├── alert.png │ │ │ ├── bg.png │ │ │ ├── bug.png │ │ │ ├── css │ │ │ │ └── welcome.css │ │ │ ├── favicon.ico │ │ │ ├── geo.png │ │ │ ├── jboss_community.png │ │ │ ├── keycloak-project.png │ │ │ ├── keycloak_logo.png │ │ │ ├── logo.png │ │ │ ├── mail.png │ │ │ └── user.png │ │ │ └── theme.properties │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── baeldung │ │ │ └── jwt │ │ │ ├── AuthorizationServerLiveTest.java │ │ │ └── ContextIntegrationTest.java │ │ └── resources │ │ ├── Keycloak.postman_collection.json │ │ └── Keycloak.postman_environment.json ├── jwt-resource-server │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── jwt │ │ │ │ ├── JWTResourceServerApp.java │ │ │ │ ├── persistence │ │ │ │ ├── model │ │ │ │ │ └── Foo.java │ │ │ │ └── repository │ │ │ │ │ └── IFooRepository.java │ │ │ │ ├── service │ │ │ │ ├── IFooService.java │ │ │ │ └── impl │ │ │ │ │ └── FooServiceImpl.java │ │ │ │ ├── spring │ │ │ │ ├── OrganizationSubClaimAdapter.java │ │ │ │ └── SecurityConfig.java │ │ │ │ └── web │ │ │ │ ├── controller │ │ │ │ ├── CustomUserAttrController.java │ │ │ │ ├── FooController.java │ │ │ │ └── UserInfoController.java │ │ │ │ └── dto │ │ │ │ └── FooDto.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── data.sql │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── jwt │ │ ├── ContextIntegrationTest.java │ │ ├── CustomClaimLiveTest.java │ │ └── ResourceServerLiveTest.java ├── oauth-ui-authorization-code-angular-jwt │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ ├── angular.json │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── app │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── app.service.ts │ │ │ ├── foo.component.ts │ │ │ └── home.component.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.spec.json │ │ └── typings.d.ts │ │ └── tsconfig.json └── pom.xml ├── oauth-legacy ├── README.md ├── oauth-authorization-server-legacy │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ ├── config │ │ │ │ ├── AuthorizationServerApplication.java │ │ │ │ ├── CorsFilter.java │ │ │ │ ├── CustomTokenEnhancer.java │ │ │ │ ├── EmployeeController.java │ │ │ │ ├── OAuth2AuthorizationServerConfig.java │ │ │ │ ├── OAuth2AuthorizationServerConfigInMemory.java │ │ │ │ ├── OAuth2AuthorizationServerConfigJwt.java │ │ │ │ ├── OAuth2ResourceServerConfig.java │ │ │ │ ├── RevokeTokenEndpoint.java │ │ │ │ └── WebSecurityConfig.java │ │ │ │ ├── controller │ │ │ │ └── TokenController.java │ │ │ │ └── model │ │ │ │ └── Employee.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── data.sql │ │ │ ├── mytest.jks │ │ │ ├── persistence.properties │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── test │ │ ├── AuthServerIntegrationTest.java │ │ ├── OAuthMvcTest.java │ │ ├── TokenControllerIntegrationTest.java │ │ └── TokenRevocationLiveTest.java ├── oauth-microservices │ ├── 1x │ │ ├── Readme.md │ │ ├── api-gateway-zuul-1 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── baeldung │ │ │ │ │ │ ├── ApiGatewayApplication.java │ │ │ │ │ │ └── security │ │ │ │ │ │ ├── Oauth2ClientContextFilterWithPath.java │ │ │ │ │ │ └── SecurityConfiguration.java │ │ │ │ └── resources │ │ │ │ │ └── application.yml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── ApiGatewayApplicationTests.java │ │ ├── authorization-server-1 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── baeldung │ │ │ │ │ │ ├── UaaServiceApplication.java │ │ │ │ │ │ └── config │ │ │ │ │ │ ├── OAuth2AuthorizationServerConfig.java │ │ │ │ │ │ ├── WebConfig.java │ │ │ │ │ │ └── WebSecurityConfig.java │ │ │ │ └── resources │ │ │ │ │ ├── application.yml │ │ │ │ │ ├── keystore.jks │ │ │ │ │ └── templates │ │ │ │ │ ├── authorize.ftl │ │ │ │ │ └── login.ftl │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── UaaServiceApplicationTests.java │ │ ├── pom.xml │ │ ├── resource-server-mvc-1 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── baeldung │ │ │ │ │ │ ├── ResourceServerApplication.java │ │ │ │ │ │ └── web │ │ │ │ │ │ └── HelloController.java │ │ │ │ └── resources │ │ │ │ │ └── application.yml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── ResourceServerApplicationTests.java │ │ ├── resource-server-mvc-no-oauth-1 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── baeldung │ │ │ │ │ │ ├── ResourceServerApplication.java │ │ │ │ │ │ └── web │ │ │ │ │ │ └── HelloController.java │ │ │ │ └── resources │ │ │ │ │ └── application.yml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── ResourceServerApplicationTests.java │ │ └── service-registry-1 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── baeldung │ │ │ │ │ └── ServiceRegistryApplication.java │ │ │ └── resources │ │ │ │ └── application.yml │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── baeldung │ │ │ └── ServiceDiscoveryApplicationTests.java │ ├── 2x │ │ ├── api-cloud-gateway-2 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── baeldung │ │ │ │ │ │ └── gateway │ │ │ │ │ │ └── ApiGatewayApplication.java │ │ │ │ └── resources │ │ │ │ │ └── application.yml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── demo │ │ │ │ └── ApiGatewayApplicationTests.java │ │ ├── api-gateway-zuul-2 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── baeldung │ │ │ │ │ ├── ApiGatewayApplication.java │ │ │ │ │ └── security │ │ │ │ │ ├── DynamicOauth2ClientContextFilter.java │ │ │ │ │ └── SecurityConfiguration.java │ │ │ │ └── resources │ │ │ │ └── application.yml │ │ ├── authorization-server-2 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── baeldung │ │ │ │ │ │ ├── AuthorizationServerApplication.java │ │ │ │ │ │ └── config │ │ │ │ │ │ ├── OAuth2AuthorizationServerConfig.java │ │ │ │ │ │ ├── WebConfig.java │ │ │ │ │ │ └── WebSecurityConfig.java │ │ │ │ └── resources │ │ │ │ │ ├── application.yml │ │ │ │ │ └── templates │ │ │ │ │ ├── authorize.ftl │ │ │ │ │ └── login.ftl │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── test │ │ │ │ ├── AuthServerIntegrationTest.java │ │ │ │ ├── AuthorizationServerLiveTest.java │ │ │ │ └── OAuthMvcTest.java │ │ ├── pom.xml │ │ ├── resource-server-mvc-2 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── baeldung │ │ │ │ │ │ ├── ResourceServerApplication1.java │ │ │ │ │ │ ├── config │ │ │ │ │ │ └── WebSecurityConfig.java │ │ │ │ │ │ └── web │ │ │ │ │ │ └── HelloController.java │ │ │ │ └── resources │ │ │ │ │ └── application.yml │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── test │ │ │ │ └── ResourceServer1IntegrationTest.java │ │ ├── resource-server-rest-2 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── baeldung │ │ │ │ │ │ ├── ResourceServerApplication2.java │ │ │ │ │ │ ├── config │ │ │ │ │ │ ├── MethodSecurityConfig.java │ │ │ │ │ │ ├── OAuth2ResourceServerConfig.java │ │ │ │ │ │ └── ResourceServerWebConfig.java │ │ │ │ │ │ ├── service │ │ │ │ │ │ └── ThirdService.java │ │ │ │ │ │ └── web │ │ │ │ │ │ ├── controller │ │ │ │ │ │ ├── BarController.java │ │ │ │ │ │ ├── FooController.java │ │ │ │ │ │ ├── ThirdController.java │ │ │ │ │ │ └── UserController.java │ │ │ │ │ │ └── dto │ │ │ │ │ │ ├── Bar.java │ │ │ │ │ │ ├── Foo.java │ │ │ │ │ │ └── Third.java │ │ │ │ └── resources │ │ │ │ │ └── application.properties │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── test │ │ │ │ ├── ResourceServer2IntegrationTest.java │ │ │ │ ├── ResourceServer2LiveTest.java │ │ │ │ └── ResourceServerRestLiveTest.java │ │ └── service-registry-2 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── ServiceRegistryApplication.java │ │ │ └── resources │ │ │ └── application.yml │ ├── README.md │ └── pom.xml ├── oauth-resource-server-legacy-1 │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ ├── config │ │ │ │ ├── CorsFilter.java │ │ │ │ ├── CustomAccessTokenConverter.java │ │ │ │ ├── MethodSecurityConfig.java │ │ │ │ ├── OAuth2ResourceServerConfig.java │ │ │ │ ├── OAuth2ResourceServerConfigJwt.java │ │ │ │ ├── OAuth2ResourceServerConfigRemoteTokenService.java │ │ │ │ ├── ResourceServerApplication.java │ │ │ │ └── ResourceServerWebConfig.java │ │ │ │ └── web │ │ │ │ ├── controller │ │ │ │ ├── BarController.java │ │ │ │ ├── FooController.java │ │ │ │ └── UserController.java │ │ │ │ └── dto │ │ │ │ ├── Bar.java │ │ │ │ └── Foo.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── persistence.properties │ │ │ └── public.txt │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ ├── live │ │ ├── AuthorizationCodeLiveTest.java │ │ ├── ImplicitFlowLiveTest.java │ │ └── PasswordFlowLiveTest.java │ │ └── test │ │ ├── AuthenticationClaimsIntegrationTest.java │ │ └── ResourceServerIntegrationTest.java ├── oauth-resource-server-legacy-2 │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ ├── config │ │ │ │ ├── CorsFilter.java │ │ │ │ ├── CustomClaimVerifier.java │ │ │ │ ├── MethodSecurityConfig.java │ │ │ │ ├── OAuth2ResourceServerConfig.java │ │ │ │ ├── ResourceServerApplication.java │ │ │ │ ├── ResourceServerWebConfig.java │ │ │ │ └── SwaggerConfig.java │ │ │ │ └── web │ │ │ │ ├── controller │ │ │ │ ├── BarController.java │ │ │ │ ├── FooController.java │ │ │ │ └── UserController.java │ │ │ │ └── dto │ │ │ │ ├── Bar.java │ │ │ │ └── Foo.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── public.txt │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── test │ │ ├── JwtClaimsVerifierIntegrationTest.java │ │ ├── OAuth2SwaggerLiveTest.java │ │ └── ResourceServerIntegrationTest.java ├── oauth-ui-authorization-code-angular-legacy │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ ├── .editorconfig │ │ ├── angular.json │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── app │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── app.service.ts │ │ │ ├── foo.component.ts │ │ │ └── home.component.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.spec.json │ │ └── typings.d.ts │ │ ├── tsconfig.json │ │ └── tslint.json ├── oauth-ui-implicit-angular-legacy │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ ├── .editorconfig │ │ ├── angular.json │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── app │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── app.service.ts │ │ │ ├── foo.component.ts │ │ │ └── home.component.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.spec.json │ │ └── typings.d.ts │ │ ├── tsconfig.json │ │ └── tslint.json ├── oauth-ui-implicit-angularjs-legacy │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── config │ │ │ │ ├── UiApplication.java │ │ │ │ └── UiWebConfig.java │ │ ├── resources │ │ │ ├── application.properties │ │ │ ├── oauth-ng.js │ │ │ └── templates │ │ │ │ ├── header.html │ │ │ │ ├── index.html │ │ │ │ └── oauthTemp.html │ │ └── webapp │ │ │ └── resources │ │ │ └── oauth-ng.js │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── test │ │ └── UiIntegrationTest.java ├── oauth-ui-password-angular-legacy │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ ├── .angular-cli.json │ │ ├── .editorconfig │ │ ├── angular.json │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── app │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── app.service.ts │ │ │ ├── foo.component.ts │ │ │ ├── home.component.ts │ │ │ └── login.component.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.spec.json │ │ └── typings.d.ts │ │ ├── tsconfig.json │ │ └── tslint.json ├── oauth-ui-password-angularjs-legacy │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── config │ │ │ │ ├── CustomHttpServletRequest.java │ │ │ │ ├── CustomPostZuulFilter.java │ │ │ │ ├── CustomPreZuulFilter.java │ │ │ │ ├── SameSiteConfig.java │ │ │ │ ├── UiApplication.java │ │ │ │ └── UiWebConfig.java │ │ ├── resources │ │ │ ├── application.yml │ │ │ └── templates │ │ │ │ ├── header.html │ │ │ │ ├── index.html │ │ │ │ ├── login.html │ │ │ │ └── login_remember.html │ │ └── webapp │ │ │ └── resources │ │ │ └── angular-utf8-base64.min.js │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── test │ │ └── UiIntegrationTest.java ├── oauth-zuul-gateway │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── baeldung │ │ │ ├── GatewayApplication.java │ │ │ └── config │ │ │ └── GatewayConfiguration.java │ │ └── resources │ │ ├── application.yml │ │ └── public.txt └── pom.xml ├── oauth-resource-server ├── README.md ├── authorization-server │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── authserver │ │ │ │ ├── AuthorizationServerApp.java │ │ │ │ └── config │ │ │ │ ├── EmbeddedKeycloakApplication.java │ │ │ │ ├── EmbeddedKeycloakConfig.java │ │ │ │ ├── EmbeddedKeycloakRequestFilter.java │ │ │ │ ├── KeycloakServerProperties.java │ │ │ │ ├── RegularJsonConfigProviderFactory.java │ │ │ │ ├── Resteasy3Provider.java │ │ │ │ └── SimplePlatformProvider.java │ │ └── resources │ │ │ ├── META-INF │ │ │ ├── keycloak-server.json │ │ │ └── services │ │ │ │ ├── org.keycloak.common.util.ResteasyProvider │ │ │ │ ├── org.keycloak.config.ConfigProviderFactory │ │ │ │ └── org.keycloak.platform.PlatformProvider │ │ │ ├── application-customer.yml │ │ │ ├── application-feign.yml │ │ │ ├── application.yml │ │ │ ├── baeldung-realm.json │ │ │ ├── customer-realm.json │ │ │ ├── feign-realm.json │ │ │ └── mytest.jks │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── jwt │ │ ├── AuthorizationServerLiveTest.java │ │ └── ContextIntegrationTest.java ├── pom.xml ├── resource-server-jwt │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── jwt │ │ │ │ ├── JWTResourceServerApp.java │ │ │ │ ├── api │ │ │ │ ├── FooController.java │ │ │ │ └── PaymentController.java │ │ │ │ ├── config │ │ │ │ └── JWTSecurityConfig.java │ │ │ │ └── resource │ │ │ │ ├── Foo.java │ │ │ │ └── Payment.java │ │ └── resources │ │ │ ├── application-feign.yml │ │ │ └── application.yml │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── jwt │ │ ├── JWTResourceServerLiveTest.java │ │ └── SpringContextLiveTest.java └── resource-server-opaque │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── baeldung │ │ │ └── opaque │ │ │ ├── OpaqueResourceServerApp.java │ │ │ ├── api │ │ │ └── BarController.java │ │ │ ├── config │ │ │ └── OpaqueSecurityConfig.java │ │ │ └── resource │ │ │ └── Bar.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── baeldung │ └── opaque │ ├── ContextIntegrationTest.java │ └── OpaqueResourceServerLiveTest.java ├── oauth-rest ├── README.md ├── keycloak-custom-providers │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── auth │ │ │ │ └── provider │ │ │ │ ├── mapper │ │ │ │ └── CustomProtocolMapper.java │ │ │ │ └── user │ │ │ │ ├── CustomUser.java │ │ │ │ ├── CustomUserStorageProvider.java │ │ │ │ ├── CustomUserStorageProviderConstants.java │ │ │ │ ├── CustomUserStorageProviderFactory.java │ │ │ │ └── DbUtil.java │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ ├── org.keycloak.protocol.ProtocolMapper │ │ │ └── org.keycloak.storage.UserStorageProviderFactory │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── baeldung │ │ │ └── auth │ │ │ └── provider │ │ │ └── user │ │ │ ├── ContextIntegrationTest.java │ │ │ └── TestClientConfiguration.java │ │ └── resources │ │ ├── application-test.yml │ │ ├── custom-database-data.sql │ │ └── custom-provider-realm.json ├── oauth-authorization-server │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── auth │ │ │ │ ├── AuthorizationServerApp.java │ │ │ │ └── config │ │ │ │ ├── EmbeddedKeycloakApplication.java │ │ │ │ ├── EmbeddedKeycloakConfig.java │ │ │ │ ├── EmbeddedKeycloakRequestFilter.java │ │ │ │ ├── KeycloakServerProperties.java │ │ │ │ ├── RegularJsonConfigProviderFactory.java │ │ │ │ ├── Resteasy3Provider.java │ │ │ │ └── SimplePlatformProvider.java │ │ └── resources │ │ │ ├── META-INF │ │ │ ├── keycloak-server.json │ │ │ └── services │ │ │ │ ├── org.keycloak.common.util.ResteasyProvider │ │ │ │ ├── org.keycloak.config.ConfigProviderFactory │ │ │ │ └── org.keycloak.platform.PlatformProvider │ │ │ ├── application.yml │ │ │ └── baeldung-realm.json │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── auth │ │ └── ContextIntegrationTest.java ├── oauth-client-spring │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── client │ │ │ │ ├── ClientSpringApp.java │ │ │ │ ├── spring │ │ │ │ └── ClientSecurityConfig.java │ │ │ │ └── web │ │ │ │ ├── controller │ │ │ │ └── FooClientController.java │ │ │ │ └── model │ │ │ │ └── FooModel.java │ │ └── resources │ │ │ ├── application.yml │ │ │ ├── banner.txt │ │ │ └── templates │ │ │ ├── addfoo.html │ │ │ ├── foos.html │ │ │ └── index.html │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── client │ │ ├── ClientContextIntegrationTest.java │ │ ├── Oauth2ClientIntegrationTest.java │ │ └── Oauth2ClientLiveTest.java ├── oauth-resource-server │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── resource │ │ │ │ ├── ResourceServerApp.java │ │ │ │ ├── persistence │ │ │ │ ├── model │ │ │ │ │ └── Foo.java │ │ │ │ └── repository │ │ │ │ │ └── IFooRepository.java │ │ │ │ ├── service │ │ │ │ ├── IFooService.java │ │ │ │ └── impl │ │ │ │ │ └── FooServiceImpl.java │ │ │ │ ├── spring │ │ │ │ └── SecurityConfig.java │ │ │ │ └── web │ │ │ │ ├── controller │ │ │ │ ├── FooController.java │ │ │ │ └── UserInfoController.java │ │ │ │ └── dto │ │ │ │ └── FooDto.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── data.sql │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── resource │ │ ├── AuthorizationCodeLiveTest.java │ │ ├── ContextIntegrationTest.java │ │ ├── ImplicitFlowLiveTest.java │ │ └── PasswordFlowLiveTest.java ├── oauth-ui-authorization-code-angular-zuul │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── config │ │ │ │ ├── CustomHttpServletRequest.java │ │ │ │ ├── CustomPostZuulFilter.java │ │ │ │ ├── CustomPreZuulFilter.java │ │ │ │ ├── SameSiteConfig.java │ │ │ │ └── UiApplication.java │ │ └── resources │ │ │ ├── .editorconfig │ │ │ ├── angular.json │ │ │ ├── application.yml │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── app │ │ │ │ ├── app.component.ts │ │ │ │ ├── app.module.ts │ │ │ │ ├── app.service.ts │ │ │ │ ├── foo.component.ts │ │ │ │ └── home.component.ts │ │ │ ├── environments │ │ │ │ ├── environment.prod.ts │ │ │ │ └── environment.ts │ │ │ ├── index.html │ │ │ ├── main.ts │ │ │ ├── polyfills.ts │ │ │ ├── tsconfig.app.json │ │ │ ├── tsconfig.spec.json │ │ │ └── typings.d.ts │ │ │ ├── tsconfig.json │ │ │ └── tslint.json │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── test │ │ └── UiIntegrationTest.java ├── oauth-ui-authorization-code-angular │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ ├── .editorconfig │ │ ├── angular.json │ │ ├── browserslist │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── app │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── app.service.ts │ │ │ ├── foo.component.ts │ │ │ └── home.component.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.spec.json │ │ └── typings.d.ts │ │ ├── tsconfig.json │ │ └── tslint.json ├── oauth2-social-login │ ├── README.md │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── springsociallogin │ │ │ │ ├── SpringSocialLoginApplication.java │ │ │ │ ├── config │ │ │ │ └── SecurityConfig.java │ │ │ │ └── controller │ │ │ │ └── HomeController.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── springsociallogin │ │ └── SpringSocialLoginApplicationTests.java └── pom.xml ├── oauth-sso ├── README.md ├── pom.xml ├── sso-authorization-server │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── auth │ │ │ │ ├── AuthorizationServerApp.java │ │ │ │ └── config │ │ │ │ ├── EmbeddedKeycloakApplication.java │ │ │ │ ├── EmbeddedKeycloakConfig.java │ │ │ │ ├── EmbeddedKeycloakRequestFilter.java │ │ │ │ ├── KeycloakServerProperties.java │ │ │ │ ├── RegularJsonConfigProviderFactory.java │ │ │ │ ├── Resteasy3Provider.java │ │ │ │ └── SimplePlatformProvider.java │ │ └── resources │ │ │ ├── META-INF │ │ │ ├── keycloak-server.json │ │ │ └── services │ │ │ │ ├── org.keycloak.common.util.ResteasyProvider │ │ │ │ ├── org.keycloak.config.ConfigProviderFactory │ │ │ │ └── org.keycloak.platform.PlatformProvider │ │ │ ├── application.yml │ │ │ └── baeldung-realm.json │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── auth │ │ └── ContextIntegrationTest.java ├── sso-client-app-1 │ ├── .gitignore │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── client │ │ │ │ ├── SSOClientApplication.java │ │ │ │ ├── spring │ │ │ │ └── UiSecurityConfig.java │ │ │ │ └── web │ │ │ │ ├── controller │ │ │ │ └── FooClientController.java │ │ │ │ └── model │ │ │ │ └── FooModel.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── templates │ │ │ ├── foos.html │ │ │ └── index.html │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── client │ │ └── ContextIntegrationTest.java ├── sso-client-app-2 │ ├── .gitignore │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baeldung │ │ │ │ └── client │ │ │ │ ├── SSOClientApplication.java │ │ │ │ ├── spring │ │ │ │ └── UiSecurityConfig.java │ │ │ │ └── web │ │ │ │ ├── controller │ │ │ │ └── FooClientController.java │ │ │ │ └── model │ │ │ │ └── FooModel.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── templates │ │ │ ├── foos.html │ │ │ └── index.html │ │ └── test │ │ └── java │ │ └── com │ │ └── baeldung │ │ └── client │ │ └── ContextIntegrationTest.java └── sso-resource-server │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── baeldung │ │ │ └── resource │ │ │ ├── ResourceServerApp.java │ │ │ ├── persistence │ │ │ ├── model │ │ │ │ └── Foo.java │ │ │ └── repository │ │ │ │ └── IFooRepository.java │ │ │ ├── service │ │ │ ├── IFooService.java │ │ │ └── impl │ │ │ │ └── FooServiceImpl.java │ │ │ ├── spring │ │ │ └── SecurityConfig.java │ │ │ └── web │ │ │ ├── controller │ │ │ ├── FooController.java │ │ │ └── UserInfoController.java │ │ │ └── dto │ │ │ └── FooDto.java │ └── resources │ │ ├── application.yml │ │ └── data.sql │ └── test │ └── java │ └── com │ └── baeldung │ └── resource │ ├── AuthorizationCodeLiveTest.java │ └── ContextIntegrationTest.java └── pom.xml /.github/ISSUE_TEMPLATE/issue_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue Report 3 | about: Report an issue to help us improve 4 | title: '[ISSUE] ' 5 | --- 6 | 7 | **Article and Module Links** 8 | A link to the affected article and the affected module. You can find the link to the module in the Conclusion section in the "on Github" standard phase. 9 | 10 | **Describe the Issue** 11 | A clear and concise description of what the issue is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected Behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment (please complete the following information):** 27 | - OS: [e.g. Windows] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional Context** 32 | Add any other context about the issue here. 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | .settings/ 7 | .classpath 8 | .project 9 | .springBeans 10 | target/ 11 | .factorypath 12 | **/.sts4-cache/* 13 | 14 | *.iml 15 | .idea 16 | 17 | # Package Files # 18 | *.jar 19 | *.war 20 | *.ear 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # node 26 | node_modules/ 27 | node/ 28 | 29 | *.log 30 | 31 | ## OS ## 32 | .DS_Store 33 | .java-version 34 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Baeldung Tutorials 2 | First off, thank you for considering contributing to Baeldung Tutorials. 3 | 4 | ## Reporting Issues 5 | Before you submit an issue, please review the guidelines below: 6 | 7 | 1. **No Custom Modifications:** If your issue arises from any custom modifications you've made to the code in the repository, we won't be able to assist. We can only help if the issue is reproducible with the untouched codebase from this repo. If you're working with a modified version, consider asking for help on StackOverflow or other relevant forums. 8 | 2. **Use a clear and descriptive title** for the issue to identify the problem. 9 | 3. **Include a link to the article** you're having issues with. 10 | 4. **Describe the exact steps which reproduce the problem** in as many details as possible. 11 | 5. **Additional Details:** Offer any other context or descriptions that could be useful. Screenshots, error messages, copy/pasteable snippets, or logs can be immensely helpful. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Baeldung 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /nbbuild/ 22 | /dist/ 23 | /nbdist/ 24 | /.nb-gradle/ 25 | /build/ 26 | -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/java/com/baeldung/clientjsonlyreact/ClientJsOnlyReactApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.clientjsonlyreact; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ClientJsOnlyReactApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ClientJsOnlyReactApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/application.properties -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/common/images/default-profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/common/images/default-profile.png -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/common/js/code_verifier_functions.js: -------------------------------------------------------------------------------- 1 | function generate_code_verifier() { 2 | return random_string(48); 3 | } 4 | -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/common/js/common_functions.js: -------------------------------------------------------------------------------- 1 | function base64_urlencode(str) { 2 | return btoa(str) 3 | .replace(/\+/g, '-') 4 | .replace(/\//g, '_') 5 | .replace(/=/g, ''); 6 | } 7 | 8 | function generate_state() { 9 | return random_string(48); 10 | } 11 | 12 | function random_string(len) { 13 | var arr = new Uint8Array(len); 14 | window.crypto.getRandomValues(arr); 15 | var str = base64_urlencode(dec2bin(arr)); 16 | return str.substring(0, len); 17 | } 18 | 19 | function dec2hex(dec) { 20 | return ('0' + dec.toString(16)).substr(-2) 21 | } 22 | 23 | function dec2bin(arr) { 24 | return hex2bin(Array.from(arr, dec2hex).join('')); 25 | } 26 | 27 | function getParameterByName(name, url) { 28 | if (!url) url = window.location.href; 29 | name = name.replace(/[\[\]]/g, '\\$&'); 30 | var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), 31 | results = regex.exec(url); 32 | if (!results) return null; 33 | if (!results[2]) return ''; 34 | return decodeURIComponent(results[2].replace(/\+/g, ' ')); 35 | } -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/common/js/components/spinner.js: -------------------------------------------------------------------------------- 1 | // Spiner indicating something is being processed 2 | const Spinner = ({ spinnerText }) => ( 3 |
4 |

{spinnerText || 'Waiting...'}

5 |
6 |
7 | ) 8 | 9 | window.Spinner = Spinner; -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/common/js/provider_configs.js: -------------------------------------------------------------------------------- 1 | const AUTH0_APP_DOMAIN = 'https://bael-jsonly-pkce.auth0.com'; 2 | const PROVIDER_CONFIGS = { 3 | AUTH0: { 4 | AUTH_URL: AUTH0_APP_DOMAIN + "/authorize", 5 | CLIENT_ID: "R7L3XpkJrwcGEkuxrUdSpGAA9NgX9ouQ", 6 | CONFIGURED_REDIRECT_URIS:{ 7 | STEP_BY_STEP: "http://localhost:8080/pkce-stepbystep/popup_code_handler.html", 8 | REAL_CASE: "http://localhost:8080/pkce-realcase/popup_code_handler.html", 9 | SIMPLE: "http://localhost:8080/pkce-simple/callback.html" 10 | }, 11 | TOKEN_URI: AUTH0_APP_DOMAIN + "/oauth/token", 12 | SCOPES: 'openid profile email', 13 | AUDIENCE: "pkceclient.baeldung.com", 14 | PROFILE_URL: AUTH0_APP_DOMAIN + "/userinfo", 15 | PROFILE_FIELDS: { 16 | NAME: "nickname", 17 | EMAIL: "email", 18 | PICTURE: "picture" 19 | }, 20 | // Renew Token Period for in seconds: 21 | RENEW_TOKEN_PERIOD: 60 22 | } 23 | } 24 | 25 | window.PROVIDER_CONFIGS = PROVIDER_CONFIGS; -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/pkce-realcase/js/components/pages/listing_item.js: -------------------------------------------------------------------------------- 1 | // Listing Item 2 | const ListingItem = ({ id, value, onDeleteFn }) => ( 3 |
4 |
5 |
{value}
6 |
7 |
8 | ) 9 | 10 | window.ListingItem = ListingItem; -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/pkce-realcase/js/resource_configs.js: -------------------------------------------------------------------------------- 1 | const RESOURCE_CONFIGS = { 2 | SAVE_COLOR_URL: 'http://localhost:8081/colors', 3 | DELETE_COLOR_URL: 'http://localhost:8081/colors/{id}', 4 | GET_COLORS_URL: 'http://localhost:8081/colors', 5 | } 6 | 7 | window.RESOURCE_CONFIGS = RESOURCE_CONFIGS; -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/pkce-simple/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/pkce-stepbystep/js/components/steps/step0.js: -------------------------------------------------------------------------------- 1 | // Step 0 - Initiate Process 2 | const Step0 = ({ providers, nextStepFn, nextStepStarted }) => ( 3 |
4 |

JS OAuth Client using PKCE - Step By Step

5 |
Click to start the authentication process, step by step.
6 |
Note: Most providers don't support PKCE for SPA yet, 7 | resulting in an error retrieving when retrieving the Token (CORS not enabled for that endpoint). 8 |
9 | At the moment of creating the tutorial, only Auth0 works properly
10 |
11 | {providers.map((provider) => 12 | ()) 13 | } 14 |
15 |
16 | ) 17 | 18 | window.Step0 = Step0; -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/pkce-stepbystep/js/components/steps/step1.js: -------------------------------------------------------------------------------- 1 | // Step 1 - Create Codes 2 | const Step1 = ({ codeVerifier, codeChallenge, state, nextStepFn, nextStepStarted }) => ( 3 |
4 |

Step 1 - Create the codes

5 |
The client must generate the tipical 'state' value to compare later and avoid CSRF:
6 |
{state}
7 |
We also generate a "Code Verifier" per request:
8 |
{codeVerifier}
9 |
Additionally, it should transform the previous code using a S256 transfromation method. This is called the "Code Challenge":
10 |
{codeChallenge}
11 |
12 | 13 |
14 |
15 | ) 16 | 17 | window.Step1 = Step1; -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/pkce-stepbystep/js/components/steps/step2.js: -------------------------------------------------------------------------------- 1 | // Step 2 - Login & obteain access token 2 | const Step2 = ({ accessToken, authCode, popup, nextStepFn, nextStepStarted }) => { 3 | 4 | return (
5 |

Step 2 - Login

6 | {authCode 7 | && (
8 |
Provider retrieved authorization code:
9 |
{authCode}
10 |
) 11 | } 12 | {accessToken 13 | && (
14 |
Used 'Code Verifier' to obtain the Access Token!
15 |
{accessToken}
16 |
) 17 | } 18 | {!!popup 19 | ? 20 | : (
21 | 22 |
) 23 | } 24 |
25 | ) 26 | }; 27 | 28 | window.Step2 = Step2; -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/main/resources/static/pkce-stepbystep/js/components/steps/step3.js: -------------------------------------------------------------------------------- 1 | // Step 3 - Secured User Information 2 | const Step3 = ({ profile }) => { 3 | const { name, lastName, email, picture } = profile; 4 | return ( 5 |
6 |

Step 3 - Retrieving Secured Resource

7 |
8 |
9 | {name ? name + ' ' : ''} {lastName || ''} 10 |
11 |
12 | 13 |
14 |
15 | {email || ''} 16 |
17 |
18 |
19 | ) 20 | }; 21 | 22 | window.Step3 = Step3; -------------------------------------------------------------------------------- /clients-SPA-legacy/clients-js-only-react-legacy/src/test/java/com/baeldung/clientjsonlyreact/ApplicationContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.clientjsonlyreact; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ApplicationContextIntegrationTest { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /clients-SPA-legacy/oauth-resource-server-auth0-legacy/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /nbbuild/ 22 | /dist/ 23 | /nbdist/ 24 | /.nb-gradle/ 25 | /build/ 26 | -------------------------------------------------------------------------------- /clients-SPA-legacy/oauth-resource-server-auth0-legacy/src/main/java/com/baeldung/resourceserverauth0/OauthResourceServerAuth0Application.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resourceserverauth0; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class OauthResourceServerAuth0Application { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(OauthResourceServerAuth0Application.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /clients-SPA-legacy/oauth-resource-server-auth0-legacy/src/main/java/com/baeldung/resourceserverauth0/dao/ColorRepository.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resourceserverauth0.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import com.baeldung.resourceserverauth0.model.Color; 6 | 7 | public interface ColorRepository extends CrudRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /clients-SPA-legacy/oauth-resource-server-auth0-legacy/src/main/java/com/baeldung/resourceserverauth0/model/Color.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resourceserverauth0.model; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.Id; 6 | 7 | @Entity 8 | public class Color { 9 | 10 | @Id 11 | @GeneratedValue 12 | private Long id; 13 | 14 | private String value; 15 | 16 | protected Color() { 17 | } 18 | 19 | public Color(String value) { 20 | this.value = value; 21 | } 22 | 23 | public String getValue() { 24 | return this.value; 25 | } 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /clients-SPA-legacy/oauth-resource-server-auth0-legacy/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | security: 3 | oauth2: 4 | resourceserver: 5 | jwt: 6 | jwk-set-uri: https://bael-jsonly-pkce.auth0.com/.well-known/jwks.json 7 | user: 8 | password: pass 9 | datasource: 10 | url: jdbc:h2:mem:bael-colors 11 | username: sa 12 | password: 13 | driver-class-name: org.h2.Driver 14 | server: 15 | port: 8081 -------------------------------------------------------------------------------- /clients-SPA-legacy/oauth-resource-server-auth0-legacy/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | insert into color 2 | values(1001, 'red'); 3 | 4 | insert into color 5 | values(1002, 'green'); 6 | 7 | insert into color 8 | values(1003, 'blue'); -------------------------------------------------------------------------------- /clients-SPA-legacy/oauth-resource-server-auth0-legacy/src/test/java/com/baeldung/resourceserverauth0/OauthResourceServerAuth0ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resourceserverauth0; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class OauthResourceServerAuth0ApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /oauth-authorization-server/README.md: -------------------------------------------------------------------------------- 1 | ## Spring Security OAuth Authorization Server 2 | 3 | ### Relevant information: 4 | 5 | This module demonstrates OAuth authorization flow using Spring Authorization Server, Spring OAuth Resource Server and 6 | Spring OAuth Client. 7 | 8 | - Run the Authorization Server from the `spring-authorization-server` module 9 | - IMPORTANT: Modify the `/etc/hosts` file and add the entry `127.0.0.1 auth-server` 10 | - Run the Resource Server from `resource-server` module 11 | - Run the client from `client-server` module 12 | - Go to `http://127.0.0.1:8080/articles` 13 | - Enter the credentials `admin/password` 14 | - The module uses the new OAuth stack with Java 11 15 | 16 | ### Relevant Articles: 17 | 18 | - [Spring Security OAuth Authorization Server](https://www.baeldung.com/spring-security-oauth-auth-server) 19 | - [Add Authorities as Custom Claims in JWT Access Tokens in Spring Authorization Server](https://www.baeldung.com/spring-jwt-access-tokens-authorities-custom-claims) 20 | -------------------------------------------------------------------------------- /oauth-authorization-server/client-server/src/main/java/com/baeldung/OAuth2ClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class OAuth2ClientApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(OAuth2ClientApplication.class, args); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /oauth-authorization-server/client-server/src/main/java/com/baeldung/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 6 | import org.springframework.security.web.SecurityFilterChain; 7 | 8 | import static org.springframework.security.config.Customizer.withDefaults; 9 | 10 | @EnableWebSecurity 11 | public class SecurityConfig { 12 | 13 | @Bean 14 | SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 15 | http 16 | .authorizeHttpRequests(authorizeRequests -> 17 | authorizeRequests.anyRequest().authenticated() 18 | ) 19 | .oauth2Login(oauth2Login -> 20 | oauth2Login.loginPage("/oauth2/authorization/articles-client-oidc")) 21 | .oauth2Client(withDefaults()); 22 | return http.build(); 23 | } 24 | } -------------------------------------------------------------------------------- /oauth-authorization-server/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | Spring Security OAuth Authorization Server 5 | 6 | com.baeldung 7 | oauth-authorization-server 8 | 0.1.0-SNAPSHOT 9 | pom 10 | 11 | 12 | spring-authorization-server 13 | resource-server 14 | client-server 15 | 16 | 17 | 18 | 17 19 | 20 | 21 | -------------------------------------------------------------------------------- /oauth-authorization-server/resource-server/src/main/java/com/baeldung/OAuth2ResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class OAuth2ResourceServerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(OAuth2ResourceServerApplication.class, args); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /oauth-authorization-server/resource-server/src/main/java/com/baeldung/config/ResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.Customizer; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 8 | import org.springframework.security.web.SecurityFilterChain; 9 | 10 | @Configuration 11 | @EnableWebSecurity 12 | public class ResourceServerConfig { 13 | 14 | @Bean 15 | SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 16 | http.securityMatcher("/articles/**") 17 | .authorizeHttpRequests(authorize -> authorize.anyRequest() 18 | .hasAuthority("SCOPE_articles.read")) 19 | .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); 20 | return http.build(); 21 | } 22 | } -------------------------------------------------------------------------------- /oauth-authorization-server/resource-server/src/main/java/com/baeldung/web/ArticlesController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class ArticlesController { 8 | 9 | @GetMapping("/articles") 10 | public String[] getArticles() { 11 | return new String[]{"Article 1", "Article 2", "Article 3"}; 12 | } 13 | } -------------------------------------------------------------------------------- /oauth-authorization-server/resource-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8090 3 | 4 | logging: 5 | level: 6 | root: INFO 7 | org.springframework.web: INFO 8 | org.springframework.security: INFO 9 | org.springframework.security.oauth2: INFO 10 | 11 | spring: 12 | security: 13 | oauth2: 14 | resourceserver: 15 | jwt: 16 | issuer-uri: http://auth-server:9000 -------------------------------------------------------------------------------- /oauth-authorization-server/spring-authorization-server/src/main/java/com/baeldung/OAuth2AuthorizationServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class OAuth2AuthorizationServerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(OAuth2AuthorizationServerApplication.class, args); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /oauth-authorization-server/spring-authorization-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9000 3 | 4 | logging: 5 | level: 6 | root: INFO 7 | org.springframework.web: INFO 8 | org.springframework.security: INFO 9 | org.springframework.security.oauth2: INFO 10 | 11 | spring: 12 | security: 13 | oauth2: 14 | authorizationserver: 15 | issuer: http://auth-server:9000 16 | client: 17 | articles-client: 18 | registration: 19 | client-id: articles-client 20 | client-secret: "{noop}secret" 21 | client-name: Articles Client 22 | client-authentication-methods: 23 | - client_secret_basic 24 | authorization-grant-types: 25 | - authorization_code 26 | - refresh_token 27 | redirect-uris: 28 | - http://127.0.0.1:8080/login/oauth2/code/articles-client-oidc 29 | - http://127.0.0.1:8080/authorized 30 | scopes: 31 | - openid 32 | - articles.read 33 | -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/README.md: -------------------------------------------------------------------------------- 1 | ## JWS + JWK in a Spring Security OAuth2 Application 2 | 3 | ### Relevant information: 4 | 5 | - This module uses the OAuth stack with Java 8 6 | 7 | ### Relevant Articles: 8 | 9 | - [JWS + JWK in a Spring Security OAuth2 Application](https://www.baeldung.com/spring-security-oauth2-jws-jwk) 10 | -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-authorization-server-jws-jwk-legacy/src/main/java/com/baeldung/AuthServerApp.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class AuthServerApp { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(AuthServerApp.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-authorization-server-jws-jwk-legacy/src/main/java/com/baeldung/web/JwkSetRestController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import com.nimbusds.jose.jwk.JWKSet; 10 | 11 | @RestController 12 | public class JwkSetRestController { 13 | 14 | @Autowired 15 | private JWKSet jwkSet; 16 | 17 | @GetMapping("/.well-known/jwks.json") 18 | public Map keys() { 19 | return this.jwkSet.toJSONObject(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-authorization-server-jws-jwk-legacy/src/main/resources/.keystore-oauth2-demo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jws-jwk-legacy/oauth-authorization-server-jws-jwk-legacy/src/main/resources/.keystore-oauth2-demo -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-authorization-server-jws-jwk-legacy/src/main/resources/bael-jwt.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jws-jwk-legacy/oauth-authorization-server-jws-jwk-legacy/src/main/resources/bael-jwt.jks -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-authorization-server-jws-jwk-legacy/src/main/resources/filtered/application.properties: -------------------------------------------------------------------------------- 1 | server.servlet.context-path=/sso-auth-server 2 | server.port=8081 3 | logging.level.org=INFO 4 | security.oauth2.client.client-id=bael-client 5 | security.oauth2.client.client-secret=bael-secret 6 | 7 | ### Only for academic purposes, these endpoints shouldn't be unsecured 8 | security.oauth2.authorization.check-token-access=permitAll() 9 | security.oauth2.authorization.token-key-access=permitAll() 10 | -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-authorization-server-jws-jwk-legacy/src/test/java/com/baeldung/SpringContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.junit.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | public class SpringContextIntegrationTest { 8 | 9 | @Test 10 | public void whenContextInitializes_thenNoExceptionsTriggered() throws Exception { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-resource-server-jws-jwk-legacy/src/main/java/com/baeldung/ResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 6 | 7 | @SpringBootApplication 8 | @EnableResourceServer 9 | public class ResourceServerApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ResourceServerApplication.class, args); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-resource-server-jws-jwk-legacy/src/main/java/com/baeldung/web/controller/FooController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.controller; 2 | 3 | import org.apache.commons.lang3.RandomStringUtils; 4 | import org.springframework.security.access.prepost.PreAuthorize; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import com.baeldung.web.dto.Foo; 11 | 12 | @RestController 13 | @RequestMapping("/foos") 14 | public class FooController { 15 | 16 | @PreAuthorize("#oauth2.hasScope('read')") 17 | @GetMapping("/{id}") 18 | public Foo retrieveFoo(@PathVariable("id") Long id) { 19 | return new Foo(id, RandomStringUtils.randomAlphabetic(6)); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-resource-server-jws-jwk-legacy/src/main/java/com/baeldung/web/dto/Foo.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.dto; 2 | 3 | public class Foo { 4 | private long id; 5 | private String name; 6 | 7 | public Foo() { 8 | super(); 9 | } 10 | 11 | public Foo(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | // 19 | 20 | public long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(final long id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(final String name) { 33 | this.name = name; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /oauth-jws-jwk-legacy/oauth-resource-server-jws-jwk-legacy/src/test/java/com/baeldung/SpringContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.junit.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | public class SpringContextIntegrationTest { 8 | 9 | @Test 10 | public void whenContextInitializes_thenNoExceptionsTriggered() throws Exception { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/README.md: -------------------------------------------------------------------------------- 1 | ### Relevant Articles: 2 | 3 | - [Accessing Keycloak Endpoints Using Postman](https://www.baeldung.com/postman-keycloak-endpoints) 4 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/java/com/baeldung/jwt/config/RegularJsonConfigProviderFactory.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.config; 2 | 3 | import org.keycloak.services.util.JsonConfigProviderFactory; 4 | 5 | public class RegularJsonConfigProviderFactory extends JsonConfigProviderFactory { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/META-INF/services/org.keycloak.common.util.ResteasyProvider: -------------------------------------------------------------------------------- 1 | com.baeldung.jwt.config.Resteasy3Provider -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/META-INF/services/org.keycloak.config.ConfigProviderFactory: -------------------------------------------------------------------------------- 1 | com.baeldung.jwt.config.RegularJsonConfigProviderFactory -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/META-INF/services/org.keycloak.platform.PlatformProvider: -------------------------------------------------------------------------------- 1 | com.baeldung.jwt.config.SimplePlatformProvider -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8083 3 | 4 | spring: 5 | datasource: 6 | username: sa 7 | url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE 8 | 9 | keycloak: 10 | server: 11 | contextPath: /auth 12 | adminUser: 13 | username: bael-admin 14 | password: pass 15 | realmImportFile: baeldung-realm.json 16 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/mytest.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/mytest.jks -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/baeldung.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/baeldung.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/favicon.ico -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/icon-sidebar-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/icon-sidebar-active.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/keycloak-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/keycloak-logo.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/resources/img/logo.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/account/theme.properties: -------------------------------------------------------------------------------- 1 | parent=base 2 | import=common/keycloak 3 | 4 | styles=node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css css/account.css 5 | 6 | ##### css classes for form buttons 7 | # main class used for all buttons 8 | kcButtonClass=btn 9 | # classes defining priority of the button - primary or default (there is typically only one priority button for the form) 10 | kcButtonPrimaryClass=btn-primary 11 | kcButtonDefaultClass=btn-default 12 | # classes defining size of the button 13 | kcButtonLargeClass=btn-lg 14 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/messages/messages_en.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=Enter Username: 2 | password=Enter Password: -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/favicon.ico -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-error-arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-error-arrow-down.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-error-sign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-error-sign.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-success-arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-success-arrow-down.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-success-sign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-success-sign.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-warning-arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-warning-arrow-down.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-warning-sign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/feedback-warning-sign.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/keycloak-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/keycloak-bg.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/keycloak-logo-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/keycloak-logo-text.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/keycloak-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/login/resources/img/keycloak-logo.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/admin-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/admin-console.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/alert.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/bg.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/bug.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/favicon.ico -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/geo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/geo.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/jboss_community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/jboss_community.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/keycloak-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/keycloak-project.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/keycloak_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/keycloak_logo.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/logo.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/mail.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/resources/user.png -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/main/resources/themes/custom/welcome/theme.properties: -------------------------------------------------------------------------------- 1 | import=common/keycloak 2 | 3 | styles=node_modules/patternfly/dist/css/patternfly.css node_modules/patternfly/dist/css/patternfly-additions.css css/welcome.css 4 | 5 | documentationUrl=https://www.keycloak.org/documentation.html 6 | displayCommunityLinks=true -------------------------------------------------------------------------------- /oauth-jwt/jwt-auth-server/src/test/java/com/baeldung/jwt/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | import com.baeldung.jwt.JWTAuthorizationServerApp; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = { JWTAuthorizationServerApp.class }) 12 | public class ContextIntegrationTest { 13 | 14 | @Test 15 | public void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/JWTResourceServerApp.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class JWTResourceServerApp { 8 | 9 | public static void main(String[] args) throws Exception { 10 | SpringApplication.run(JWTResourceServerApp.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/persistence/repository/IFooRepository.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.persistence.repository; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | 5 | import com.baeldung.jwt.persistence.model.Foo; 6 | 7 | public interface IFooRepository extends PagingAndSortingRepository { 8 | } 9 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/service/IFooService.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.service; 2 | 3 | import java.util.Optional; 4 | 5 | import com.baeldung.jwt.persistence.model.Foo; 6 | 7 | 8 | public interface IFooService { 9 | Optional findById(Long id); 10 | 11 | Foo save(Foo foo); 12 | 13 | Iterable findAll(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/service/impl/FooServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.service.impl; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.stereotype.Service; 6 | 7 | import com.baeldung.jwt.persistence.model.Foo; 8 | import com.baeldung.jwt.persistence.repository.IFooRepository; 9 | import com.baeldung.jwt.service.IFooService; 10 | 11 | @Service 12 | public class FooServiceImpl implements IFooService { 13 | 14 | private IFooRepository fooRepository; 15 | 16 | public FooServiceImpl(IFooRepository fooRepository) { 17 | this.fooRepository = fooRepository; 18 | } 19 | 20 | @Override 21 | public Optional findById(Long id) { 22 | return fooRepository.findById(id); 23 | } 24 | 25 | @Override 26 | public Foo save(Foo foo) { 27 | return fooRepository.save(foo); 28 | } 29 | 30 | @Override 31 | public Iterable findAll() { 32 | return fooRepository.findAll(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/spring/OrganizationSubClaimAdapter.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.spring; 2 | 3 | import java.util.Collections; 4 | import java.util.Map; 5 | 6 | import org.springframework.core.convert.converter.Converter; 7 | import org.springframework.security.oauth2.jwt.MappedJwtClaimSetConverter; 8 | 9 | public class OrganizationSubClaimAdapter implements Converter, Map> { 10 | 11 | private final MappedJwtClaimSetConverter delegate = MappedJwtClaimSetConverter.withDefaults(Collections.emptyMap()); 12 | 13 | public Map convert(Map claims) { 14 | Map convertedClaims = this.delegate.convert(claims); 15 | 16 | String organization = convertedClaims.get("organization") != null ? (String) convertedClaims.get("organization") 17 | : "unknown"; 18 | convertedClaims.put("organization", organization.toUpperCase()); 19 | 20 | return convertedClaims; 21 | } 22 | } -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/web/controller/CustomUserAttrController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.web.controller; 2 | 3 | import java.util.Collections; 4 | import java.util.Map; 5 | 6 | import org.springframework.security.core.annotation.AuthenticationPrincipal; 7 | import org.springframework.security.oauth2.jwt.Jwt; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @RestController 12 | public class CustomUserAttrController { 13 | 14 | @GetMapping("/user/info/custom") 15 | public Map getUserInfo(@AuthenticationPrincipal Jwt principal) { 16 | return Collections.singletonMap("DOB", principal.getClaimAsString("DOB")); 17 | } 18 | } -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/web/controller/UserInfoController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.web.controller; 2 | 3 | import java.util.Collections; 4 | import java.util.Hashtable; 5 | import java.util.Map; 6 | 7 | import org.springframework.security.core.annotation.AuthenticationPrincipal; 8 | import org.springframework.security.oauth2.jwt.Jwt; 9 | import org.springframework.web.bind.annotation.CrossOrigin; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | public class UserInfoController { 15 | 16 | @CrossOrigin(origins = "http://localhost:8084") 17 | @GetMapping("/user/info") 18 | public Map getUserInfo(@AuthenticationPrincipal Jwt principal) { 19 | Map map = new Hashtable(); 20 | map.put("user_name", principal.getClaimAsString("preferred_username")); 21 | map.put("organization", principal.getClaimAsString("organization")); 22 | return Collections.unmodifiableMap(map); 23 | } 24 | } -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/java/com/baeldung/jwt/web/dto/FooDto.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.web.dto; 2 | 3 | public class FooDto { 4 | private long id; 5 | private String name; 6 | 7 | public FooDto() { 8 | super(); 9 | } 10 | 11 | public FooDto(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | // 19 | 20 | public long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(final long id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(final String name) { 33 | this.name = name; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | servlet: 4 | context-path: /jwt-resource-server 5 | 6 | ####### resource server configuration properties 7 | spring: 8 | jpa: 9 | defer-datasource-initialization: true 10 | security: 11 | oauth2: 12 | resourceserver: 13 | jwt: 14 | issuer-uri: http://localhost:8083/auth/realms/baeldung 15 | jwk-set-uri: http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/certs -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO Foo(id, name) VALUES (1, 'Foo 1'); 2 | INSERT INTO Foo(id, name) VALUES (2, 'Foo 2'); 3 | INSERT INTO Foo(id, name) VALUES (3, 'Foo 3'); 4 | 5 | -------------------------------------------------------------------------------- /oauth-jwt/jwt-resource-server/src/test/java/com/baeldung/jwt/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | import com.baeldung.jwt.JWTResourceServerApp; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = { JWTResourceServerApp.class }) 12 | public class ContextIntegrationTest { 13 | 14 | @Test 15 | public void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/README.md: -------------------------------------------------------------------------------- 1 | ## Spring Security OAuth - Authorization Code JWT 2 | A simple Angular client for Authorization Code Flow to demonstrate functionality offered by JWT. 3 | 4 | ## Run the Module 5 | To run the application, first make sure authorization and resource server is already running 6 | Then, build the app using command line: 7 | ``` 8 | mvn clean install 9 | ``` 10 | 11 | Change directory to src/main/resources: 12 | ``` 13 | cd src/main/resources 14 | ``` 15 | 16 | Finally, run our app on port 8084: 17 | ``` 18 | npm start 19 | ``` 20 | 21 | Hit the app: 22 | http://localhost:8084/ -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 12 | ` 13 | }) 14 | 15 | export class AppComponent {} -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { HttpClientModule } from '@angular/common/http'; 4 | import { RouterModule } from '@angular/router'; 5 | 6 | import { AppComponent } from './app.component'; 7 | import { HomeComponent } from './home.component'; 8 | import { FooComponent } from './foo.component'; 9 | 10 | @NgModule({ 11 | declarations: [ 12 | AppComponent, 13 | HomeComponent, 14 | FooComponent 15 | ], 16 | imports: [ 17 | BrowserModule, 18 | HttpClientModule, 19 | RouterModule.forRoot([ 20 | { path: '', component: HomeComponent, pathMatch: 'full' }], {onSameUrlNavigation: 'reload'}) 21 | ], 22 | providers: [], 23 | bootstrap: [AppComponent] 24 | }) 25 | export class AppModule { } 26 | -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Authorization Code 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "main.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts", 15 | "polyfills.ts" 16 | ], 17 | "include": [ 18 | "**/*.spec.ts", 19 | "**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /oauth-jwt/oauth-ui-authorization-code-angular-jwt/src/main/resources/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "downlevelIteration": true, 5 | "module": "esnext", 6 | "outDir": "./dist/out-tsc", 7 | "baseUrl": "src", 8 | "sourceMap": true, 9 | "declaration": false, 10 | "moduleResolution": "node", 11 | "emitDecoratorMetadata": true, 12 | "experimentalDecorators": true, 13 | "target": "ES2022", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2016", 19 | "dom" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /oauth-jwt/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | JWT with OAuth2 Stack in Spring Security 5 5 | 6 | com.baeldung 7 | oauth-jwt 8 | 0.1.0-SNAPSHOT 9 | pom 10 | 11 | 12 | jwt-auth-server 13 | jwt-resource-server 14 | oauth-ui-authorization-code-angular-jwt 15 | 16 | 17 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-authorization-server-legacy/src/main/java/com/baeldung/config/AuthorizationServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | 7 | @SpringBootApplication(scanBasePackages = "com.baeldung") 8 | public class AuthorizationServerApplication extends SpringBootServletInitializer { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(AuthorizationServerApplication.class, args); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-authorization-server-legacy/src/main/java/com/baeldung/config/CustomTokenEnhancer.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; 9 | import org.springframework.security.oauth2.common.OAuth2AccessToken; 10 | import org.springframework.security.oauth2.provider.OAuth2Authentication; 11 | import org.springframework.security.oauth2.provider.token.TokenEnhancer; 12 | 13 | public class CustomTokenEnhancer implements TokenEnhancer { 14 | 15 | @Override 16 | public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { 17 | final Map additionalInfo = new HashMap<>(); 18 | additionalInfo.put("organization", authentication.getName() + randomAlphabetic(4)); 19 | ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo); 20 | return accessToken; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-authorization-server-legacy/src/main/java/com/baeldung/model/Employee.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.model; 2 | 3 | public class Employee { 4 | private String email; 5 | private String name; 6 | 7 | public Employee() { 8 | } 9 | 10 | public Employee(String email, String name) { 11 | super(); 12 | this.email = email; 13 | this.name = name; 14 | } 15 | 16 | public String getEmail() { 17 | return email; 18 | } 19 | 20 | public void setEmail(String email) { 21 | this.email = email; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public void setName(String name) { 29 | this.name = name; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-authorization-server-legacy/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.servlet.context-path=/spring-security-oauth-server 2 | server.port=8081 3 | 4 | #spring.profiles.active=dev 5 | 6 | #logging.level.org.springframework=DEBUG -------------------------------------------------------------------------------- /oauth-legacy/oauth-authorization-server-legacy/src/main/resources/mytest.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-legacy/oauth-authorization-server-legacy/src/main/resources/mytest.jks -------------------------------------------------------------------------------- /oauth-legacy/oauth-authorization-server-legacy/src/main/resources/persistence.properties: -------------------------------------------------------------------------------- 1 | ################### DataSource Configuration ########################## 2 | 3 | ###################### H2 ##################### 4 | jdbc.driverClassName=org.h2.Driver 5 | jdbc.url=jdbc:h2:~/data/oauth2;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE 6 | jdbc.user=sa 7 | jdbc.pass= 8 | 9 | 10 | ##################### MySQL ##################### 11 | #jdbc.driverClassName=com.mysql.jdbc.Driver 12 | #jdbc.url=jdbc:mysql://localhost:3306/oauth2?createDatabaseIfNotExist=true 13 | #jdbc.user=tutorialuser 14 | #jdbc.pass=tutorialmy5ql 15 | 16 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-authorization-server-legacy/src/test/java/com/baeldung/test/AuthServerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.baeldung.config.AuthorizationServerApplication; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest(classes = AuthorizationServerApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 13 | public class AuthServerIntegrationTest { 14 | 15 | @Test 16 | public void whenLoadApplication_thenSuccess() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/api-gateway-zuul-1/src/main/java/com/baeldung/ApiGatewayApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 7 | 8 | @SpringBootApplication 9 | @EnableZuulProxy 10 | @EnableDiscoveryClient 11 | public class ApiGatewayApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(ApiGatewayApplication.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/api-gateway-zuul-1/src/test/java/com/baeldung/ApiGatewayApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.autoconfigure.web.ServerProperties; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 | 11 | import com.baeldung.ApiGatewayApplication; 12 | 13 | @RunWith(SpringJUnit4ClassRunner.class) 14 | @SpringBootTest(classes = ApiGatewayApplication.class) 15 | public class ApiGatewayApplicationTests { 16 | 17 | @Configuration 18 | public static class ByPassConfiguration { 19 | @Bean 20 | public ServerProperties serverProperties() { 21 | return new ServerProperties(); 22 | } 23 | } 24 | 25 | @Test 26 | public void contextLoads() { 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/authorization-server-1/src/main/java/com/baeldung/UaaServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | @EnableDiscoveryClient 9 | public class UaaServiceApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(UaaServiceApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/authorization-server-1/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: authorization-server-1 4 | 5 | server: 6 | port: 8769 7 | context-path: /authorization-server-1 8 | use-forward-headers: false 9 | 10 | eureka: 11 | instance: 12 | hostname: localhost 13 | port: 8761 14 | client: 15 | serviceUrl: 16 | defaultZone: http://${eureka.instance.hostname}:${eureka.instance.port}/eureka/ 17 | 18 | security: 19 | basic: 20 | enabled: false 21 | user: 22 | password: password 23 | ignored: /css/**,/js/**,/favicon.ico,/webjars/** 24 | 25 | logging: 26 | level.org.springframework.security: DEBUG 27 | 28 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/authorization-server-1/src/main/resources/keystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-legacy/oauth-microservices/1x/authorization-server-1/src/main/resources/keystore.jks -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/authorization-server-1/src/main/resources/templates/authorize.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |

Please Confirm

7 | 8 |

9 | Do you authorize "${authorizationRequest.clientId}" at "${authorizationRequest.redirectUri}" to access your 10 | protected resources 11 | with scope ${authorizationRequest.scope?join(", ")}. 12 |

13 |
15 | 16 | 17 |
18 |
20 | 21 | 22 |
23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/authorization-server-1/src/main/resources/templates/login.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 | 16 |
17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/authorization-server-1/src/test/java/com/baeldung/UaaServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | 8 | import com.baeldung.UaaServiceApplication; 9 | 10 | @RunWith(SpringJUnit4ClassRunner.class) 11 | @SpringBootTest(classes = UaaServiceApplication.class) 12 | public class UaaServiceApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/resource-server-mvc-1/src/main/java/com/baeldung/ResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 7 | 8 | @SpringBootApplication 9 | @EnableResourceServer 10 | @EnableDiscoveryClient 11 | class ResourceServerApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(ResourceServerApplication.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/resource-server-mvc-1/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: resource-server-mvc-1 4 | 5 | server: 6 | port: 8870 7 | 8 | eureka: 9 | instance: 10 | hostname: localhost 11 | port: 8761 12 | client: 13 | serviceUrl: 14 | defaultZone: http://${eureka.instance.hostname}:${eureka.instance.port}/eureka/ 15 | 16 | security: 17 | basic: 18 | enabled: false 19 | oauth2: 20 | resource: 21 | jwt: 22 | keyValue: "abc" 23 | id: fooScope 24 | service-id: ${PREFIX:}resource 25 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/resource-server-mvc-1/src/test/java/com/baeldung/ResourceServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | import org.springframework.test.context.web.WebAppConfiguration; 8 | 9 | import com.baeldung.ResourceServerApplication; 10 | 11 | @RunWith(SpringJUnit4ClassRunner.class) 12 | @SpringBootTest(classes = ResourceServerApplication.class) 13 | @WebAppConfiguration 14 | public class ResourceServerApplicationTests { 15 | 16 | @Test 17 | public void contextLoads() { 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/resource-server-mvc-no-oauth-1/src/main/java/com/baeldung/ResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | @EnableDiscoveryClient 9 | class ResourceServerApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ResourceServerApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/resource-server-mvc-no-oauth-1/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: resource-server-mvc-1 4 | 5 | server: 6 | port: 8870 7 | 8 | eureka: 9 | instance: 10 | hostname: localhost 11 | port: 8761 12 | client: 13 | serviceUrl: 14 | defaultZone: http://${eureka.instance.hostname}:${eureka.instance.port}/eureka/ 15 | 16 | security: 17 | basic: 18 | enabled: false 19 | oauth2: 20 | resource: 21 | jwt: 22 | keyValue: "abc" 23 | id: fooScope 24 | service-id: ${PREFIX:}resource 25 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/resource-server-mvc-no-oauth-1/src/test/java/com/baeldung/ResourceServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | import org.springframework.test.context.web.WebAppConfiguration; 8 | 9 | import com.baeldung.ResourceServerApplication; 10 | 11 | @RunWith(SpringJUnit4ClassRunner.class) 12 | @SpringBootTest(classes = ResourceServerApplication.class) 13 | @WebAppConfiguration 14 | public class ResourceServerApplicationTests { 15 | 16 | @Test 17 | public void contextLoads() { 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/service-registry-1/src/main/java/com/baeldung/ServiceRegistryApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaServer 9 | public class ServiceRegistryApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ServiceRegistryApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/service-registry-1/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: service-registry-1 4 | 5 | server: 6 | port: 8761 7 | 8 | eureka: 9 | instance: 10 | hostname: localhost 11 | port: ${server.port} 12 | client: 13 | registerWithEureka: false 14 | fetchRegistry: false 15 | serviceUrl: 16 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 17 | server: 18 | waitTimeInMsWhenSyncEmpty: 0 19 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/1x/service-registry-1/src/test/java/com/baeldung/ServiceDiscoveryApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 7 | 8 | import com.baeldung.ServiceRegistryApplication; 9 | 10 | @RunWith(SpringJUnit4ClassRunner.class) 11 | @SpringBootTest(classes = ServiceRegistryApplication.class) 12 | public class ServiceDiscoveryApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/api-cloud-gateway-2/src/main/java/com/baeldung/gateway/ApiGatewayApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.gateway.route.RouteLocator; 6 | import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; 7 | import org.springframework.context.annotation.Bean; 8 | 9 | @SpringBootApplication 10 | public class ApiGatewayApplication { 11 | 12 | @Bean 13 | public RouteLocator routeLocator(RouteLocatorBuilder builder) {// @formatter:off 14 | return builder.routes() 15 | .route(r -> 16 | r.path("/foos/**") 17 | // .filters(f -> f.stripPrefix(1)) 18 | .uri("http://localhost:8082/resource-server-mvc-2/foos") 19 | ).build(); 20 | }// @formatter:on 21 | 22 | public static void main(String[] args) { 23 | SpringApplication.run(ApiGatewayApplication.class, args); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/api-cloud-gateway-2/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | gateway: 4 | routes: 5 | - id: foos 6 | uri: http://example.org 7 | predicates: 8 | - After=2017-01-20T17:42:47.789-07:00[America/Denver] -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/api-cloud-gateway-2/src/test/java/com/baeldung/demo/ApiGatewayApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.demo; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ApiGatewayApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/api-gateway-zuul-2/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | aop: 3 | proxy-target-class: true 4 | application: 5 | name: api-gateway-zuul-2 6 | 7 | server: 8 | port: 8765 9 | 10 | eureka: 11 | instance: 12 | hostname: localhost 13 | non-secure-port: 8761 14 | client: 15 | serviceUrl: 16 | defaultZone: http://${eureka.instance.hostname}:${eureka.instance.non-secure-port}/eureka/ 17 | 18 | zuul: 19 | routes: 20 | uaa-service: 21 | sensitiveHeaders: 22 | path: /uaa/** 23 | stripPrefix: false 24 | add-proxy-headers: true 25 | 26 | security: 27 | oauth2: 28 | sso: 29 | loginPath: /login 30 | client: 31 | accessTokenUri: http://uaa-service/uaa/oauth/token 32 | userAuthorizationUri: /uaa/oauth/authorize 33 | clientId: acme 34 | clientSecret: acmesecret 35 | resource: 36 | jwt: 37 | keyValue: "abc" 38 | id: openid 39 | serviceId: ${PREFIX:}resource 40 | 41 | logging: 42 | level.org.springframework.security: DEBUG 43 | 44 | # http://localhost:8080/login -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/authorization-server-2/src/main/java/com/baeldung/AuthorizationServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | 7 | @SpringBootApplication 8 | public class AuthorizationServerApplication extends SpringBootServletInitializer { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(AuthorizationServerApplication.class, args); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/authorization-server-2/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: authorization-server-2 4 | 5 | server: 6 | port: 8769 7 | servlet: 8 | context-path: /uaa 9 | use-forward-headers: false 10 | 11 | eureka: 12 | instance: 13 | hostname: localhost 14 | port: 8761 15 | client: 16 | serviceUrl: 17 | defaultZone: http://${eureka.instance.hostname}:${eureka.instance.port}/eureka/ 18 | 19 | logging: 20 | level.org.springframework.security: DEBUG 21 | 22 | # http://localhost:8081/authorization-server-2/login 23 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/authorization-server-2/src/main/resources/templates/login.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 | 16 | 17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/authorization-server-2/src/test/java/com/baeldung/test/AuthServerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.baeldung.AuthorizationServerApplication; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest(classes = AuthorizationServerApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 13 | public class AuthServerIntegrationTest { 14 | 15 | @Test 16 | public void whenLoadApplication_thenSuccess() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-mvc-2/src/main/java/com/baeldung/ResourceServerApplication1.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 7 | 8 | @SpringBootApplication 9 | @EnableResourceServer 10 | public class ResourceServerApplication1 extends SpringBootServletInitializer { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(ResourceServerApplication1.class, args); 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-mvc-2/src/main/java/com/baeldung/config/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 7 | 8 | @EnableWebSecurity 9 | @Configuration 10 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 11 | 12 | @Override 13 | protected void configure(HttpSecurity http) throws Exception { 14 | http.httpBasic().disable(); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-mvc-2/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: resource-server-mvc-1 4 | 5 | server: 6 | port: 8870 7 | 8 | eureka: 9 | instance: 10 | hostname: localhost 11 | port: 8761 12 | client: 13 | serviceUrl: 14 | defaultZone: http://${eureka.instance.hostname}:${eureka.instance.port}/eureka/ 15 | 16 | security: 17 | oauth2: 18 | resource: 19 | jwt: 20 | keyValue: "abc" 21 | id: fooScope 22 | serviceId: ${PREFIX:}resource 23 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-mvc-2/src/test/java/com/baeldung/test/ResourceServer1IntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.baeldung.ResourceServerApplication1; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest(classes = ResourceServerApplication1.class, webEnvironment = WebEnvironment.RANDOM_PORT) 13 | public class ResourceServer1IntegrationTest { 14 | 15 | @Test 16 | public void whenLoadApplication_thenSuccess() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/java/com/baeldung/ResourceServerApplication2.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | 7 | @SpringBootApplication 8 | public class ResourceServerApplication2 extends SpringBootServletInitializer { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(ResourceServerApplication2.class, args); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/java/com/baeldung/config/MethodSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; 5 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 6 | import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; 7 | import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler; 8 | 9 | @Configuration 10 | @EnableGlobalMethodSecurity(prePostEnabled = true) 11 | public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { 12 | 13 | @Override 14 | protected MethodSecurityExpressionHandler createExpressionHandler() { 15 | return new OAuth2MethodSecurityExpressionHandler(); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/java/com/baeldung/config/ResourceServerWebConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.ComponentScan; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | @Configuration 8 | // @EnableWebMvc 9 | @ComponentScan({ "com.baeldung.web.controller" }) 10 | public class ResourceServerWebConfig implements WebMvcConfigurer { 11 | // 12 | } 13 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/java/com/baeldung/service/ThirdService.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.service; 2 | 3 | import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; 4 | import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; 5 | 6 | import org.springframework.security.access.prepost.PreAuthorize; 7 | import org.springframework.stereotype.Service; 8 | 9 | import com.baeldung.web.dto.Third; 10 | 11 | @Service 12 | public class ThirdService { 13 | 14 | @PreAuthorize("hasRole('ROLE_ADMIN')") 15 | public Third findById(long id) { 16 | return new Third(Long.parseLong(randomNumeric(2)), randomAlphabetic(4)); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/java/com/baeldung/web/controller/ThirdController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.PathVariable; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | import org.springframework.web.bind.annotation.ResponseBody; 8 | 9 | import com.baeldung.service.ThirdService; 10 | import com.baeldung.web.dto.Third; 11 | 12 | @Controller 13 | public class ThirdController { 14 | 15 | private ThirdService thirdService; 16 | 17 | public ThirdController(ThirdService thirdService) { 18 | this.thirdService = thirdService; 19 | } 20 | 21 | // API 22 | 23 | @RequestMapping(method = RequestMethod.GET, value = "/third/{id}") 24 | @ResponseBody 25 | public Third findById(@PathVariable final long id) { 26 | return thirdService.findById(id); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/java/com/baeldung/web/dto/Bar.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class Bar { 11 | 12 | private long id; 13 | private String name; 14 | 15 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/java/com/baeldung/web/dto/Foo.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class Foo { 11 | 12 | private long id; 13 | private String name; 14 | 15 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/java/com/baeldung/web/dto/Third.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class Third { 11 | 12 | private long id; 13 | private String name; 14 | 15 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.servlet.contextPath=/resource-server-rest-2 2 | server.port=8083 3 | logging.level.org=INFO 4 | #endpoints.cors.allowed-origins=* 5 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/resource-server-rest-2/src/test/java/com/baeldung/test/ResourceServer2IntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.baeldung.ResourceServerApplication2; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest(classes = ResourceServerApplication2.class, webEnvironment = WebEnvironment.RANDOM_PORT) 13 | public class ResourceServer2IntegrationTest { 14 | 15 | @Test 16 | public void whenLoadApplication_thenSuccess() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/service-registry-2/src/main/java/com/baeldung/ServiceRegistryApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaServer 9 | public class ServiceRegistryApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ServiceRegistryApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/2x/service-registry-2/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: service-registry-2 4 | 5 | server: 6 | port: 8761 7 | 8 | eureka: 9 | instance: 10 | hostname: localhost 11 | port: ${server.port} 12 | client: 13 | registerWithEureka: false 14 | fetchRegistry: false 15 | serviceUrl: 16 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 17 | server: 18 | waitTimeInMsWhenSyncEmpty: 0 19 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-microservices/README.md: -------------------------------------------------------------------------------- 1 | ### Relevant Articles: 2 | - [OAuth2 – @EnableResourceServer vs @EnableOAuth2Sso](https://www.baeldung.com/spring-security-oauth2-enable-resource-server-vs-enable-oauth2-sso) 3 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/java/com/baeldung/config/CustomAccessTokenConverter.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.security.oauth2.provider.OAuth2Authentication; 6 | import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class CustomAccessTokenConverter extends DefaultAccessTokenConverter { 11 | 12 | @Override 13 | public OAuth2Authentication extractAuthentication(Map claims) { 14 | OAuth2Authentication authentication = super.extractAuthentication(claims); 15 | authentication.setDetails(claims); 16 | return authentication; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/java/com/baeldung/config/MethodSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; 5 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 6 | import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; 7 | import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler; 8 | 9 | @Configuration 10 | @EnableGlobalMethodSecurity(prePostEnabled = true) 11 | public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { 12 | 13 | @Override 14 | protected MethodSecurityExpressionHandler createExpressionHandler() { 15 | return new OAuth2MethodSecurityExpressionHandler(); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/java/com/baeldung/config/ResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | 7 | @SpringBootApplication 8 | public class ResourceServerApplication extends SpringBootServletInitializer { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(ResourceServerApplication.class, args); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/java/com/baeldung/config/ResourceServerWebConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.ComponentScan; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 7 | 8 | @Configuration 9 | @EnableWebMvc 10 | @ComponentScan({ "com.baeldung.web.controller" }) 11 | public class ResourceServerWebConfig implements WebMvcConfigurer { 12 | // 13 | } 14 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/java/com/baeldung/web/dto/Bar.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.dto; 2 | 3 | public class Bar { 4 | private long id; 5 | private String name; 6 | 7 | public Bar() { 8 | super(); 9 | } 10 | 11 | public Bar(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | // 19 | 20 | public long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(final long id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(final String name) { 33 | this.name = name; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/java/com/baeldung/web/dto/Foo.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.dto; 2 | 3 | public class Foo { 4 | private long id; 5 | private String name; 6 | 7 | public Foo() { 8 | super(); 9 | } 10 | 11 | public Foo(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | // 19 | 20 | public long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(final long id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(final String name) { 33 | this.name = name; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.servlet.context-path=/spring-security-oauth-resource 2 | server.port=8082 3 | logging.level.org=INFO 4 | #endpoints.cors.allowed-origins=* -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/resources/persistence.properties: -------------------------------------------------------------------------------- 1 | ################### DataSource Configuration ########################## 2 | 3 | ###################### H2 ##################### 4 | jdbc.driverClassName=org.h2.Driver 5 | jdbc.url=jdbc:h2:~/data/oauth2;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE;IFEXISTS=TRUE 6 | jdbc.user=sa 7 | jdbc.pass= 8 | 9 | 10 | ##################### MySQL ##################### 11 | #jdbc.driverClassName=com.mysql.jdbc.Driver 12 | #jdbc.url=jdbc:mysql://localhost:3306/oauth2?createDatabaseIfNotExist=true 13 | #jdbc.user=tutorialuser 14 | #jdbc.pass=tutorialmy5ql 15 | 16 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/main/resources/public.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp 3 | OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2 4 | /5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3 5 | DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR 6 | xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr 7 | lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK 8 | eQIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-1/src/test/java/com/baeldung/test/ResourceServerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.baeldung.config.ResourceServerApplication; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest(classes = ResourceServerApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 13 | public class ResourceServerIntegrationTest { 14 | 15 | @Test 16 | public void whenLoadApplication_thenSuccess() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/main/java/com/baeldung/config/CustomClaimVerifier.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; 6 | import org.springframework.security.oauth2.provider.token.store.JwtClaimsSetVerifier; 7 | 8 | public class CustomClaimVerifier implements JwtClaimsSetVerifier { 9 | @Override 10 | public void verify(Map claims) throws InvalidTokenException { 11 | final String username = (String) claims.get("user_name"); 12 | if ((username == null) || (username.length() == 0)) { 13 | throw new InvalidTokenException("user_name claim is empty"); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/main/java/com/baeldung/config/MethodSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; 5 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 6 | import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; 7 | import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler; 8 | 9 | @Configuration 10 | @EnableGlobalMethodSecurity(prePostEnabled = true) 11 | public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { 12 | 13 | @Override 14 | protected MethodSecurityExpressionHandler createExpressionHandler() { 15 | return new OAuth2MethodSecurityExpressionHandler(); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/main/java/com/baeldung/config/ResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | 7 | @SpringBootApplication 8 | public class ResourceServerApplication extends SpringBootServletInitializer { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(ResourceServerApplication.class, args); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/main/java/com/baeldung/config/ResourceServerWebConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.context.annotation.ComponentScan; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | @Configuration 8 | // @EnableWebMvc 9 | @ComponentScan({ "com.baeldung.web.controller" }) 10 | public class ResourceServerWebConfig implements WebMvcConfigurer { 11 | // 12 | } 13 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/main/java/com/baeldung/web/dto/Bar.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.dto; 2 | 3 | public class Bar { 4 | private long id; 5 | private String name; 6 | 7 | public Bar() { 8 | super(); 9 | } 10 | 11 | public Bar(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | // 19 | 20 | public long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(final long id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(final String name) { 33 | this.name = name; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/main/java/com/baeldung/web/dto/Foo.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.web.dto; 2 | 3 | public class Foo { 4 | private long id; 5 | private String name; 6 | 7 | public Foo() { 8 | super(); 9 | } 10 | 11 | public Foo(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | // 19 | 20 | public long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(final long id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(final String name) { 33 | this.name = name; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.servlet.context-path=/spring-security-oauth-resource 2 | server.port=8088 3 | logging.level.org=INFO 4 | #endpoints.cors.allowed-origins=* -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/main/resources/public.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp 3 | OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2 4 | /5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3 5 | DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR 6 | xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr 7 | lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK 8 | eQIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /oauth-legacy/oauth-resource-server-legacy-2/src/test/java/com/baeldung/test/ResourceServerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.baeldung.config.ResourceServerApplication; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest(classes = ResourceServerApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 13 | public class ResourceServerIntegrationTest { 14 | 15 | @Test 16 | public void whenLoadApplication_thenSuccess() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/README.md: -------------------------------------------------------------------------------- 1 | ## Spring Security OAuth - Authorization Code 2 | A simple Angular client for Authorization Code Flow 3 | 4 | ## Run the Module 5 | To run the application, first make sure both authorization and resource server are already running 6 | Then, build the app using command line: 7 | ``` 8 | mvn clean install 9 | ``` 10 | 11 | Change directory to src/main/resources: 12 | ``` 13 | cd src/main/resources 14 | ``` 15 | 16 | Finally, run our app on port 8089: 17 | ``` 18 | npm start 19 | ``` 20 | 21 | Hit the app: 22 | http://localhost:8089/ -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 12 | ` 13 | }) 14 | 15 | export class AppComponent {} -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { HttpClientModule } from '@angular/common/http'; 4 | import { RouterModule } from '@angular/router'; 5 | 6 | import { AppComponent } from './app.component'; 7 | import { HomeComponent } from './home.component'; 8 | import { FooComponent } from './foo.component'; 9 | 10 | @NgModule({ 11 | declarations: [ 12 | AppComponent, 13 | HomeComponent, 14 | FooComponent 15 | ], 16 | imports: [ 17 | BrowserModule, 18 | HttpClientModule, 19 | RouterModule.forRoot([ 20 | { path: '', component: HomeComponent, pathMatch: 'full' }], {onSameUrlNavigation: 'reload'}) 21 | ], 22 | providers: [], 23 | bootstrap: [AppComponent] 24 | }) 25 | export class AppModule { } 26 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Authorization Code 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "baseUrl": "", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts", 15 | "polyfills.ts" 16 | ], 17 | "include": [ 18 | "**/*.spec.ts", 19 | "**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-authorization-code-angular-legacy/src/main/resources/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "baseUrl": "src", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2016", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 12 | ` 13 | }) 14 | 15 | export class AppComponent {} -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { HttpModule } from '@angular/http'; 5 | import { HttpClientModule } from '@angular/common/http'; 6 | import { RouterModule } from '@angular/router'; 7 | import { OAuthModule } from 'angular-oauth2-oidc'; 8 | 9 | import { AppComponent } from './app.component'; 10 | import { HomeComponent } from './home.component'; 11 | import { FooComponent } from './foo.component'; 12 | 13 | @NgModule({ 14 | declarations: [ 15 | AppComponent, 16 | HomeComponent, 17 | FooComponent 18 | ], 19 | imports: [ 20 | BrowserModule, 21 | FormsModule, 22 | HttpModule, 23 | HttpClientModule, 24 | OAuthModule.forRoot(), 25 | RouterModule.forRoot([ 26 | { path: '', component: HomeComponent }]) 27 | ], 28 | providers: [], 29 | bootstrap: [AppComponent] 30 | }) 31 | export class AppModule { } 32 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/app/home.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {AppService} from './app.service' 3 | 4 | @Component({ 5 | selector: 'home-header', 6 | providers: [AppService], 7 | template: `
8 | 9 |
10 | Welcome !! 11 | Logout 12 |
13 | 14 |
15 |
` 16 | }) 17 | 18 | export class HomeComponent { 19 | public isLoggedIn = false; 20 | 21 | constructor( 22 | private _service:AppService){} 23 | 24 | ngOnInit(){ 25 | this.isLoggedIn = this._service.isLoggedIn(); 26 | } 27 | 28 | login() { 29 | this._service.obtainAccessToken(); 30 | } 31 | 32 | logout() { 33 | this._service.logout(); 34 | } 35 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OauthImplicit 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "baseUrl": "", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts", 15 | "polyfills.ts" 16 | ], 17 | "include": [ 18 | "**/*.spec.ts", 19 | "**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angular-legacy/src/main/resources/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "baseUrl": "src", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2016", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angularjs-legacy/src/main/java/com/baeldung/config/UiApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | 7 | @SpringBootApplication 8 | public class UiApplication extends SpringBootServletInitializer { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(UiApplication.class, args); 12 | } 13 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angularjs-legacy/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8083 -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angularjs-legacy/src/main/resources/templates/oauthTemp.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | Login 4 | Access denied. Try again. 5 | Logout. 6 | 7 |
-------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-implicit-angularjs-legacy/src/test/java/com/baeldung/test/UiIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.baeldung.config.UiApplication; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest(classes = UiApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 13 | public class UiIntegrationTest { 14 | 15 | @Test 16 | public void whenLoadApplication_thenSuccess() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 12 | ` 13 | }) 14 | 15 | export class AppComponent {} -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { HttpModule } from '@angular/http'; 5 | import { RouterModule } from '@angular/router'; 6 | 7 | import { AppComponent } from './app.component'; 8 | import { LoginComponent } from './login.component'; 9 | import { HomeComponent } from './home.component'; 10 | import { FooComponent } from './foo.component'; 11 | 12 | @NgModule({ 13 | declarations: [ 14 | AppComponent, 15 | HomeComponent, 16 | LoginComponent, 17 | FooComponent 18 | ], 19 | imports: [ 20 | BrowserModule, 21 | FormsModule, 22 | HttpModule, 23 | RouterModule.forRoot([ 24 | { path: '', component: HomeComponent }, 25 | { path: 'login', component: LoginComponent }]) 26 | ], 27 | providers: [], 28 | bootstrap: [AppComponent] 29 | }) 30 | export class AppModule { } 31 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/app/home.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {AppService} from './app.service' 3 | 4 | @Component({ 5 | selector: 'home-header', 6 | providers: [AppService], 7 | template: `
8 |
9 | Welcome !! 10 | Logout 11 |
12 | 13 |
` 14 | }) 15 | 16 | export class HomeComponent { 17 | 18 | constructor( 19 | private _service:AppService){} 20 | 21 | ngOnInit(){ 22 | this._service.checkCredentials(); 23 | } 24 | 25 | logout() { 26 | this._service.logout(); 27 | } 28 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OauthPassword 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "baseUrl": "", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts" 15 | ], 16 | "include": [ 17 | "**/*.spec.ts", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angular-legacy/src/main/resources/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "baseUrl": "src", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2016", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angularjs-legacy/src/main/java/com/baeldung/config/CustomHttpServletRequest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletRequestWrapper; 8 | 9 | public class CustomHttpServletRequest extends HttpServletRequestWrapper { 10 | private final Map additionalParams; 11 | private final HttpServletRequest request; 12 | 13 | public CustomHttpServletRequest(final HttpServletRequest request, final Map additionalParams) { 14 | super(request); 15 | this.request = request; 16 | this.additionalParams = additionalParams; 17 | } 18 | 19 | @Override 20 | public Map getParameterMap() { 21 | final Map map = request.getParameterMap(); 22 | final Map param = new HashMap(); 23 | param.putAll(map); 24 | param.putAll(additionalParams); 25 | return param; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angularjs-legacy/src/main/java/com/baeldung/config/SameSiteConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.apache.tomcat.util.http.Rfc6265CookieProcessor; 4 | import org.apache.tomcat.util.http.SameSiteCookies; 5 | import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | 10 | 11 | @Configuration 12 | public class SameSiteConfig implements WebMvcConfigurer { 13 | @Bean 14 | public TomcatContextCustomizer sameSiteCookiesConfig() { 15 | return context -> { 16 | final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor(); 17 | cookieProcessor.setSameSiteCookies(SameSiteCookies.STRICT.getValue()); 18 | context.setCookieProcessor(cookieProcessor); 19 | }; 20 | } 21 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angularjs-legacy/src/main/java/com/baeldung/config/UiApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 7 | 8 | @EnableZuulProxy 9 | @SpringBootApplication 10 | public class UiApplication extends SpringBootServletInitializer { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(UiApplication.class, args); 14 | } 15 | } -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angularjs-legacy/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8084 3 | zuul: 4 | routes: 5 | oauth: 6 | path: /oauth/** 7 | sensitiveHeaders: 8 | url: http://localhost:8081/spring-security-oauth-server/oauth 9 | Servlet30WrapperFilter: 10 | pre: 11 | disable:true -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angularjs-legacy/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Spring Security OAuth 6 | 7 | 8 | 9 | 10 |
11 | 12 |
13 | 14 |

Login

15 |
16 |
17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 |
25 | 26 |
27 | Login 28 | 29 |
30 | 31 |
32 | 33 |
34 | 35 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-ui-password-angularjs-legacy/src/test/java/com/baeldung/test/UiIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | import com.baeldung.config.UiApplication; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest(classes = UiApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 13 | public class UiIntegrationTest { 14 | 15 | @Test 16 | public void whenLoadApplication_thenSuccess() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-zuul-gateway/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Relevant Articles: 3 | 4 | - [Handle Security in Zuul, with OAuth2 and JWT](https://www.baeldung.com/spring-security-zuul-oauth-jwt) 5 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-zuul-gateway/src/main/java/org/baeldung/GatewayApplication.java: -------------------------------------------------------------------------------- 1 | package org.baeldung; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 7 | 8 | @EnableResourceServer 9 | @EnableZuulProxy 10 | @SpringBootApplication 11 | public class GatewayApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(GatewayApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-zuul-gateway/src/main/java/org/baeldung/config/GatewayConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.baeldung.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 7 | 8 | @Configuration 9 | @EnableResourceServer 10 | public class GatewayConfiguration extends ResourceServerConfigurerAdapter { 11 | @Override 12 | public void configure(final HttpSecurity http) throws Exception { 13 | http.authorizeRequests(). 14 | antMatchers("/oauth/**"). 15 | permitAll(). 16 | antMatchers("/**"). 17 | authenticated(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-zuul-gateway/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | zuul: 4 | sensitiveHeaders: Cookie,Set-Cookie 5 | routes: 6 | spring-security-oauth-resource: 7 | path: /spring-security-oauth-resource/** 8 | url: http://localhost:8082/spring-security-oauth-resource 9 | oauth: 10 | path: /oauth/** 11 | url: http://localhost:8081/spring-security-oauth-server/oauth 12 | 13 | security: 14 | oauth2: 15 | resource: 16 | jwt: 17 | key-value: 123 18 | 19 | -------------------------------------------------------------------------------- /oauth-legacy/oauth-zuul-gateway/src/main/resources/public.txt: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp 3 | OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2 4 | /5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3 5 | DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR 6 | xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr 7 | lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK 8 | eQIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Relevant Articles: 3 | - [Get Keycloak User ID in Spring](https://www.baeldung.com/spring-keycloak-get-user-id) 4 | -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/main/java/com/baeldung/authserver/config/RegularJsonConfigProviderFactory.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.authserver.config; 2 | 3 | import org.keycloak.services.util.JsonConfigProviderFactory; 4 | 5 | public class RegularJsonConfigProviderFactory extends JsonConfigProviderFactory { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/main/resources/META-INF/services/org.keycloak.common.util.ResteasyProvider: -------------------------------------------------------------------------------- 1 | com.baeldung.authserver.config.Resteasy3Provider -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/main/resources/META-INF/services/org.keycloak.config.ConfigProviderFactory: -------------------------------------------------------------------------------- 1 | com.baeldung.authserver.config.RegularJsonConfigProviderFactory -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/main/resources/META-INF/services/org.keycloak.platform.PlatformProvider: -------------------------------------------------------------------------------- 1 | com.baeldung.authserver.config.SimplePlatformProvider -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/main/resources/application-customer.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8083 3 | 4 | spring: 5 | datasource: 6 | username: sa 7 | url: jdbc:h2:mem:testdb 8 | 9 | keycloak: 10 | server: 11 | contextPath: /auth 12 | adminUser: 13 | username: bael-admin 14 | password: pass 15 | realmImportFile: customer-realm.json 16 | 17 | -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/main/resources/application-feign.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8083 3 | 4 | spring: 5 | datasource: 6 | username: sa 7 | url: jdbc:h2:mem:testdb 8 | 9 | keycloak: 10 | server: 11 | contextPath: /auth 12 | adminUser: 13 | username: bael-admin 14 | password: pass 15 | realmImportFile: feign-realm.json 16 | 17 | -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8083 3 | 4 | spring: 5 | datasource: 6 | username: sa 7 | url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE 8 | 9 | keycloak: 10 | server: 11 | contextPath: /auth 12 | adminUser: 13 | username: bael-admin 14 | password: pass 15 | realmImportFile: baeldung-realm.json -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/main/resources/mytest.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baeldung/spring-security-oauth/a0c05211898dd41b53b80883271224d0029b6c6b/oauth-resource-server/authorization-server/src/main/resources/mytest.jks -------------------------------------------------------------------------------- /oauth-resource-server/authorization-server/src/test/java/com/baeldung/jwt/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | import com.baeldung.authserver.AuthorizationServerApp; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = { AuthorizationServerApp.class }) 12 | public class ContextIntegrationTest { 13 | 14 | @Test 15 | public void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /oauth-resource-server/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | JWT with OAuth2 Stack in Spring Security 5 5 | 6 | com.baeldung 7 | oauth-resource-server 8 | 0.1.0-SNAPSHOT 9 | pom 10 | 11 | 12 | authorization-server 13 | resource-server-jwt 14 | resource-server-opaque 15 | 16 | 17 | -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-jwt/src/main/java/com/baeldung/jwt/JWTResourceServerApp.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class JWTResourceServerApp { 8 | 9 | public static void main(String[] args) throws Exception { 10 | SpringApplication.run(JWTResourceServerApp.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-jwt/src/main/java/com/baeldung/jwt/api/PaymentController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.api; 2 | 3 | import com.baeldung.jwt.resource.Payment; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @RestController 11 | public class PaymentController { 12 | 13 | @GetMapping("/payments") 14 | public List getPayments() { 15 | List payments = new ArrayList<>(); 16 | for(int i = 1; i < 6; i++){ 17 | Payment payment = new Payment(); 18 | payment.setId(String.valueOf(i)); 19 | payment.setAmount(2); 20 | payments.add(payment); 21 | } 22 | return payments; 23 | } 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-jwt/src/main/java/com/baeldung/jwt/config/JWTSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.http.HttpMethod; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.web.SecurityFilterChain; 8 | 9 | @Configuration 10 | public class JWTSecurityConfig { 11 | 12 | @Bean 13 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 14 | http.authorizeRequests(authz -> authz.antMatchers(HttpMethod.GET, "/foos/**") 15 | .hasAuthority("SCOPE_read") 16 | .antMatchers(HttpMethod.POST, "/foos") 17 | .hasAuthority("SCOPE_write") 18 | .anyRequest() 19 | .authenticated()) 20 | .oauth2ResourceServer(oauth2 -> oauth2.jwt()); 21 | return http.build(); 22 | } 23 | } -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-jwt/src/main/java/com/baeldung/jwt/resource/Foo.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.resource; 2 | 3 | public class Foo { 4 | private long id; 5 | private String name; 6 | 7 | public Foo() { 8 | super(); 9 | } 10 | 11 | public Foo(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | public long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(final long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(final String name) { 31 | this.name = name; 32 | } 33 | } -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-jwt/src/main/java/com/baeldung/jwt/resource/Payment.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt.resource; 2 | 3 | public class Payment { 4 | 5 | private String id; 6 | private double amount; 7 | 8 | public String getId() { 9 | return id; 10 | } 11 | 12 | public void setId(String id) { 13 | this.id = id; 14 | } 15 | 16 | public double getAmount() { 17 | return amount; 18 | } 19 | 20 | public void setAmount(double amount) { 21 | this.amount = amount; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-jwt/src/main/resources/application-feign.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | servlet: 4 | context-path: /resource-server-jwt 5 | 6 | ####### resource server configuration properties 7 | spring: 8 | security: 9 | oauth2: 10 | resourceserver: 11 | jwt: 12 | issuer-uri: http://localhost:8083/auth/realms/master -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-jwt/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | servlet: 4 | context-path: /resource-server-jwt 5 | 6 | ####### resource server configuration properties 7 | spring: 8 | security: 9 | oauth2: 10 | resourceserver: 11 | jwt: 12 | issuer-uri: http://localhost:8083/auth/realms/baeldung -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-jwt/src/test/java/com/baeldung/jwt/SpringContextLiveTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.jwt; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | @ExtendWith(SpringExtension.class) 9 | @SpringBootTest 10 | /* the configuration requires the AS to be running */ 11 | public class SpringContextLiveTest { 12 | 13 | @Test 14 | public void whenLoadApplication_thenSuccess() { 15 | 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-opaque/src/main/java/com/baeldung/opaque/OpaqueResourceServerApp.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.opaque; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class OpaqueResourceServerApp { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(OpaqueResourceServerApp.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-opaque/src/main/java/com/baeldung/opaque/resource/Bar.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.opaque.resource; 2 | 3 | public class Bar { 4 | private long id; 5 | private String name; 6 | 7 | public Bar() { 8 | super(); 9 | } 10 | 11 | public Bar(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | public long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(final long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(final String name) { 31 | this.name = name; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-opaque/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8082 3 | servlet: 4 | context-path: /resource-server-opaque 5 | 6 | ####### resource server configuration properties 7 | spring: 8 | security: 9 | oauth2: 10 | resourceserver: 11 | opaque: 12 | introspection-uri: http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/token/introspect 13 | introspection-client-id: barClient 14 | introspection-client-secret: barClientSecret 15 | -------------------------------------------------------------------------------- /oauth-resource-server/resource-server-opaque/src/test/java/com/baeldung/opaque/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.opaque; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | import com.baeldung.opaque.OpaqueResourceServerApp; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = { OpaqueResourceServerApp.class }) 12 | public class ContextIntegrationTest { 13 | 14 | @Test 15 | public void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /oauth-rest/keycloak-custom-providers/README.md: -------------------------------------------------------------------------------- 1 | ### Relevant Articles: 2 | 3 | - [Using Custom User Providers with Keycloak](https://www.baeldung.com/java-keycloak-custom-user-providers) 4 | - [Custom Protocol Mapper with Keycloak](https://www.baeldung.com/keycloak-custom-protocol-mapper) 5 | -------------------------------------------------------------------------------- /oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/CustomUserStorageProviderConstants.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.auth.provider.user; 2 | 3 | public final class CustomUserStorageProviderConstants { 4 | public static final String CONFIG_KEY_JDBC_DRIVER = "jdbcDriver"; 5 | public static final String CONFIG_KEY_JDBC_URL = "jdbcUrl"; 6 | public static final String CONFIG_KEY_DB_USERNAME = "username"; 7 | public static final String CONFIG_KEY_DB_PASSWORD = "password"; 8 | public static final String CONFIG_KEY_VALIDATION_QUERY = "validationQuery"; 9 | } 10 | -------------------------------------------------------------------------------- /oauth-rest/keycloak-custom-providers/src/main/java/com/baeldung/auth/provider/user/DbUtil.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.auth.provider.user; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | 7 | import org.keycloak.component.ComponentModel; 8 | import static com.baeldung.auth.provider.user.CustomUserStorageProviderConstants.*; 9 | 10 | public class DbUtil { 11 | 12 | public static Connection getConnection(ComponentModel config) throws SQLException{ 13 | String driverClass = config.get(CONFIG_KEY_JDBC_DRIVER); 14 | try { 15 | Class.forName(driverClass); 16 | } 17 | catch(ClassNotFoundException nfe) { 18 | throw new RuntimeException("Invalid JDBC driver: " + driverClass + ". Please check if your driver if properly installed"); 19 | } 20 | 21 | return DriverManager.getConnection(config.get(CONFIG_KEY_JDBC_URL), 22 | config.get(CONFIG_KEY_DB_USERNAME), 23 | config.get(CONFIG_KEY_DB_PASSWORD)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /oauth-rest/keycloak-custom-providers/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper: -------------------------------------------------------------------------------- 1 | com.baeldung.auth.provider.mapper.CustomProtocolMapper -------------------------------------------------------------------------------- /oauth-rest/keycloak-custom-providers/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory: -------------------------------------------------------------------------------- 1 | com.baeldung.auth.provider.user.CustomUserStorageProviderFactory -------------------------------------------------------------------------------- /oauth-rest/keycloak-custom-providers/src/test/java/com/baeldung/auth/provider/user/TestClientConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.baeldung.auth.provider.user; 5 | 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.client.RestTemplate; 9 | 10 | /** 11 | * @author Philippe 12 | * 13 | */ 14 | @Configuration 15 | public class TestClientConfiguration { 16 | 17 | @Bean 18 | public RestTemplate restTemplate() { 19 | return new RestTemplate(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /oauth-rest/keycloak-custom-providers/src/test/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8083 3 | 4 | spring: 5 | datasource: 6 | username: sa 7 | url: jdbc:h2:mem:testdb 8 | 9 | keycloak: 10 | server: 11 | contextPath: /auth 12 | adminUser: 13 | username: admin 14 | password: admin 15 | realmImportFile: custom-provider-realm.json 16 | -------------------------------------------------------------------------------- /oauth-rest/keycloak-custom-providers/src/test/resources/custom-database-data.sql: -------------------------------------------------------------------------------- 1 | create table if not exists users( 2 | username varchar(64) not null primary key, 3 | password varchar(64) not null, 4 | email varchar(128), 5 | firstName varchar(128) not null, 6 | lastName varchar(128) not null, 7 | birthDate DATE not null ); 8 | 9 | delete from users; 10 | insert into users(username,password,email, firstName, lastName,birthDate) values('user1','changeme','jean.premier@example.com', 'Jean', 'Premier', PARSEDATETIME('1970-01-01','yyyy-MM-dd')); 11 | insert into users(username,password,email, firstName, lastName,birthDate) values('user2','changeme','louis.second@example.com','Louis', 'Second', PARSEDATETIME('1970-01-01','yyyy-MM-dd')); 12 | insert into users(username,password,email, firstName, lastName,birthDate) values('user3','changeme','philippe.troisieme@example.com','Philippe', 'Troisième', PARSEDATETIME('1970-01-01','yyyy-MM-dd')); 13 | 14 | -------------------------------------------------------------------------------- /oauth-rest/oauth-authorization-server/README.md: -------------------------------------------------------------------------------- 1 | ### Relevant Articles: 2 | 3 | - [Keycloak Embedded in a Spring Boot Application](https://www.baeldung.com/keycloak-embedded-in-spring-boot-app) 4 | -------------------------------------------------------------------------------- /oauth-rest/oauth-authorization-server/src/main/java/com/baeldung/auth/config/RegularJsonConfigProviderFactory.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.auth.config; 2 | 3 | import org.keycloak.services.util.JsonConfigProviderFactory; 4 | 5 | public class RegularJsonConfigProviderFactory extends JsonConfigProviderFactory { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /oauth-rest/oauth-authorization-server/src/main/resources/META-INF/services/org.keycloak.common.util.ResteasyProvider: -------------------------------------------------------------------------------- 1 | com.baeldung.auth.config.Resteasy3Provider -------------------------------------------------------------------------------- /oauth-rest/oauth-authorization-server/src/main/resources/META-INF/services/org.keycloak.config.ConfigProviderFactory: -------------------------------------------------------------------------------- 1 | com.baeldung.auth.config.RegularJsonConfigProviderFactory -------------------------------------------------------------------------------- /oauth-rest/oauth-authorization-server/src/main/resources/META-INF/services/org.keycloak.platform.PlatformProvider: -------------------------------------------------------------------------------- 1 | com.baeldung.auth.config.SimplePlatformProvider -------------------------------------------------------------------------------- /oauth-rest/oauth-authorization-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8083 3 | 4 | spring: 5 | jpa: 6 | defer-datasource-initialization: true 7 | datasource: 8 | username: sa 9 | url: jdbc:h2:mem:customdb;DB_CLOSE_ON_EXIT=FALSE 10 | 11 | keycloak: 12 | server: 13 | contextPath: /auth 14 | adminUser: 15 | username: bael-admin 16 | password: pass 17 | realmImportFile: baeldung-realm.json 18 | -------------------------------------------------------------------------------- /oauth-rest/oauth-authorization-server/src/test/java/com/baeldung/auth/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.auth; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | import com.baeldung.auth.AuthorizationServerApp; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = { AuthorizationServerApp.class }) 12 | public class ContextIntegrationTest { 13 | 14 | @Test 15 | public void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /oauth-rest/oauth-client-spring/src/main/java/com/baeldung/client/ClientSpringApp.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.client; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ClientSpringApp { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ClientSpringApp.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /oauth-rest/oauth-client-spring/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | . ____ _ __ _ _ 3 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ 4 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ 5 | \\/ ___)| |_)| | | | | || (_| | ) ) ) ) 6 | ' |____| .__|_| |_|_| |_\__, | / / / / 7 | =========|_|==============|___/=/_/_/_/ 8 | :: Spring Boot :: 9 | -------------------------------------------------------------------------------- /oauth-rest/oauth-client-spring/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Spring OAuth Client Thymeleaf 6 | 7 | 8 | 9 | 12 | 13 |
14 |
Login 15 |
16 | 17 | -------------------------------------------------------------------------------- /oauth-rest/oauth-client-spring/src/test/java/com/baeldung/client/ClientContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.client; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest(classes = { ClientSpringApp.class }) 7 | public class ClientContextIntegrationTest { 8 | 9 | @Test 10 | public void whenLoadApplication_thenSuccess() { 11 | 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/ResourceServerApp.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ResourceServerApp { 8 | 9 | public static void main(String[] args) throws Exception { 10 | SpringApplication.run(ResourceServerApp.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/persistence/repository/IFooRepository.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.persistence.repository; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | 5 | import com.baeldung.resource.persistence.model.Foo; 6 | 7 | public interface IFooRepository extends PagingAndSortingRepository { 8 | } 9 | -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/service/IFooService.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.service; 2 | 3 | import java.util.Optional; 4 | 5 | import com.baeldung.resource.persistence.model.Foo; 6 | 7 | 8 | public interface IFooService { 9 | Optional findById(Long id); 10 | 11 | Foo save(Foo foo); 12 | 13 | Iterable findAll(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/service/impl/FooServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.service.impl; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.stereotype.Service; 6 | 7 | import com.baeldung.resource.persistence.model.Foo; 8 | import com.baeldung.resource.persistence.repository.IFooRepository; 9 | import com.baeldung.resource.service.IFooService; 10 | 11 | @Service 12 | public class FooServiceImpl implements IFooService { 13 | 14 | private IFooRepository fooRepository; 15 | 16 | public FooServiceImpl(IFooRepository fooRepository) { 17 | this.fooRepository = fooRepository; 18 | } 19 | 20 | @Override 21 | public Optional findById(Long id) { 22 | return fooRepository.findById(id); 23 | } 24 | 25 | @Override 26 | public Foo save(Foo foo) { 27 | return fooRepository.save(foo); 28 | } 29 | 30 | @Override 31 | public Iterable findAll() { 32 | return fooRepository.findAll(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/spring/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.spring; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.http.HttpMethod; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.web.SecurityFilterChain; 8 | 9 | @Configuration 10 | public class SecurityConfig { 11 | 12 | @Bean 13 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 14 | http.cors() 15 | .and() 16 | .authorizeRequests() 17 | .antMatchers(HttpMethod.GET, "/user/info", "/api/foos/**") 18 | .hasAuthority("SCOPE_read") 19 | .antMatchers(HttpMethod.POST, "/api/foos") 20 | .hasAuthority("SCOPE_write") 21 | .anyRequest() 22 | .authenticated() 23 | .and() 24 | .oauth2ResourceServer() 25 | .jwt(); 26 | return http.build(); 27 | } 28 | } -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/web/controller/UserInfoController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.web.controller; 2 | 3 | import java.util.Collections; 4 | import java.util.Map; 5 | 6 | import org.springframework.security.core.annotation.AuthenticationPrincipal; 7 | import org.springframework.security.oauth2.jwt.Jwt; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @RestController 12 | public class UserInfoController { 13 | 14 | @GetMapping("/user/info") 15 | public Map getUserInfo(@AuthenticationPrincipal Jwt principal) { 16 | return Collections.singletonMap("user_name", principal.getClaimAsString("preferred_username")); 17 | } 18 | } -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/java/com/baeldung/resource/web/dto/FooDto.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.web.dto; 2 | 3 | public class FooDto { 4 | private long id; 5 | private String name; 6 | 7 | public FooDto() { 8 | super(); 9 | } 10 | 11 | public FooDto(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | // 19 | 20 | public long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(final long id) { 25 | this.id = id; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(final String name) { 33 | this.name = name; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | servlet: 4 | context-path: /resource-server 5 | 6 | ####### resource server configuration properties 7 | spring: 8 | jpa: 9 | defer-datasource-initialization: true 10 | security: 11 | oauth2: 12 | resourceserver: 13 | jwt: 14 | issuer-uri: http://localhost:8083/auth/realms/baeldung 15 | jwk-set-uri: http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/certs -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO Foo(id, name) VALUES (default, 'Foo 1'); 2 | INSERT INTO Foo(id, name) VALUES (default, 'Foo 2'); 3 | INSERT INTO Foo(id, name) VALUES (default, 'Foo 3'); 4 | 5 | -------------------------------------------------------------------------------- /oauth-rest/oauth-resource-server/src/test/java/com/baeldung/resource/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | import com.baeldung.resource.ResourceServerApp; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = { ResourceServerApp.class }) 12 | public class ContextIntegrationTest { 13 | 14 | @Test 15 | public void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/README.md: -------------------------------------------------------------------------------- 1 | ## Spring Security OAuth - Authorization Code Using Zuul 2 | A simple Angular client for Authorization Code Flow Using Zuul 3 | 4 | ## Run the Module 5 | To run the application, first make sure both authorization and resource server are already running 6 | Then, build the app using command line: 7 | ``` 8 | mvn clean install 9 | ``` 10 | 11 | To launch the Angular UI, simply start the UIApplication class and hit the app at: 12 | http://localhost:8089/ -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/java/com/baeldung/config/SameSiteConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.apache.tomcat.util.http.Rfc6265CookieProcessor; 4 | import org.apache.tomcat.util.http.SameSiteCookies; 5 | import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | 10 | @Configuration 11 | public class SameSiteConfig implements WebMvcConfigurer { 12 | @Bean 13 | public TomcatContextCustomizer sameSiteCookiesConfig() { 14 | return context -> { 15 | final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor(); 16 | cookieProcessor.setSameSiteCookies(SameSiteCookies.STRICT.getValue()); 17 | context.setCookieProcessor(cookieProcessor); 18 | }; 19 | } 20 | } -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/java/com/baeldung/config/UiApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 7 | 8 | @EnableZuulProxy 9 | @SpringBootApplication 10 | public class UiApplication extends SpringBootServletInitializer { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(UiApplication.class, args); 14 | } 15 | } -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 12 | ` 13 | }) 14 | 15 | export class AppComponent { } -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { HttpClientModule } from '@angular/common/http'; 4 | import { RouterModule } from '@angular/router'; 5 | 6 | import { AppComponent } from './app.component'; 7 | import { HomeComponent } from './home.component'; 8 | import { FooComponent } from './foo.component'; 9 | 10 | @NgModule({ 11 | declarations: [ 12 | AppComponent, 13 | HomeComponent, 14 | FooComponent 15 | ], 16 | imports: [ 17 | BrowserModule, 18 | HttpClientModule, 19 | RouterModule.forRoot([ 20 | { path: '', component: HomeComponent, pathMatch: 'full' }, 21 | { path: '**', component: HomeComponent }], { onSameUrlNavigation: 'reload' }) 22 | ], 23 | providers: [], 24 | bootstrap: [AppComponent] 25 | }) 26 | export class AppModule { } 27 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Authorization Code with Zuul 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "main.ts", 10 | "polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts", 15 | "polyfills.ts" 16 | ], 17 | "include": [ 18 | "**/*.spec.ts", 19 | "**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/main/resources/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "outDir": "./dist/out-tsc", 6 | "baseUrl": "src", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "moduleResolution": "node", 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "target": "ES2022", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "lib": [ 17 | "es2016", 18 | "dom" 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular-zuul/src/test/java/com/baeldung/test/UiIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.test; 2 | 3 | import com.baeldung.config.UiApplication; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 8 | import org.springframework.test.context.junit.jupiter.SpringExtension; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = UiApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 12 | public class UiIntegrationTest { 13 | 14 | @Test 15 | void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/README.md: -------------------------------------------------------------------------------- 1 | ## Spring Security OAuth - Authorization Code 2 | A simple Angular client for Authorization Code Flow 3 | 4 | ## Run the Module 5 | To run the application, first make sure both authorization and resource server are already running 6 | Then, build the app using command line: 7 | ``` 8 | mvn clean install 9 | ``` 10 | 11 | Change directory to src/main/resources: 12 | ``` 13 | cd src/main/resources 14 | ``` 15 | 16 | Finally, run our app on port 8089: 17 | ``` 18 | npm start 19 | ``` 20 | 21 | Hit the app: 22 | http://localhost:8089/ -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | Chrome >=99 9 | Firefox >=99 10 | Edge >=79 11 | Safari >=13 12 | iOS >=13 -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 12 | ` 13 | }) 14 | 15 | export class AppComponent {} -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { HttpClientModule } from '@angular/common/http'; 4 | import { RouterModule } from '@angular/router'; 5 | 6 | import { AppComponent } from './app.component'; 7 | import { HomeComponent } from './home.component'; 8 | import { FooComponent } from './foo.component'; 9 | 10 | @NgModule({ 11 | declarations: [ 12 | AppComponent, 13 | HomeComponent, 14 | FooComponent 15 | ], 16 | imports: [ 17 | BrowserModule, 18 | HttpClientModule, 19 | RouterModule.forRoot([ 20 | { path: '', component: HomeComponent, pathMatch: 'full' }], {onSameUrlNavigation: 'reload'}) 21 | ], 22 | providers: [], 23 | bootstrap: [AppComponent] 24 | }) 25 | export class AppModule { } 26 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Authorization Code 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "main.ts", 10 | "polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts", 15 | "polyfills.ts" 16 | ], 17 | "include": [ 18 | "**/*.spec.ts", 19 | "**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /oauth-rest/oauth-ui-authorization-code-angular/src/main/resources/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "downlevelIteration": true, 5 | "module": "esnext", 6 | "outDir": "./dist/out-tsc", 7 | "baseUrl": "src", 8 | "sourceMap": true, 9 | "declaration": false, 10 | "moduleResolution": "node", 11 | "emitDecoratorMetadata": true, 12 | "experimentalDecorators": true, 13 | "target": "ES2022", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2016", 19 | "dom" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /oauth-rest/oauth2-social-login/README.md: -------------------------------------------------------------------------------- 1 | ## Relevant articles: 2 | 3 | - [Authenticate Using Social Login in Spring Authorization Server](https://www.baeldung.com/spring-authorization-server-social-login-authentication) 4 | -------------------------------------------------------------------------------- /oauth-rest/oauth2-social-login/src/main/java/com/baeldung/springsociallogin/SpringSocialLoginApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.springsociallogin; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringSocialLoginApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringSocialLoginApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /oauth-rest/oauth2-social-login/src/main/java/com/baeldung/springsociallogin/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.springsociallogin.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.Customizer; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 8 | import org.springframework.security.web.SecurityFilterChain; 9 | 10 | @Configuration 11 | @EnableWebSecurity 12 | public class SecurityConfig { 13 | 14 | @Bean 15 | SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 16 | return http 17 | .authorizeHttpRequests(auth -> { 18 | auth.requestMatchers("/").permitAll(); 19 | auth.anyRequest().authenticated(); 20 | }) 21 | .oauth2Login(Customizer.withDefaults()) 22 | .formLogin(Customizer.withDefaults()) 23 | .build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /oauth-rest/oauth2-social-login/src/main/java/com/baeldung/springsociallogin/controller/HomeController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.springsociallogin.controller; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class HomeController { 8 | 9 | @GetMapping("/") 10 | public String home() { 11 | return "Hello, public user!"; 12 | } 13 | 14 | @GetMapping("/secure") 15 | public String secured() { 16 | return "Hello, logged in user!"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /oauth-rest/oauth2-social-login/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=spring-social-login 2 | 3 | logging.level.org.springframework.security = TRACE 4 | 5 | spring.security.oauth2.client.registration.google.client-id = REPLACE_ME 6 | spring.security.oauth2.client.registration.google.client-secret = REPLACE_ME -------------------------------------------------------------------------------- /oauth-rest/oauth2-social-login/src/test/java/com/baeldung/springsociallogin/SpringSocialLoginApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.springsociallogin; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringSocialLoginApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /oauth-sso/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | New OAuth2 Stack in Spring Security 5 6 | 7 | com.baeldung 8 | oauth-sso 9 | 0.1.0-SNAPSHOT 10 | pom 11 | 12 | 13 | sso-authorization-server 14 | sso-resource-server 15 | sso-client-app-1 16 | sso-client-app-2 17 | 18 | 19 | -------------------------------------------------------------------------------- /oauth-sso/sso-authorization-server/src/main/java/com/baeldung/auth/config/RegularJsonConfigProviderFactory.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.auth.config; 2 | 3 | import org.keycloak.services.util.JsonConfigProviderFactory; 4 | 5 | public class RegularJsonConfigProviderFactory extends JsonConfigProviderFactory { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /oauth-sso/sso-authorization-server/src/main/resources/META-INF/services/org.keycloak.common.util.ResteasyProvider: -------------------------------------------------------------------------------- 1 | com.baeldung.auth.config.Resteasy3Provider -------------------------------------------------------------------------------- /oauth-sso/sso-authorization-server/src/main/resources/META-INF/services/org.keycloak.config.ConfigProviderFactory: -------------------------------------------------------------------------------- 1 | com.baeldung.auth.config.RegularJsonConfigProviderFactory -------------------------------------------------------------------------------- /oauth-sso/sso-authorization-server/src/main/resources/META-INF/services/org.keycloak.platform.PlatformProvider: -------------------------------------------------------------------------------- 1 | com.baeldung.auth.config.SimplePlatformProvider -------------------------------------------------------------------------------- /oauth-sso/sso-authorization-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8083 3 | 4 | spring: 5 | datasource: 6 | username: sa 7 | url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE 8 | 9 | keycloak: 10 | server: 11 | contextPath: /auth 12 | adminUser: 13 | username: bael-admin 14 | password: pass 15 | realmImportFile: baeldung-realm.json 16 | -------------------------------------------------------------------------------- /oauth-sso/sso-authorization-server/src/test/java/com/baeldung/auth/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.auth; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | import com.baeldung.auth.AuthorizationServerApp; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = { AuthorizationServerApp.class }) 12 | public class ContextIntegrationTest { 13 | 14 | @Test 15 | public void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /oauth-sso/sso-client-app-1/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | .mvn 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /oauth-sso/sso-client-app-1/src/main/java/com/baeldung/client/SSOClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.client; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SSOClientApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SSOClientApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /oauth-sso/sso-client-app-1/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Spring OAuth Client Thymeleaf - 1 6 | 8 | 9 | 10 | 15 | 16 |
17 |
Login 19 |
20 | 21 | -------------------------------------------------------------------------------- /oauth-sso/sso-client-app-1/src/test/java/com/baeldung/client/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.client; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | @ExtendWith(SpringExtension.class) 9 | @SpringBootTest(classes = { SSOClientApplication.class }) 10 | public class ContextIntegrationTest { 11 | 12 | @Test 13 | public void whenLoadApplication_thenSuccess() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /oauth-sso/sso-client-app-2/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | .mvn 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /oauth-sso/sso-client-app-2/src/main/java/com/baeldung/client/SSOClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.client; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SSOClientApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SSOClientApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /oauth-sso/sso-client-app-2/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Spring OAuth Client Thymeleaf - 2 6 | 8 | 9 | 10 | 15 | 16 |
17 |
Login 19 |
20 | 21 | -------------------------------------------------------------------------------- /oauth-sso/sso-client-app-2/src/test/java/com/baeldung/client/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.client; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | @ExtendWith(SpringExtension.class) 9 | @SpringBootTest(classes = { SSOClientApplication.class }) 10 | public class ContextIntegrationTest { 11 | 12 | @Test 13 | public void whenLoadApplication_thenSuccess() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/java/com/baeldung/resource/ResourceServerApp.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ResourceServerApp { 8 | 9 | public static void main(String[] args) throws Exception { 10 | SpringApplication.run(ResourceServerApp.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/java/com/baeldung/resource/persistence/repository/IFooRepository.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.persistence.repository; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | 5 | import com.baeldung.resource.persistence.model.Foo; 6 | 7 | public interface IFooRepository extends PagingAndSortingRepository { 8 | } 9 | -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/java/com/baeldung/resource/service/IFooService.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.service; 2 | 3 | import java.util.Optional; 4 | 5 | import com.baeldung.resource.persistence.model.Foo; 6 | 7 | public interface IFooService { 8 | Optional findById(Long id); 9 | 10 | Foo save(Foo foo); 11 | 12 | Iterable findAll(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/java/com/baeldung/resource/service/impl/FooServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.service.impl; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.stereotype.Service; 6 | 7 | import com.baeldung.resource.persistence.model.Foo; 8 | import com.baeldung.resource.persistence.repository.IFooRepository; 9 | import com.baeldung.resource.service.IFooService; 10 | 11 | @Service 12 | public class FooServiceImpl implements IFooService { 13 | 14 | private IFooRepository fooRepository; 15 | 16 | public FooServiceImpl(IFooRepository fooRepository) { 17 | this.fooRepository = fooRepository; 18 | } 19 | 20 | @Override 21 | public Optional findById(Long id) { 22 | return fooRepository.findById(id); 23 | } 24 | 25 | @Override 26 | public Foo save(Foo foo) { 27 | return fooRepository.save(foo); 28 | } 29 | 30 | @Override 31 | public Iterable findAll() { 32 | return fooRepository.findAll(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/java/com/baeldung/resource/spring/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.spring; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.http.HttpMethod; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.web.SecurityFilterChain; 8 | 9 | @Configuration 10 | public class SecurityConfig { 11 | 12 | @Bean 13 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 14 | http.cors() 15 | .and() 16 | .authorizeRequests() 17 | .antMatchers(HttpMethod.GET, "/user/info", "/api/foos/**") 18 | .hasAuthority("SCOPE_read") 19 | .antMatchers(HttpMethod.POST, "/api/foos") 20 | .hasAuthority("SCOPE_write") 21 | .anyRequest() 22 | .authenticated() 23 | .and() 24 | .oauth2ResourceServer() 25 | .jwt(); 26 | return http.build(); 27 | } 28 | } -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/java/com/baeldung/resource/web/controller/UserInfoController.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.web.controller; 2 | 3 | import java.util.Collections; 4 | import java.util.Map; 5 | 6 | import org.springframework.security.core.annotation.AuthenticationPrincipal; 7 | import org.springframework.security.oauth2.jwt.Jwt; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @RestController 12 | public class UserInfoController { 13 | 14 | @GetMapping("/user/info") 15 | public Map getUserInfo(@AuthenticationPrincipal Jwt principal) { 16 | return Collections.singletonMap("user_name", principal.getClaimAsString("preferred_username")); 17 | } 18 | } -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/java/com/baeldung/resource/web/dto/FooDto.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource.web.dto; 2 | 3 | public class FooDto { 4 | private long id; 5 | private String name; 6 | 7 | public FooDto() { 8 | super(); 9 | } 10 | 11 | public FooDto(final long id, final String name) { 12 | super(); 13 | 14 | this.id = id; 15 | this.name = name; 16 | } 17 | 18 | public long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(final long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(final String name) { 31 | this.name = name; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | servlet: 4 | context-path: /sso-resource-server 5 | 6 | ####### resource server configuration properties 7 | spring: 8 | security: 9 | oauth2: 10 | resourceserver: 11 | jwt: 12 | issuer-uri: http://localhost:8083/auth/realms/baeldung 13 | jwk-set-uri: http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/certs 14 | jpa: 15 | defer-datasource-initialization: true -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO Foo(id, name) VALUES (1, 'Foo 1'); 2 | INSERT INTO Foo(id, name) VALUES (2, 'Foo 2'); 3 | INSERT INTO Foo(id, name) VALUES (3, 'Foo 3'); 4 | 5 | -------------------------------------------------------------------------------- /oauth-sso/sso-resource-server/src/test/java/com/baeldung/resource/ContextIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.baeldung.resource; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit.jupiter.SpringExtension; 7 | 8 | import com.baeldung.resource.ResourceServerApp; 9 | 10 | @ExtendWith(SpringExtension.class) 11 | @SpringBootTest(classes = { ResourceServerApp.class }) 12 | public class ContextIntegrationTest { 13 | 14 | @Test 15 | public void whenLoadApplication_thenSuccess() { 16 | 17 | } 18 | 19 | } --------------------------------------------------------------------------------