├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md └── workflows │ └── ci.yml ├── .gitignore ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── .readme_resources ├── auth0-application-details.png ├── auth0-role-creation.png ├── authorization-code_flow.png ├── aws-console.png ├── create-user-pool-1.png ├── create-user-pool-2.png ├── create-user-pool-4.png └── keycloak-confidential.png ├── 7.0.0-migration-guide.md ├── CONTRIBUTING.md ├── README.MD ├── infra ├── .env ├── .gitignore ├── compose.yml └── import │ └── spring-addons-realm.json ├── license.txt ├── lombok.config ├── maven-central.md ├── migrate-to-8.0.0.md ├── mvnw ├── mvnw.cmd ├── pom.xml ├── release-notes.md ├── samples ├── README.md ├── oauth2-bff-reactive │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── c4soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ ├── BffApplication.java │ │ │ ├── BffController.java │ │ │ └── UiController.java │ │ └── resources │ │ ├── application.yml │ │ ├── static │ │ └── favicon.ico │ │ └── templates │ │ └── index.html ├── oauth2-bff-servlet │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── c4soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ ├── BffApplication.java │ │ │ ├── BffController.java │ │ │ └── UiController.java │ │ └── resources │ │ ├── application.yml │ │ ├── static │ │ └── favicon.ico │ │ └── templates │ │ └── index.html ├── pom.xml ├── springdoc-openapi-2494-reactive │ ├── README.md │ ├── openapi.json │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ ├── DemoController.java │ │ │ │ └── EnumBugReproducerApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── c4soft │ │ ├── DemoControllerTest.java │ │ └── EnumBugReproducerApplicationTests.java ├── springdoc-openapi-2494-servlet │ ├── README.md │ ├── openapi.json │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ ├── DemoController.java │ │ │ │ └── EnumBugReproducerApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── c4soft │ │ ├── DemoControllerTest.java │ │ └── EnumBugReproducerApplicationTests.java ├── tutorials │ ├── README.md │ ├── auth0.md │ ├── bff │ │ └── README.md │ ├── cognito.md │ ├── keycloak.md │ ├── pom.xml │ ├── reactive-client │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── IndexController.java │ │ │ │ │ ├── ReactiveClientApplication.java │ │ │ │ │ └── WebSecurityConfig.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ ├── banner.txt │ │ │ │ ├── static │ │ │ │ ├── index.html │ │ │ │ └── nice.html │ │ │ │ └── templates │ │ │ │ └── index.html │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── ReactiveClientApplicationTest.java │ │ │ │ └── TestSecurityConf.java │ │ │ └── resources │ │ │ └── mockito-extensions │ │ │ └── org.mockito.plugins.MockMaker │ ├── reactive-resource-server │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── GreetingController.java │ │ │ │ │ ├── ReactiveResourceServerApplication.java │ │ │ │ │ └── WebSecurityConfig.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── banner.txt │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── GreetingControllerTest.java │ │ │ │ └── ReactiveResourceServerApplicationTests.java │ │ │ └── resources │ │ │ ├── auth0_badboy.json │ │ │ └── auth0_nice.json │ ├── resource-server_multitenant_dynamic │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── GreetingController.java │ │ │ │ │ ├── ResourceServerMultitenantDynamicApplication.java │ │ │ │ │ └── WebSecurityConfig.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── banner.txt │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── GreetingControllerTest.java │ │ │ │ └── ResourceServerMultitenantDynamicApplicationTests.java │ │ │ └── resources │ │ │ ├── keycloak_badboy.json │ │ │ └── keycloak_nice.json │ ├── resource-server_with_additional-header │ │ ├── .gitignore │ │ ├── .mvn │ │ │ └── wrapper │ │ │ │ ├── maven-wrapper.jar │ │ │ │ └── maven-wrapper.properties │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── GreetingController.java │ │ │ │ │ ├── SecurityConfig.java │ │ │ │ │ └── ServletResourceServerWithAdditionalHeader.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── banner.txt │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── c4soft │ │ │ └── springaddons │ │ │ └── tutorials │ │ │ ├── GreetingControllerTest.java │ │ │ ├── ServletResourceServerWithAdditionalHeaderTests.java │ │ │ └── WithMyAuth.java │ ├── resource-server_with_introspection │ │ ├── .gitignore │ │ ├── .mvn │ │ │ └── wrapper │ │ │ │ ├── maven-wrapper.jar │ │ │ │ └── maven-wrapper.properties │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── GreetingController.java │ │ │ │ │ ├── ResourceServerWithOAuthenticationApplication.java │ │ │ │ │ └── WebSecurityConfig.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── banner.txt │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── GreetingControllerTest.java │ │ │ │ └── ResourceServerWithOAuthenticationApplicationTests.java │ │ │ └── resources │ │ │ ├── ch4mp.json │ │ │ └── tonton-pirate.json │ ├── resource-server_with_oauthentication │ │ ├── .gitignore │ │ ├── .mvn │ │ │ └── wrapper │ │ │ │ ├── maven-wrapper.jar │ │ │ │ └── maven-wrapper.properties │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── GreetingController.java │ │ │ │ │ └── ResourceServerWithOAuthenticationApplication.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── banner.txt │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── GreetingControllerTest.java │ │ │ │ └── ResourceServerWithOAuthenticationApplicationTests.java │ │ │ └── resources │ │ │ ├── auth0_badboy.json │ │ │ └── auth0_nice.json │ ├── resource-server_with_specialized_oauthentication │ │ ├── .gitignore │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── GreetingController.java │ │ │ │ │ ├── ProxiesAuthentication.java │ │ │ │ │ ├── ProxiesToken.java │ │ │ │ │ ├── Proxy.java │ │ │ │ │ ├── ResourceServerWithOAuthenticationApplication.java │ │ │ │ │ └── SecurityConfig.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── banner.txt │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── GreetingControllerTest.java │ │ │ │ └── ResourceServerWithOidcAuthenticationApplicationTests.java │ │ │ └── resources │ │ │ ├── ch4mp.json │ │ │ └── tonton_proxy_ch4mp.json │ ├── resource-server_with_ui │ │ ├── README.md │ │ ├── pom.xml │ │ ├── readme-resources │ │ │ └── greet.png │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── ResourceServerWithUiApplication.java │ │ │ │ │ ├── WebSecurityConfig.java │ │ │ │ │ ├── api │ │ │ │ │ └── ApiController.java │ │ │ │ │ └── ui │ │ │ │ │ ├── GreetApi.java │ │ │ │ │ ├── LoginController.java │ │ │ │ │ ├── RestClientsConfig.java │ │ │ │ │ └── UiController.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ ├── banner.txt │ │ │ │ ├── static │ │ │ │ └── favicon.ico │ │ │ │ └── templates │ │ │ │ ├── greet-js.html │ │ │ │ ├── greet.html │ │ │ │ ├── index.html │ │ │ │ └── login.html │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── ResourceServerWithUiApplicationTests.java │ │ │ │ └── api │ │ │ │ └── ApiControllerTest.java │ │ │ └── resources │ │ │ └── ch4mp_keycloak.json │ ├── servlet-client │ │ ├── .gitignore │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── c4soft │ │ │ │ │ └── springaddons │ │ │ │ │ └── tutorials │ │ │ │ │ ├── AuthoritiesMappingProperties.java │ │ │ │ │ ├── IndexController.java │ │ │ │ │ ├── LogoutProperties.java │ │ │ │ │ ├── ServletClientApplication.java │ │ │ │ │ └── WebSecurityConfig.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ ├── banner.txt │ │ │ │ ├── static │ │ │ │ ├── index.html │ │ │ │ └── nice.html │ │ │ │ └── templates │ │ │ │ └── index.html │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── ServletClientApplicationTests.java │ │ │ │ └── TestSecurityConf.java │ │ │ └── resources │ │ │ └── mockito-extensions │ │ │ └── org.mockito.plugins.MockMaker │ └── servlet-resource-server │ │ ├── README.md │ │ ├── pom.xml │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4soft │ │ │ │ └── springaddons │ │ │ │ └── tutorials │ │ │ │ ├── GreetingController.java │ │ │ │ ├── ServletResourceServerApplication.java │ │ │ │ └── WebSecurityConfig.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4soft │ │ │ └── springaddons │ │ │ └── tutorials │ │ │ ├── GivenUserIsCh4mp.java │ │ │ ├── GivenUserIsCh4mpDeprecated.java │ │ │ ├── GreetingControllerTest.java │ │ │ └── ServletResourceServerApplicationTests.java │ │ └── resources │ │ └── ch4mp_auth0.json ├── webflux-introspecting-default │ ├── LICENSE │ ├── bindings │ │ └── ca-certificates │ │ │ └── type │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4_soft │ │ │ │ └── springaddons │ │ │ │ └── samples │ │ │ │ └── webflux_jwtauthenticationtoken │ │ │ │ ├── GreetingController.java │ │ │ │ ├── MessageService.java │ │ │ │ ├── SecretRepo.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ └── WebfluxIntrospectingDefault.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webflux_jwtauthenticationtoken │ │ │ ├── GreetingControllerAnnotatedTest.java │ │ │ ├── GreetingControllerFluentApiTest.java │ │ │ ├── MessageServiceTests.java │ │ │ ├── SecretRepoTest.java │ │ │ └── WebfluxIntrospectingDefaultTest.java │ │ └── resources │ │ ├── ch4mp.json │ │ ├── mockito-extensions │ │ └── org.mockito.plugins.MockMaker │ │ └── tonton-pirate.json ├── webflux-introspecting-oauthentication │ ├── bindings │ │ └── ca-certificates │ │ │ └── type │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4_soft │ │ │ │ └── springaddons │ │ │ │ └── samples │ │ │ │ └── webflux_jwtauthenticationtoken │ │ │ │ ├── GreetingController.java │ │ │ │ ├── MessageService.java │ │ │ │ ├── SecretRepo.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ └── WebfluxIntrospectingOAthentication.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webflux_jwtauthenticationtoken │ │ │ ├── GreetingControllerAnnotatedTest.java │ │ │ ├── GreetingControllerFluentApiTest.java │ │ │ ├── MessageServiceTests.java │ │ │ ├── SampleApiIntegrationTests.java │ │ │ └── SecretRepoTest.java │ │ └── resources │ │ ├── ch4mp.json │ │ ├── mockito-extensions │ │ └── org.mockito.plugins.MockMaker │ │ └── tonton-pirate.json ├── webflux-jwt-default │ ├── LICENSE │ ├── README.md │ ├── bindings │ │ └── ca-certificates │ │ │ └── type │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4_soft │ │ │ │ └── springaddons │ │ │ │ └── samples │ │ │ │ └── webflux_jwtauthenticationtoken │ │ │ │ ├── GreetingController.java │ │ │ │ ├── MessageService.java │ │ │ │ ├── SecretRepo.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ └── WebfluxJwtDefault.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webflux_jwtauthenticationtoken │ │ │ ├── GreetingControllerAnnotatedTest.java │ │ │ ├── GreetingControllerFluentApiTest.java │ │ │ ├── MessageServiceTests.java │ │ │ ├── SampleApiIntegrationTests.java │ │ │ └── SecretRepoTest.java │ │ └── resources │ │ ├── ch4mp.json │ │ ├── mockito-extensions │ │ └── org.mockito.plugins.MockMaker │ │ └── tonton-pirate.json ├── webflux-jwt-oauthentication │ ├── LICENSE │ ├── bindings │ │ └── ca-certificates │ │ │ └── type │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4_soft │ │ │ │ └── springaddons │ │ │ │ └── samples │ │ │ │ └── webflux_oidcauthentication │ │ │ │ ├── GreetingController.java │ │ │ │ ├── MessageService.java │ │ │ │ ├── SecretRepo.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ └── WebfluxJwtOauthentication.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webflux_oidcauthentication │ │ │ ├── GreetingControllerAnnotatedTest.java │ │ │ ├── MessageServiceTests.java │ │ │ ├── SampleApiIntegrationTests.java │ │ │ └── SecretRepoTest.java │ │ └── resources │ │ ├── ch4mp.json │ │ ├── mockito-extensions │ │ └── org.mockito.plugins.MockMaker │ │ └── tonton-pirate.json ├── webmvc-introspecting-default │ ├── LICENSE │ ├── bindings │ │ └── ca-certificates │ │ │ └── type │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4_soft │ │ │ │ └── springaddons │ │ │ │ └── samples │ │ │ │ └── webmvc_jwtauthenticationtoken │ │ │ │ ├── GreetingController.java │ │ │ │ ├── MessageService.java │ │ │ │ ├── SecretRepo.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ └── WebmvcIntrospectingDefault.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webmvc_jwtauthenticationtoken │ │ │ ├── GreetingControllerAnnotatedTest.java │ │ │ ├── GreetingControllerFluentApiTest.java │ │ │ ├── MessageServiceTests.java │ │ │ ├── SampleApiIntegrationTest.java │ │ │ └── SecretRepoTest.java │ │ └── resources │ │ ├── ch4mp.json │ │ └── tonton-pirate.json ├── webmvc-introspecting-oauthentication │ ├── LICENSE │ ├── bindings │ │ └── ca-certificates │ │ │ └── type │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4_soft │ │ │ │ └── springaddons │ │ │ │ └── samples │ │ │ │ └── webmvc_oidcauthentication │ │ │ │ ├── GreetingController.java │ │ │ │ ├── MessageService.java │ │ │ │ ├── SecretRepo.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ └── WebmvcIntrospectingOauthentication.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webmvc_oidcauthentication │ │ │ ├── GreetingControllerAnnotatedTest.java │ │ │ ├── MessageServiceTests.java │ │ │ ├── SampleApiIntegrationTest.java │ │ │ └── SecretRepoTest.java │ │ └── resources │ │ ├── ch4mp.json │ │ └── tonton-pirate.json ├── webmvc-jwt-default-jpa-authorities │ ├── LICENSE │ ├── bindings │ │ └── ca-certificates │ │ │ └── type │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4_soft │ │ │ │ └── springaddons │ │ │ │ └── samples │ │ │ │ └── webmvc_jwtauthenticationtoken_jpa_authorities │ │ │ │ ├── GreetingController.java │ │ │ │ ├── MessageService.java │ │ │ │ ├── PersistedGrantedAuthoritiesRetriever.java │ │ │ │ ├── PersistenceConfig.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ ├── UserAuthority.java │ │ │ │ ├── UserAuthorityId.java │ │ │ │ ├── UserAuthorityRepository.java │ │ │ │ └── WebmvcJwtDefaultJpaAuthorities.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webmvc_jwtauthenticationtoken_jpa_authorities │ │ │ ├── GreetingControllerAnnotatedTest.java │ │ │ ├── GreetingControllerFluentApiTest.java │ │ │ ├── MessageServiceTests.java │ │ │ └── TestUserAuthorityRepositoryConf.java │ │ └── resources │ │ ├── application.yml │ │ ├── ch4mp.json │ │ └── tonton-pirate.json ├── webmvc-jwt-default │ ├── LICENSE │ ├── README.md │ ├── bindings │ │ └── ca-certificates │ │ │ └── type │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── c4_soft │ │ │ │ └── springaddons │ │ │ │ └── samples │ │ │ │ └── webmvc_jwtauthenticationtoken │ │ │ │ ├── BasicAuthSecurityConfig.java │ │ │ │ ├── GreetingController.java │ │ │ │ ├── MessageService.java │ │ │ │ ├── OAuth2SecurityConfig.java │ │ │ │ ├── SecretRepo.java │ │ │ │ └── WebmvcJwtDefault.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── banner.txt │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webmvc_jwtauthenticationtoken │ │ │ ├── GreetingControllerAnnotatedTest.java │ │ │ ├── GreetingControllerFluentApiTest.java │ │ │ ├── MessageServiceTests.java │ │ │ ├── SampleApiIntegrationTest.java │ │ │ └── SecretRepoTest.java │ │ └── resources │ │ ├── ch4mp.json │ │ └── tonton-pirate.json └── webmvc-jwt-oauthentication │ ├── LICENSE │ ├── bindings │ └── ca-certificates │ │ └── type │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── samples │ │ │ └── webmvc_oidcauthentication │ │ │ ├── GreetingController.java │ │ │ ├── MessageService.java │ │ │ ├── SecretRepo.java │ │ │ ├── SecurityConfig.java │ │ │ └── WebmvcJwtOauthentication.java │ └── resources │ │ ├── application.yml │ │ └── banner.txt │ └── test │ ├── java │ └── com │ │ └── c4_soft │ │ └── springaddons │ │ └── samples │ │ └── webmvc_oidcauthentication │ │ ├── GreetingControllerAnnotatedTest.java │ │ ├── MessageServiceTests.java │ │ ├── SampleApiIntegrationTest.java │ │ └── SecretRepoTest.java │ └── resources │ ├── ch4mp.json │ └── tonton-pirate.json ├── spring-addons-oauth2-test ├── Cucumber.md ├── README.MD ├── license.txt ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ ├── security │ │ │ └── oauth2 │ │ │ │ └── test │ │ │ │ ├── AuthenticationBuilder.java │ │ │ │ ├── AuthenticationFactoriesTestConf.java │ │ │ │ ├── AuthoritiesConverterNotAMockException.java │ │ │ │ ├── Defaults.java │ │ │ │ ├── MockAuthenticationBuilder.java │ │ │ │ ├── OAuthenticationTestingBuilder.java │ │ │ │ ├── OpenidClaimSetBuilder.java │ │ │ │ ├── OpenidTokenBuilder.java │ │ │ │ └── annotations │ │ │ │ ├── AbstractAnnotatedAuthenticationBuilder.java │ │ │ │ ├── Claims.java │ │ │ │ ├── ClasspathClaims.java │ │ │ │ ├── DoubleClaim.java │ │ │ │ ├── IntClaim.java │ │ │ │ ├── InvalidClaimException.java │ │ │ │ ├── InvalidJsonException.java │ │ │ │ ├── JsonFileClaim.java │ │ │ │ ├── JsonObjectArrayClaim.java │ │ │ │ ├── JsonObjectClaim.java │ │ │ │ ├── LongClaim.java │ │ │ │ ├── NestedClaims.java │ │ │ │ ├── OpenIdAddress.java │ │ │ │ ├── OpenIdClaims.java │ │ │ │ ├── StringArrayClaim.java │ │ │ │ ├── StringClaim.java │ │ │ │ ├── WithJwt.java │ │ │ │ ├── WithMockAuthentication.java │ │ │ │ ├── WithMockBearerTokenAuthentication.java │ │ │ │ ├── WithMockJwtAuth.java │ │ │ │ ├── WithOAuth2Login.java │ │ │ │ ├── WithOidcLogin.java │ │ │ │ ├── WithOpaqueToken.java │ │ │ │ └── parameterized │ │ │ │ ├── AuthenticationSource.java │ │ │ │ ├── OAuth2LoginAuthenticationSource.java │ │ │ │ ├── OidcLoginAuthenticationSource.java │ │ │ │ ├── ParameterizedAuthentication.java │ │ │ │ ├── ParameterizedOAuth2Login.java │ │ │ │ └── ParameterizedOidcLogin.java │ │ │ └── test │ │ │ └── support │ │ │ └── web │ │ │ ├── ByteArrayHttpOutputMessage.java │ │ │ ├── ConversionFailedException.java │ │ │ └── SerializationHelper.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ ├── java │ └── com │ │ └── c4_soft │ │ └── springaddons │ │ └── security │ │ └── oauth2 │ │ └── test │ │ └── annotations │ │ └── ClasspathClaimsTest.java │ └── resources │ └── ch4mp.json ├── spring-addons-oauth2 ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── c4_soft │ └── springaddons │ └── security │ └── oidc │ ├── ClaimSet.java │ ├── DelegatingMap.java │ ├── ModifiableClaimSet.java │ ├── OAuthentication.java │ ├── OpenidClaimSet.java │ ├── OpenidToken.java │ ├── UnmodifiableClaimSet.java │ ├── UnparsableClaimException.java │ └── spring │ ├── C4MethodSecurityExpressionHandler.java │ ├── C4MethodSecurityExpressionRoot.java │ ├── SpringAddonsMethodSecurityExpressionHandler.java │ └── SpringAddonsMethodSecurityExpressionRoot.java ├── spring-addons-starter-oidc-test ├── README.MD ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── c4_soft │ └── springaddons │ └── security │ └── oauth2 │ └── test │ ├── webflux │ ├── AddonsWebfluxComponentTest.java │ ├── AddonsWebfluxTestConf.java │ ├── AuthenticationConfigurer.java │ ├── AutoConfigureAddonsWebfluxClientSecurity.java │ ├── AutoConfigureAddonsWebfluxMinimalSecurity.java │ ├── AutoConfigureAddonsWebfluxResourceServerSecurity.java │ ├── MockAuthenticationWebTestClientConfigurer.java │ ├── OidcIdAuthenticationTokenWebTestClientConfigurer.java │ ├── WebTestClientProperties.java │ └── WebTestClientSupport.java │ └── webmvc │ ├── AddonsWebmvcComponentTest.java │ ├── AddonsWebmvcTestConf.java │ ├── AuthenticationRequestPostProcessor.java │ ├── AutoConfigureAddonsWebmvcClientSecurity.java │ ├── AutoConfigureAddonsWebmvcMinimalSecurity.java │ ├── AutoConfigureAddonsWebmvcResourceServerSecurity.java │ ├── MockAuthenticationRequestPostProcessor.java │ ├── MockMvcPerformException.java │ ├── MockMvcProperties.java │ ├── MockMvcSupport.java │ ├── SecurityContextRequestPostProcessorSupport.java │ └── ServletUnitTestingSupport.java ├── spring-addons-starter-oidc ├── README.MD ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── security │ │ │ └── oidc │ │ │ └── starter │ │ │ ├── AdditionalParamsAuthorizationRequestCustomizer.java │ │ │ ├── ByIssuerOpenidProviderPropertiesResolver.java │ │ │ ├── ClaimSetAuthoritiesConverter.java │ │ │ ├── CompositeOAuth2AuthorizationRequestCustomizer.java │ │ │ ├── ConfigurableClaimSetAuthoritiesConverter.java │ │ │ ├── LogoutRequestUriBuilder.java │ │ │ ├── OpenidProviderPropertiesResolver.java │ │ │ ├── SpringAddonsOAuth2LogoutRequestUriBuilder.java │ │ │ ├── properties │ │ │ ├── CorsProperties.java │ │ │ ├── Csrf.java │ │ │ ├── InvalidRedirectionUriException.java │ │ │ ├── MisconfiguredPostLoginUriException.java │ │ │ ├── MisconfiguredPostLogoutUriException.java │ │ │ ├── NotAConfiguredOpenidProviderException.java │ │ │ ├── SpringAddonsOidcClientProperties.java │ │ │ ├── SpringAddonsOidcProperties.java │ │ │ ├── SpringAddonsOidcResourceServerProperties.java │ │ │ └── condition │ │ │ │ ├── HasClientCorsPropertiesCondition.java │ │ │ │ ├── HasCorsPropertiesCondition.java │ │ │ │ ├── HasOAuth2RegistrationPropertiesCondition.java │ │ │ │ ├── HasPropertyPrefixCondition.java │ │ │ │ ├── HasResourceServerCorsPropertiesCondition.java │ │ │ │ ├── bean │ │ │ │ ├── AuthenticationConverterMissingCondition.java │ │ │ │ ├── BackwardCompatibleCorsPropertiesCondition.java │ │ │ │ ├── CookieCsrfCondition.java │ │ │ │ ├── DefaultAuthenticationEntryPointCondition.java │ │ │ │ ├── DefaultAuthenticationFailureHandlerCondition.java │ │ │ │ ├── DefaultAuthenticationManagerResolverCondition.java │ │ │ │ ├── DefaultAuthenticationSuccessHandlerCondition.java │ │ │ │ ├── DefaultCorsFilterCondition.java │ │ │ │ ├── DefaultCorsWebFilterCondition.java │ │ │ │ ├── DefaultGrantedAuthoritiesMapperCondition.java │ │ │ │ ├── DefaultJwtAbstractAuthenticationTokenConverterCondition.java │ │ │ │ ├── DefaultOAuth2AuthorizedClientManagerCondition.java │ │ │ │ ├── DefaultOAuth2AuthorizedClientProviderCondition.java │ │ │ │ ├── DefaultOidcBackChannelLogoutHandlerCondition.java │ │ │ │ ├── DefaultOidcSessionRegistryCondition.java │ │ │ │ ├── DefaultOpaqueTokenAuthenticationConverterCondition.java │ │ │ │ ├── DefaultReactiveOAuth2AuthorizedClientManagerCondition.java │ │ │ │ ├── DefaultReactiveOAuth2AuthorizedClientProviderCondition.java │ │ │ │ ├── IsIntrospectingResourceServerCondition.java │ │ │ │ └── IsJwtDecoderResourceServerCondition.java │ │ │ │ └── configuration │ │ │ │ ├── IsClientWithLoginCondition.java │ │ │ │ ├── IsNotServlet.java │ │ │ │ ├── IsOidcResourceServerCondition.java │ │ │ │ ├── IsReactiveOauth2ClientCondition.java │ │ │ │ └── IsServletOauth2ClientCondition.java │ │ │ ├── reactive │ │ │ ├── AuthorizeExchangeSpecPostProcessor.java │ │ │ ├── ReactiveConfigurationSupport.java │ │ │ ├── ReactiveHttpSecurityPostProcessor.java │ │ │ ├── ReactiveSpringAddonsOidcBeans.java │ │ │ ├── ServerHttpRequestSupport.java │ │ │ ├── client │ │ │ │ ├── C4Oauth2ServerRedirectStrategy.java │ │ │ │ ├── ClientAuthorizeExchangeSpecPostProcessor.java │ │ │ │ ├── ClientReactiveHttpSecurityPostProcessor.java │ │ │ │ ├── PerRegistrationReactiveOAuth2AuthorizedClientProvider.java │ │ │ │ ├── ReactiveSpringAddonsOAuth2AuthorizedClientBeans.java │ │ │ │ ├── ReactiveSpringAddonsOidcClientWithLoginBeans.java │ │ │ │ ├── SpringAddonsOauth2ServerAuthenticationFailureHandler.java │ │ │ │ ├── SpringAddonsOauth2ServerAuthenticationSuccessHandler.java │ │ │ │ ├── SpringAddonsOauth2ServerRedirectStrategy.java │ │ │ │ ├── SpringAddonsServerAuthenticationEntryPoint.java │ │ │ │ ├── SpringAddonsServerLogoutSuccessHandler.java │ │ │ │ └── SpringAddonsServerOAuth2AuthorizationRequestResolver.java │ │ │ └── resourceserver │ │ │ │ ├── DefaultSpringAddonsReactiveJwtDecoderFactory.java │ │ │ │ ├── ReactiveJWTClaimsSetAuthenticationManager.java │ │ │ │ ├── ReactiveJwtAbstractAuthenticationTokenConverter.java │ │ │ │ ├── ReactiveSpringAddonsOidcResourceServerBeans.java │ │ │ │ ├── ResourceServerAuthorizeExchangeSpecPostProcessor.java │ │ │ │ ├── ResourceServerReactiveHttpSecurityPostProcessor.java │ │ │ │ ├── SpringAddonsReactiveJwtAuthenticationManagerResolver.java │ │ │ │ └── SpringAddonsReactiveJwtDecoderFactory.java │ │ │ └── synchronised │ │ │ ├── ExpressionInterceptUrlRegistryPostProcessor.java │ │ │ ├── HttpServletRequestSupport.java │ │ │ ├── ServletConfigurationSupport.java │ │ │ ├── SpringAddonsOidcBeans.java │ │ │ ├── SynchronizedHttpSecurityPostProcessor.java │ │ │ ├── client │ │ │ ├── C4Oauth2RedirectStrategy.java │ │ │ ├── ClientExpressionInterceptUrlRegistryPostProcessor.java │ │ │ ├── ClientSynchronizedHttpSecurityPostProcessor.java │ │ │ ├── PerRegistrationOAuth2AuthorizedClientProvider.java │ │ │ ├── PreAuthorizationCodeRedirectStrategy.java │ │ │ ├── SpringAddonsAuthenticationEntryPoint.java │ │ │ ├── SpringAddonsLogoutSuccessHandler.java │ │ │ ├── SpringAddonsOAuth2AuthorizationRequestResolver.java │ │ │ ├── SpringAddonsOAuth2AuthorizedClientBeans.java │ │ │ ├── SpringAddonsOauth2AuthenticationFailureHandler.java │ │ │ ├── SpringAddonsOauth2AuthenticationSuccessHandler.java │ │ │ ├── SpringAddonsOauth2RedirectStrategy.java │ │ │ └── SpringAddonsOidcClientWithLoginBeans.java │ │ │ └── resourceserver │ │ │ ├── DefaultSpringAddonsJwtDecoderFactory.java │ │ │ ├── JWTClaimsSetAuthenticationManager.java │ │ │ ├── JwtAbstractAuthenticationTokenConverter.java │ │ │ ├── ResourceServerExpressionInterceptUrlRegistryPostProcessor.java │ │ │ ├── ResourceServerSynchronizedHttpSecurityPostProcessor.java │ │ │ ├── SpringAddonsJwtAuthenticationManagerResolver.java │ │ │ ├── SpringAddonsJwtDecoderFactory.java │ │ │ └── SpringAddonsOidcResourceServerBeans.java │ └── resources │ │ ├── META-INF │ │ └── spring │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ │ └── c4-spring-addons.properties │ └── test │ └── java │ └── com │ └── c4_soft │ └── springaddons │ └── security │ └── oidc │ └── starter │ ├── ConfigurableJwtGrantedAuthoritiesConverterTest.java │ ├── properties │ └── SpringAddonsOidcClientPropertiesTest.java │ ├── reactive │ └── client │ │ └── SpringAddonsServerOAuth2AuthorizationRequestResolverTest.java │ └── synchronised │ └── client │ ├── SpringAddonsLogoutSuccessHandlerTest.java │ └── SpringAddonsOAuth2AuthorizationRequestResolverTest.java ├── spring-addons-starter-openapi ├── README.MD ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── c4_soft │ │ └── springaddons │ │ └── openapi │ │ ├── EnumPossibleValuesExtractor.java │ │ ├── MockHttpOutputMessage.java │ │ ├── SpringAddonsOpenapiAutoConfiguration.java │ │ ├── SpringReactiveEnumModelConverter.java │ │ └── SpringServletEnumModelConverter.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── spring-addons-starter-recaptcha ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── c4_soft │ │ │ └── springaddons │ │ │ └── starter │ │ │ └── recaptcha │ │ │ ├── C4ReCaptchaSettings.java │ │ │ ├── C4ReCaptchaValidationService.java │ │ │ ├── ReCaptchaValidationException.java │ │ │ ├── SpringBootAutoConfiguration.java │ │ │ ├── V2ValidationResponseDto.java │ │ │ └── V3ValidationResponseDto.java │ └── resources │ │ └── META-INF │ │ ├── additional-spring-configuration-metadata.json │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── resources │ └── application.properties └── spring-addons-starter-rest ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── c4_soft │ │ └── springaddons │ │ └── rest │ │ ├── AbstractWebClientBuilderFactoryBean.java │ │ ├── HttpExchangeProxyFactoryBean.java │ │ ├── ProxySupport.java │ │ ├── RestClientHttpExchangeProxyFactoryBean.java │ │ ├── RestConfigurationNotFoundException.java │ │ ├── RestMisconfigurationException.java │ │ ├── SpringAddonsRestProperties.java │ │ ├── SystemProxyProperties.java │ │ ├── WebClientHttpExchangeProxyFactoryBean.java │ │ ├── reactive │ │ ├── DefaultReactiveAuthorizationFailureHandlerCondition.java │ │ ├── ServerWebClientBuilderFactoryBean.java │ │ ├── ServerWebClientFactoryBean.java │ │ ├── SpringAddonsServerWebClientBeanDefinitionRegistryPostProcessor.java │ │ ├── SpringAddonsServerWebClientBeans.java │ │ └── SpringAddonsServerWebClientSupport.java │ │ └── synchronised │ │ ├── DefaultAuthorizationFailureHandlerCondition.java │ │ ├── HttpComponentsClientHttpRequestFactoryHelper.java │ │ ├── IsServletWithWebClientCondition.java │ │ ├── JettyClientHttpRequestFactoryHelper.java │ │ ├── RestClientBuilderFactoryBean.java │ │ ├── RestClientFactoryBean.java │ │ ├── ServletWebClientBuilderFactoryBean.java │ │ ├── ServletWebClientFactoryBean.java │ │ ├── SpringAddonsClientHttpRequestFactory.java │ │ ├── SpringAddonsRestClientBeanDefinitionRegistryPostProcessor.java │ │ ├── SpringAddonsRestClientBeans.java │ │ ├── SpringAddonsServletWebClientBeanDefinitionRegistryPostProcessor.java │ │ ├── SpringAddonsServletWebClientBeans.java │ │ └── SpringAddonsServletWebClientSupport.java └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports └── test ├── java └── com │ └── c4_soft │ └── springaddons │ └── rest │ ├── AbstractSpringAddonsClientHttpRequestFactoryTest.java │ ├── SpringAddonsClientHttpRequestFactoryDisabledTest.java │ ├── SpringAddonsClientHttpRequestFactoryFullTest.java │ ├── SpringAddonsClientHttpRequestFactoryMinimalTest.java │ ├── SpringAddonsClientHttpRequestFactoryStdEnvVarsTest.java │ ├── StubBootApplication.java │ ├── reactive │ ├── SpringAddonsServerWebClientBeanDefinitionRegistryPostProcessorTest.java │ └── SpringAddonsServerWebClientSupportTest.java │ └── synchronised │ └── SpringAddonsRestClientBeanDefinitionRegistryPostProcessorTest.java └── resources ├── application.yml └── ch4mp.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: ch4mpy 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | polar: # Replace with a single Polar username 14 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: ch4mpy 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Code sample** 14 | Ideally, provide me with : 15 | 1. failing test 16 | 2. `@Component` under test (no, not only `@Controllers` can be tested with this lib) 17 | 3. spring-security configuration involved (runtime and tests) 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Additional context** 23 | Add any other context about the problem here. 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: ch4mpy 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | # compiled output 5 | /dist 6 | /tmp 7 | /out-tsc 8 | **/.angular/cache 9 | 10 | # dependencies 11 | **/node_modules/ 12 | 13 | # log files 14 | *.log 15 | 16 | # IDEs and editors 17 | .c9/ 18 | *.launch 19 | *.sublime-workspace 20 | 21 | ### STS ### 22 | .apt_generated 23 | .classpath 24 | .factorypath 25 | .project 26 | .settings 27 | .springBeans 28 | .dbeaver-data-sources.xml 29 | .sts4-cache/ 30 | .dbeaver/ 31 | .metadata/ 32 | 33 | ### IntelliJ IDEA ### 34 | .idea 35 | *.iws 36 | *.iml 37 | *.ipr 38 | 39 | ### NetBeans ### 40 | nbproject/private/ 41 | build/ 42 | nbbuild/ 43 | dist/ 44 | nbdist/ 45 | .nb-gradle/ 46 | 47 | ### VSCode 48 | .vscode/ 49 | !.vscode/settings.json 50 | !.vscode/tasks.json 51 | !.vscode/launch.json 52 | !.vscode/extensions.json 53 | 54 | # misc 55 | /.sass-cache 56 | /connect.lock 57 | /coverage 58 | /libpeerconnection.log 59 | npm-debug.log 60 | testem.log 61 | /typings 62 | .attach_pid* 63 | 64 | # e2e 65 | /e2e/*.js 66 | /e2e/*.map 67 | 68 | # System Files 69 | .DS_Store 70 | Thumbs.db 71 | 72 | # secret files 73 | application-secret.properties 74 | 75 | # release files 76 | release.properties 77 | **/*.releaseBackup 78 | 79 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip 2 | -------------------------------------------------------------------------------- /.readme_resources/auth0-application-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/.readme_resources/auth0-application-details.png -------------------------------------------------------------------------------- /.readme_resources/auth0-role-creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/.readme_resources/auth0-role-creation.png -------------------------------------------------------------------------------- /.readme_resources/authorization-code_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/.readme_resources/authorization-code_flow.png -------------------------------------------------------------------------------- /.readme_resources/aws-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/.readme_resources/aws-console.png -------------------------------------------------------------------------------- /.readme_resources/create-user-pool-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/.readme_resources/create-user-pool-1.png -------------------------------------------------------------------------------- /.readme_resources/create-user-pool-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/.readme_resources/create-user-pool-2.png -------------------------------------------------------------------------------- /.readme_resources/create-user-pool-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/.readme_resources/create-user-pool-4.png -------------------------------------------------------------------------------- /.readme_resources/keycloak-confidential.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/.readme_resources/keycloak-confidential.png -------------------------------------------------------------------------------- /infra/.env: -------------------------------------------------------------------------------- 1 | KEYCLOAK_ADMIN_PASSWORD=admin -------------------------------------------------------------------------------- /infra/.gitignore: -------------------------------------------------------------------------------- 1 | ssl/ 2 | docker-compose-ssl.yaml 3 | -------------------------------------------------------------------------------- /lombok.config: -------------------------------------------------------------------------------- 1 | lombok.addLombokGeneratedAnnotation = true -------------------------------------------------------------------------------- /samples/oauth2-bff-reactive/README.md: -------------------------------------------------------------------------------- 1 | # Reactive OAuth2 BFF 2 | Sample for an OAuth2 BFF using the WebFlux version of Spring Cloud Gateway. 3 | 4 | The Javascript UI is written with JQuery and included in a Thymeleaf template. 5 | 6 | As logout (made with a POST) and PUT request are made with ajax (XHR), the CSRF protection is configured with `HttpOnly=flase` cookies. 7 | 8 | The `webmvc-jwt-default` module can be used as _"downstream micro-service"_. -------------------------------------------------------------------------------- /samples/oauth2-bff-reactive/src/main/java/com/c4soft/springaddons/samples/BffApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.samples; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class BffApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(BffApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/oauth2-bff-reactive/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/samples/oauth2-bff-reactive/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /samples/oauth2-bff-servlet/README.md: -------------------------------------------------------------------------------- 1 | # Servlet OAuth2 BFF 2 | Sample for an OAuth2 BFF using the WebMvc (aka servlet or synchronized) version of Spring Cloud Gateway. 3 | 4 | The Javascript UI is written with JQuery and included in a Thymeleaf template. 5 | 6 | As logout (made with a POST) and PUT request are made with ajax (XHR), the CSRF protection is configured with `HttpOnly=flase` cookies. 7 | 8 | The `webmvc-jwt-default` module can be used as _"downstream micro-service"_. -------------------------------------------------------------------------------- /samples/oauth2-bff-servlet/src/main/java/com/c4soft/springaddons/samples/BffApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.samples; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class BffApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(BffApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/oauth2-bff-servlet/src/main/java/com/c4soft/springaddons/samples/UiController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.samples; 2 | 3 | import java.net.URISyntaxException; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.security.core.Authentication; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.Model; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PutMapping; 10 | import org.springframework.web.bind.annotation.ResponseBody; 11 | import org.springframework.web.bind.annotation.ResponseStatus; 12 | import org.springframework.web.servlet.view.RedirectView; 13 | import lombok.extern.slf4j.Slf4j; 14 | 15 | @Controller 16 | @Slf4j 17 | public class UiController { 18 | 19 | @GetMapping({"", "/",}) 20 | public RedirectView getIndex() throws URISyntaxException { 21 | return new RedirectView("/ui/"); 22 | } 23 | 24 | @GetMapping({"/ui", "/ui/"}) 25 | public String getIndex(Model model, Authentication auth) { 26 | model.addAttribute("isAuthenticated", auth != null && auth.isAuthenticated()); 27 | model.addAttribute("username", auth == null ? null : auth.getName()); 28 | return "index"; 29 | } 30 | 31 | @PutMapping("/ui/xhr") 32 | @ResponseBody 33 | @ResponseStatus(HttpStatus.ACCEPTED) 34 | public void post() {} 35 | } 36 | -------------------------------------------------------------------------------- /samples/oauth2-bff-servlet/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/samples/oauth2-bff-servlet/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /samples/springdoc-openapi-2494-reactive/openapi.json: -------------------------------------------------------------------------------- 1 | {"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://localhost:8080","description":"Generated server url"}],"paths":{"/demo":{"get":{"tags":["demo-controller"],"operationId":"getDemo","parameters":[{"name":"nameRequestParam","in":"query","required":true,"schema":{"type":"string","enum":["name a","name b"]}},{"name":"strRequestParam","in":"query","required":true,"schema":{"type":"string","enum":["str a","str b"]}},{"name":"bijRequestParam","in":"query","required":true,"schema":{"type":"string","enum":["bij a","bij b"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Dto"}}}}}},"put":{"tags":["demo-controller"],"operationId":"putDemo","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Dto"}}},"required":true},"responses":{"200":{"description":"OK"}}}}},"components":{"schemas":{"Dto":{"required":["bij","name","str"],"type":"object","properties":{"name":{"type":"string","enum":["name a","name b"]},"str":{"type":"string","enum":["str a","str b"]},"bij":{"type":"string","enum":["bij a","bij b"]}}}}}} -------------------------------------------------------------------------------- /samples/springdoc-openapi-2494-reactive/src/main/java/com/c4soft/EnumBugReproducerApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class EnumBugReproducerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(EnumBugReproducerApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/springdoc-openapi-2494-reactive/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/springdoc-openapi-2494-servlet/openapi.json: -------------------------------------------------------------------------------- 1 | {"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://localhost:8080","description":"Generated server url"}],"paths":{"/demo":{"get":{"tags":["demo-controller"],"operationId":"getDemo","parameters":[{"name":"nameRequestParam","in":"query","required":true,"schema":{"type":"string","enum":["A","B"]}},{"name":"strRequestParam","in":"query","required":true,"schema":{"type":"string","enum":["A","B"]}},{"name":"bijRequestParam","in":"query","required":true,"schema":{"type":"string","enum":["bij a","bij b"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/Dto"}}}}}},"put":{"tags":["demo-controller"],"operationId":"putDemo","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Dto"}}},"required":true},"responses":{"200":{"description":"OK"}}}}},"components":{"schemas":{"Dto":{"required":["bij","name","str"],"type":"object","properties":{"name":{"type":"string","enum":["A","B"]},"str":{"type":"string","enum":["str a","str b"]},"bij":{"type":"string","enum":["bij a","bij b"]}}}}}} -------------------------------------------------------------------------------- /samples/springdoc-openapi-2494-servlet/src/main/java/com/c4soft/EnumBugReproducerApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class EnumBugReproducerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(EnumBugReproducerApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /samples/springdoc-openapi-2494-servlet/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /samples/tutorials/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.c4-soft.springaddons.samples 6 | spring-addons-samples 7 | 8.1.16-SNAPSHOT 8 | .. 9 | 10 | com.c4-soft.springaddons.samples.tutorials 11 | tutorials 12 | pom 13 | 14 | 15 | resource-server_with_introspection 16 | resource-server_with_oauthentication 17 | resource-server_with_specialized_oauthentication 18 | resource-server_with_ui 19 | resource-server_with_additional-header 20 | reactive-client 21 | servlet-client 22 | reactive-resource-server 23 | servlet-resource-server 24 | resource-server_multitenant_dynamic 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/tutorials/reactive-client/src/main/java/com/c4soft/springaddons/tutorials/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.security.authentication.AnonymousAuthenticationToken; 4 | import org.springframework.security.core.Authentication; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | import reactor.core.publisher.Mono; 10 | 11 | @Controller 12 | public class IndexController { 13 | 14 | @GetMapping("/") 15 | public Mono getIndex(Authentication auth, Model model) { 16 | model.addAttribute("isAuthenticated", auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken)); 17 | return Mono.just("index.html"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/tutorials/reactive-client/src/main/java/com/c4soft/springaddons/tutorials/ReactiveClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.context.properties.ConfigurationPropertiesScan; 6 | 7 | @SpringBootApplication 8 | @ConfigurationPropertiesScan 9 | public class ReactiveClientApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ReactiveClientApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /samples/tutorials/reactive-client/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _______ _ _ _ 2 | |__ __| | | (_) | | 3 | | |_ _| |_ ___ _ __ _ __ _| |___ 4 | | | | | | __/ _ \| '__| |/ _` | / __| 5 | | | |_| | || (_) | | | | (_| | \__ \ 6 | __|_|\__,_|\__\___/|_|_ |_|\__,_|_|___/ _____ _ _ _ 7 | | __ \ | | (_) / ____| (_) | | 8 | | |__) |___ __ _ ___| |_ ___ _____ | | | |_ ___ _ __ | |_ 9 | | _ // _ \/ _` |/ __| __| \ \ / / _ \ | | | | |/ _ \ '_ \| __| 10 | | | \ \ __/ (_| | (__| |_| |\ V / __/ | |____| | | __/ | | | |_ 11 | |_| \_\___|\__,_|\___|\__|_| \_/ \___| \_____|_|_|\___|_| |_|\__| 12 | | | / ____| | | || | 13 | | |__ _ _ | | | |__| || |_ _ __ ___ _ __ _ _ 14 | | '_ \| | | | | | | '_ \__ _| '_ ` _ \| '_ \| | | | 15 | | |_) | |_| | | |____| | | | | | | | | | | | |_) | |_| | 16 | |_.__/ \__, | \_____|_| |_| |_| |_| |_| |_| .__/ \__, | 17 | __/ | | | __/ | 18 | |___/ |_| |___/ -------------------------------------------------------------------------------- /samples/tutorials/reactive-client/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Reactive Application 10 | 11 | 12 | 13 | 14 | 15 |
16 |

Static Index

17 | 18 | 19 |
20 | -------------------------------------------------------------------------------- /samples/tutorials/reactive-client/src/main/resources/static/nice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Servlet Client 10 | 11 | 12 | 13 | 14 | 15 |
16 |

You are so nice!

17 |
18 | -------------------------------------------------------------------------------- /samples/tutorials/reactive-client/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Servlet Client 10 | 11 | 12 | 13 | 14 | 15 |
16 |

Dynamic Index

17 | 18 | 19 |
20 | -------------------------------------------------------------------------------- /samples/tutorials/reactive-client/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /samples/tutorials/reactive-resource-server/src/main/java/com/c4soft/springaddons/tutorials/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.security.core.Authentication; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | import reactor.core.publisher.Mono; 8 | 9 | @RestController 10 | public class GreetingController { 11 | 12 | @GetMapping("/greet") 13 | public Mono getGreeting(Authentication auth) { 14 | return Mono.just(new MessageDto("Hi %s! You are granted with: %s.".formatted(auth.getName(), auth.getAuthorities()))); 15 | } 16 | 17 | @GetMapping("/restricted") 18 | @PreAuthorize("hasAuthority('NICE')") 19 | public Mono getRestricted() { 20 | return Mono.just(new MessageDto("You are so nice!")); 21 | } 22 | 23 | static record MessageDto(String body) { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/tutorials/reactive-resource-server/src/main/java/com/c4soft/springaddons/tutorials/ReactiveResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ReactiveResourceServerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ReactiveResourceServerApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /samples/tutorials/reactive-resource-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | scheme: http 2 | origins: http://localhost:4200,https://localhost:4200 3 | permit-all: /public/** 4 | keycloak-port: 8442 5 | keycloak-issuer: https://oidc.c4-soft.com/auth/realms/master 6 | cognito-issuer: https://cognito-idp.us-west-2.amazonaws.com/us-west-2_RzhmgLwjl 7 | auth0-issuer: https://dev-ch4mpy.eu.auth0.com/ 8 | 9 | server: 10 | error: 11 | include-message: always 12 | ssl: 13 | enabled: false 14 | 15 | spring: 16 | security: 17 | oauth2: 18 | resourceserver: 19 | jwt: 20 | issuer-uri: ${keycloak-issuer} 21 | 22 | spring-addons: 23 | issuers: 24 | - uri: ${keycloak-issuer} 25 | username-json-path: $.preferred_username 26 | claims: 27 | - jsonPath: $.realm_access.roles 28 | - jsonPath: $.resource_access.*.roles 29 | - uri: ${cognito-issuer} 30 | claims: 31 | - jsonPath: $.cognito:groups 32 | - uri: ${auth0-issuer} 33 | username-json-path: $['https://c4-soft.com/user']['name'] 34 | claims: 35 | - jsonPath: $.roles 36 | - jsonPath: $.groups 37 | - jsonPath: $.permissions 38 | 39 | --- 40 | scheme: https 41 | keycloak-port: 8443 42 | 43 | server: 44 | ssl: 45 | enabled: true 46 | 47 | spring: 48 | config: 49 | activate: 50 | on-profile: ssl -------------------------------------------------------------------------------- /samples/tutorials/reactive-resource-server/src/test/resources/auth0_badboy.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "tonton-pirate@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "tonton-pirate", 18 | "nickname": "Tonton Pirate", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "SKIPPER" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "permissions": [ 28 | "AUTHOR" 29 | ], 30 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 31 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 32 | "aud": [ 33 | "demo.c4-soft.com", 34 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 35 | ], 36 | "iat": 1687633329, 37 | "exp": 1687719729, 38 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 39 | "scope": "openid email" 40 | } -------------------------------------------------------------------------------- /samples/tutorials/reactive-resource-server/src/test/resources/auth0_nice.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "ch4mp@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "ch4mp", 18 | "nickname": "ch4mp", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "permissions": [ 28 | "NICE", "AUTHOR" 29 | ], 30 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 31 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 32 | "aud": [ 33 | "demo.c4-soft.com", 34 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 35 | ], 36 | "iat": 1687633329, 37 | "exp": 1687719729, 38 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 39 | "scope": "openid email" 40 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_multitenant_dynamic/src/main/java/com/c4soft/springaddons/tutorials/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.security.oauth2.core.oidc.StandardClaimNames; 5 | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | @RestController 10 | @PreAuthorize("isAuthenticated()") 11 | public class GreetingController { 12 | 13 | @GetMapping("/greet") 14 | public MessageDto getGreeting(JwtAuthenticationToken auth) { 15 | return new MessageDto( 16 | "Hi %s! You are granted with: %s and your email is %s." 17 | .formatted(auth.getName(), auth.getAuthorities(), auth.getTokenAttributes().get(StandardClaimNames.EMAIL))); 18 | } 19 | 20 | @GetMapping("/nice") 21 | @PreAuthorize("hasAuthority('NICE')") 22 | public MessageDto getNiceGreeting(JwtAuthenticationToken auth) { 23 | return new MessageDto("Dear %s! You are granted with: %s.".formatted(auth.getName(), auth.getAuthorities())); 24 | } 25 | 26 | static record MessageDto(String body) { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_multitenant_dynamic/src/main/java/com/c4soft/springaddons/tutorials/ResourceServerMultitenantDynamicApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; 7 | import io.swagger.v3.oas.annotations.security.OAuthFlow; 8 | import io.swagger.v3.oas.annotations.security.OAuthFlows; 9 | import io.swagger.v3.oas.annotations.security.OAuthScope; 10 | import io.swagger.v3.oas.annotations.security.SecurityScheme; 11 | 12 | @SecurityScheme( 13 | name = "authorization-code", 14 | type = SecuritySchemeType.OAUTH2, 15 | flows = @OAuthFlows( 16 | authorizationCode = @OAuthFlow( 17 | authorizationUrl = "https://localhost:8443/realms/master/protocol/openid-connect/auth", 18 | tokenUrl = "https://localhost:8443/realms/master/protocol/openid-connect/token", 19 | scopes = { @OAuthScope(name = "openid"), @OAuthScope(name = "profile") }))) 20 | @SpringBootApplication 21 | public class ResourceServerMultitenantDynamicApplication { 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(ResourceServerMultitenantDynamicApplication.class, args); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_multitenant_dynamic/src/test/resources/keycloak_badboy.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "tonton-pirate@c4-soft.com", 3 | "email_verified": true, 4 | "realm_access": { 5 | "roles": [ 6 | "SKIPPER", "UNCLE" 7 | ] 8 | }, 9 | "iss": "http://localhost:8080/realms/master", 10 | "sub": "oauth2|c4-soft|5ff56dbb-71ef-4fe2-9358-3ae3240a9fff" 11 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_multitenant_dynamic/src/test/resources/keycloak_nice.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "ch4mp@c4-soft.com", 3 | "email_verified": true, 4 | "realm_access": { 5 | "roles": [ 6 | "USER_ROLES_EDITOR", "NICE", "AUTHOR" 7 | ] 8 | }, 9 | "iss": "http://localhost:8080/realms/master", 10 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 11 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_additional-header/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_additional-header/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/samples/tutorials/resource-server_with_additional-header/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_additional-header/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_additional-header/src/main/java/com/c4soft/springaddons/tutorials/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | import com.c4soft.springaddons.tutorials.SecurityConfig.MyAuth; 7 | 8 | @RestController 9 | @PreAuthorize("isAuthenticated()") 10 | public class GreetingController { 11 | 12 | @GetMapping("/greet") 13 | public MessageDto getGreeting(MyAuth auth) { 14 | // email From ID token in X-ID-Token header 15 | // Authorities from access token in Authorization header 16 | return new MessageDto("Hi %s! You are granted with: %s.".formatted(auth.getIdToken().getEmail(), 17 | auth.getAuthorities())); 18 | } 19 | 20 | static record MessageDto(String body) { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_additional-header/src/main/java/com/c4soft/springaddons/tutorials/ServletResourceServerWithAdditionalHeader.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ServletResourceServerWithAdditionalHeader { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ServletResourceServerWithAdditionalHeader.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_introspection/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_introspection/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/samples/tutorials/resource-server_with_introspection/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_introspection/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_introspection/src/main/java/com/c4soft/springaddons/tutorials/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.http.MediaType; 4 | import org.springframework.security.access.prepost.PreAuthorize; 5 | import org.springframework.security.core.Authentication; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | @RequestMapping(value = "/greet", produces = MediaType.APPLICATION_JSON_VALUE) 12 | public class GreetingController { 13 | 14 | @GetMapping() 15 | @PreAuthorize("hasAuthority('NICE')") 16 | public MessageDto getGreeting(Authentication auth) { 17 | return new MessageDto("Hi %s! You are granted with: %s.".formatted(auth.getName(), auth.getAuthorities())); 18 | } 19 | 20 | public static record MessageDto(String body) { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_introspection/src/main/java/com/c4soft/springaddons/tutorials/ResourceServerWithOAuthenticationApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ResourceServerWithOAuthenticationApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ResourceServerWithOAuthenticationApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_introspection/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _______ _ _ _ 2 | |__ __| | | (_) | | 3 | | |_ _| |_ ___ _ __ _ __ _| |___ 4 | | | | | | __/ _ \| '__| |/ _` | / __| 5 | | | |_| | || (_) | | | | (_| | \__ \ 6 | __|_|\__,_|\__\___/|_| |_|\__,_|_|___/ _ _ 7 | |_ _| | | | | (_) 8 | | | _ __ | |_ _ __ ___ ___ _ __ ___ ___| |_ _ ___ _ __ 9 | | | | '_ \| __| '__/ _ \/ __| '_ \ / _ \/ __| __| |/ _ \| '_ \ 10 | _| |_| | | | |_| | | (_) \__ \ |_) | __/ (__| |_| | (_) | | | | 11 | |_____|_| |_|\__|_| \___/|___/ .__/ \___|\___|\__|_|\___/|_| |_| 12 | | | 13 | |_| 14 | _ _ _ _ 15 | | | | | | || | 16 | | |__ _ _ ___| |__| || |_ _ __ ___ _ __ _ _ 17 | | '_ \| | | | / __| '_ \__ _| '_ ` _ \| '_ \| | | | 18 | | |_) | |_| | | (__| | | | | | | | | | | | |_) | |_| | 19 | |_.__/ \__, | \___|_| |_| |_| |_| |_| |_| .__/ \__, | 20 | __/ | | | __/ | 21 | |___/ |_| |___/ 22 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_introspection/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "ch4mp@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "ch4mp", 5 | "realm_access": { 6 | "roles": [ 7 | "NICE", 8 | "AUTHOR", 9 | "ROLE_AUTHORIZED_PERSONNEL" 10 | ] 11 | }, 12 | "iss": "https://oidc.c4-soft.com/auth/realms/spring-addons", 13 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 14 | "aud": [ 15 | "demo.c4-soft.com", 16 | "http://localhost:8080" 17 | ], 18 | "iat": 1687633329, 19 | "exp": 1687719729, 20 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 21 | "scope": "openid email" 22 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_introspection/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "tonton-pirate@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "tonton-pirate", 5 | "realm_access": { 6 | "roles": [ 7 | "UNCLE", 8 | "PIRATE" 9 | ] 10 | }, 11 | "iss": "https://oidc.c4-soft.com/auth/realms/spring-addons", 12 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 13 | "aud": [ 14 | "demo.c4-soft.com", 15 | "http://localhost:8080" 16 | ], 17 | "iat": 1687633329, 18 | "exp": 1687719729, 19 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 20 | "scope": "openid email" 21 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_oauthentication/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_oauthentication/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/samples/tutorials/resource-server_with_oauthentication/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_oauthentication/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_oauthentication/src/main/java/com/c4soft/springaddons/tutorials/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | import com.c4_soft.springaddons.security.oidc.OAuthentication; 7 | import com.c4_soft.springaddons.security.oidc.OpenidToken; 8 | 9 | @RestController 10 | @PreAuthorize("isAuthenticated()") 11 | public class GreetingController { 12 | 13 | @GetMapping("/greet") 14 | public MessageDto getGreeting(OAuthentication auth) { 15 | return new MessageDto("Hi %s! You are granted with: %s and your email is %s." 16 | .formatted(auth.getName(), auth.getAuthorities(), auth.getClaims().getEmail())); 17 | } 18 | 19 | @GetMapping("/nice") 20 | @PreAuthorize("hasAuthority('NICE')") 21 | public MessageDto getNiceGreeting(OAuthentication auth) { 22 | return new MessageDto( 23 | "Dear %s! You are granted with: %s.".formatted(auth.getName(), auth.getAuthorities())); 24 | } 25 | 26 | static record MessageDto(String body) { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_oauthentication/src/test/resources/auth0_badboy.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "tonton-pirate@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "tonton-pirate", 18 | "nickname": "Tonton Pirate", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "SKIPPER" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "permissions": [ 28 | "AUTHOR" 29 | ], 30 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 31 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 32 | "aud": [ 33 | "demo.c4-soft.com", 34 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 35 | ], 36 | "iat": 1687633329, 37 | "exp": 1687719729, 38 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 39 | "scope": "openid email" 40 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_oauthentication/src/test/resources/auth0_nice.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "ch4mp@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "ch4mp", 18 | "nickname": "ch4mp", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "permissions": [ 28 | "NICE", "AUTHOR" 29 | ], 30 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 31 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 32 | "aud": [ 33 | "demo.c4-soft.com", 34 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 35 | ], 36 | "iat": 1687633329, 37 | "exp": 1687719729, 38 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 39 | "scope": "openid email" 40 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_specialized_oauthentication/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_specialized_oauthentication/src/main/java/com/c4soft/springaddons/tutorials/ProxiesAuthentication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import java.util.Collection; 4 | import java.util.Objects; 5 | import org.springframework.security.core.GrantedAuthority; 6 | import com.c4_soft.springaddons.security.oidc.OAuthentication; 7 | import lombok.Data; 8 | import lombok.EqualsAndHashCode; 9 | 10 | @Data 11 | @EqualsAndHashCode(callSuper = true) 12 | public class ProxiesAuthentication extends OAuthentication { 13 | private static final long serialVersionUID = 447991554788295331L; 14 | 15 | public ProxiesAuthentication(ProxiesToken token, 16 | Collection authorities) { 17 | super(token, authorities); 18 | } 19 | 20 | public boolean hasName(String username) { 21 | return Objects.equals(getName(), username); 22 | } 23 | 24 | public Proxy getProxyFor(String username) { 25 | return getAttributes().getProxyFor(username); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_specialized_oauthentication/src/main/java/com/c4soft/springaddons/tutorials/Proxy.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import java.io.Serializable; 4 | import java.util.Collection; 5 | import java.util.Collections; 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | import lombok.Data; 9 | 10 | @Data 11 | public class Proxy implements Serializable { 12 | private static final long serialVersionUID = 8853377414305913148L; 13 | 14 | private final String proxiedUsername; 15 | private final String tenantUsername; 16 | private final Set permissions; 17 | 18 | public Proxy(String proxiedUsername, String tenantUsername, Collection permissions) { 19 | this.proxiedUsername = proxiedUsername; 20 | this.tenantUsername = tenantUsername; 21 | this.permissions = Collections.unmodifiableSet(new HashSet<>(permissions)); 22 | } 23 | 24 | public boolean can(String permission) { 25 | return permissions.contains(permission); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_specialized_oauthentication/src/main/java/com/c4soft/springaddons/tutorials/ResourceServerWithOAuthenticationApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ResourceServerWithOAuthenticationApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ResourceServerWithOAuthenticationApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_specialized_oauthentication/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ch4mp", 3 | "preferred_username": "ch4mp", 4 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 5 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 6 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 7 | "scope": "openid email", 8 | "permissions": ["NICE", "AUTHOR"], 9 | "proxies": { 10 | "machin": ["truc", "bidule"], 11 | "chose": [], 12 | } 13 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_specialized_oauthentication/src/test/resources/tonton_proxy_ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tonton Pirate", 3 | "preferred_username": "Tonton Pirate", 4 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 5 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 6 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 7 | "scope": "openid email", 8 | "permissions": ["SKIPPER"], 9 | "proxies": { 10 | "ch4mp": ["greet"] 11 | } 12 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/readme-resources/greet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/samples/tutorials/resource-server_with_ui/readme-resources/greet.png -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/src/main/java/com/c4soft/springaddons/tutorials/ResourceServerWithUiApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ResourceServerWithUiApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ResourceServerWithUiApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/src/main/java/com/c4soft/springaddons/tutorials/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; 5 | 6 | /** 7 | * Security configuration is defined with application properties thanks to the following starters: 8 | *
    9 | *
  • spring-addons-webmvc-jwt-client which defines a 10 | * "client" security filter-chain (sessions, CSRF protection, OAuth2 login & logout, redirect unauthorized requests to login with 302) with high @Order 11 | * and security-matchers defined with com.c4-soft.springaddons.oidc.client.security-matchers property
  • 12 | *
  • spring-addons-webmvc-jwt-resource-server which 14 | * defines a "resource server" security filter-chain (no session, no CSRF protection, no login nor logout, returns 401 for unauthorized requests) with lowest 15 | * @Order and no security-matchers (processes all requests that were not processed by other security filter-chains)
  • 16 | *
17 | * 18 | * @author Jerome Wacongne ch4mp@c4-soft.com 19 | */ 20 | @Configuration 21 | @EnableMethodSecurity 22 | public class WebSecurityConfig { 23 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/src/main/java/com/c4soft/springaddons/tutorials/api/ApiController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials.api; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.security.oauth2.jwt.JwtClaimNames; 5 | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | @RequestMapping("/api") 12 | @PreAuthorize("isAuthenticated()") 13 | public class ApiController { 14 | @GetMapping("/greet") 15 | public String getGreeting(JwtAuthenticationToken auth) { 16 | return "Hi %s! You are authenticated by %s and granted with: %s." 17 | .formatted(auth.getName(), auth.getTokenAttributes().get(JwtClaimNames.ISS), auth.getAuthorities()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/src/main/java/com/c4soft/springaddons/tutorials/ui/GreetApi.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials.ui; 2 | 3 | import org.springframework.http.MediaType; 4 | import org.springframework.web.service.annotation.GetExchange; 5 | import org.springframework.web.service.annotation.HttpExchange; 6 | 7 | @HttpExchange(accept = MediaType.APPLICATION_JSON_VALUE) 8 | public interface GreetApi { 9 | @GetExchange(url = "/greet") 10 | String getGreeting(); 11 | } -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/src/main/java/com/c4soft/springaddons/tutorials/ui/RestClientsConfig.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials.ui; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.client.RestClient; 6 | import com.c4_soft.springaddons.rest.RestClientHttpExchangeProxyFactoryBean; 7 | 8 | @Configuration 9 | public class RestClientsConfig { 10 | 11 | @Bean 12 | GreetApi greetApi(RestClient greetClient) throws Exception { 13 | return new RestClientHttpExchangeProxyFactoryBean<>(GreetApi.class, greetClient).getObject(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch4mpy/spring-addons/1568a2c419e6636a6870566d4fa4ca652e5f313c/samples/tutorials/resource-server_with_ui/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/src/main/resources/templates/greet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Greetings! 10 | 12 | 14 | 15 | 16 | 17 |
18 |

Greetings from the REST API

19 |
..!..
20 |
21 | 22 |
23 |
24 | -------------------------------------------------------------------------------- /samples/tutorials/resource-server_with_ui/src/test/resources/ch4mp_keycloak.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm_access": { 3 | "roles": [ 4 | "NICE", "AUTHOR" 5 | ] 6 | }, 7 | "iss": "http://localhost:7080/auth/realms/spring-addons", 8 | "sub": "4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 9 | "preferred_username": "ch4mpy", 10 | "iat": 1687633329, 11 | "exp": 1687719729, 12 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 13 | "scope": "openid email" 14 | } -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/src/main/java/com/c4soft/springaddons/tutorials/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.security.authentication.AnonymousAuthenticationToken; 4 | import org.springframework.security.core.Authentication; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | @Controller 10 | public class IndexController { 11 | 12 | @GetMapping("/") 13 | public String getIndex(Authentication auth, Model model) { 14 | model.addAttribute("isAuthenticated", auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken)); 15 | return "index"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/src/main/java/com/c4soft/springaddons/tutorials/LogoutProperties.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import java.net.URI; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | import lombok.Data; 11 | 12 | @Data 13 | @Configuration 14 | @ConfigurationProperties(prefix = "logout") 15 | public class LogoutProperties { 16 | private Map registration = new HashMap<>(); 17 | 18 | @Data 19 | static class ProviderLogoutProperties { 20 | private URI logoutUri; 21 | private String postLogoutUriParameterName; 22 | } 23 | } -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/src/main/java/com/c4soft/springaddons/tutorials/ServletClientApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.context.properties.ConfigurationPropertiesScan; 6 | 7 | @SpringBootApplication 8 | @ConfigurationPropertiesScan 9 | public class ServletClientApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ServletClientApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _______ _ _ _ 2 | |__ __| | | (_) | | 3 | | |_ _| |_ ___ _ __ _ __ _| |___ 4 | | | | | | __/ _ \| '__| |/ _` | / __| 5 | | | |_| | || (_) | | | | (_| | \__ \ 6 | |_|\__,_|\__\___/|_| |_|\__,_|_|___/ 7 | _____ _ _ _____ _ _ _ 8 | / ____| | | | | / ____| (_) | | 9 | | (___ ___ _ ____ _| | ___| |_ | | | |_ ___ _ __ | |_ 10 | \___ \ / _ \ '__\ \ / / |/ _ \ __| | | | | |/ _ \ '_ \| __| 11 | ____) | __/ | \ V /| | __/ |_ | |____| | | __/ | | | |_ 12 | |_____/ \___|_| ___\_/_|_|\___|\__| \_____|_|_|\___|_| |_|\__| 13 | | | / ____| | | || | 14 | | |__ _ _ | | | |__| || |_ _ __ ___ _ __ _ _ 15 | | '_ \| | | | | | | '_ \__ _| '_ ` _ \| '_ \| | | | 16 | | |_) | |_| | | |____| | | | | | | | | | | | |_) | |_| | 17 | |_.__/ \__, | \_____|_| |_| |_| |_| |_| |_| .__/ \__, | 18 | __/ | | | __/ | 19 | |___/ |_| |___/ -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Servlet Client 10 | 11 | 12 | 13 | 14 | 15 |
16 |

Static Index

17 | 18 | 19 |
20 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/src/main/resources/static/nice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Servlet Client 10 | 11 | 12 | 13 | 14 | 15 |
16 |

You are so nice!

17 |
18 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Servlet Client 10 | 11 | 12 | 13 | 14 | 15 |
16 |

Dynamic Index

17 | 18 | 19 |
20 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-client/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /samples/tutorials/servlet-resource-server/src/main/java/com/c4soft/springaddons/tutorials/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.security.core.Authentication; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | public class GreetingController { 10 | 11 | @GetMapping("/greet") 12 | public MessageDto getGreeting(Authentication auth) { 13 | return new MessageDto("Hi %s! You are granted with: %s.".formatted(auth.getName(), auth.getAuthorities())); 14 | } 15 | 16 | @GetMapping("/restricted") 17 | @PreAuthorize("hasAnyAuthority('NICE', 'VERY_NICE')") 18 | public MessageDto getRestricted() { 19 | return new MessageDto("You are so nice!"); 20 | } 21 | 22 | static record MessageDto(String body) { 23 | } 24 | } -------------------------------------------------------------------------------- /samples/tutorials/servlet-resource-server/src/main/java/com/c4soft/springaddons/tutorials/ServletResourceServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ServletResourceServerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ServletResourceServerApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-resource-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | scheme: http 2 | origins: ${scheme}://localhost:4200 3 | keycloak-port: 8442 4 | keycloak-issuer: https://oidc.c4-soft.com/auth/realms/master 5 | cognito-issuer: https://cognito-idp.us-west-2.amazonaws.com/us-west-2_RzhmgLwjl 6 | auth0-issuer: https://dev-ch4mpy.eu.auth0.com/ 7 | 8 | server: 9 | error: 10 | include-message: always 11 | ssl: 12 | enabled: false 13 | 14 | spring-addons: 15 | issuers: 16 | - uri: ${keycloak-issuer} 17 | username-json-path: $.preferred_username 18 | claims: 19 | - jsonPath: $.realm_access.roles 20 | - jsonPath: $.resource_access.*.roles 21 | - uri: ${cognito-issuer} 22 | claims: 23 | - jsonPath: $.cognito:groups 24 | - uri: ${auth0-issuer} 25 | claims: 26 | - jsonPath: $.roles 27 | - jsonPath: $.groups 28 | - jsonPath: $.permissions 29 | 30 | --- 31 | scheme: https 32 | keycloak-port: 8443 33 | 34 | server: 35 | ssl: 36 | enabled: true 37 | 38 | spring: 39 | config: 40 | activate: 41 | on-profile: ssl 42 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-resource-server/src/test/java/com/c4soft/springaddons/tutorials/GivenUserIsCh4mp.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | import com.c4_soft.springaddons.security.oauth2.test.annotations.WithJwt; 8 | 9 | @Target({ElementType.METHOD, ElementType.TYPE}) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @WithJwt("ch4mp_auth0.json") 12 | public @interface GivenUserIsCh4mp { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-resource-server/src/test/java/com/c4soft/springaddons/tutorials/GivenUserIsCh4mpDeprecated.java: -------------------------------------------------------------------------------- 1 | package com.c4soft.springaddons.tutorials; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | import com.c4_soft.springaddons.security.oauth2.test.annotations.ClasspathClaims; 8 | import com.c4_soft.springaddons.security.oauth2.test.annotations.OpenIdClaims; 9 | import com.c4_soft.springaddons.security.oauth2.test.annotations.WithMockJwtAuth; 10 | 11 | @Target({ElementType.METHOD, ElementType.TYPE}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @WithMockJwtAuth(claims = @OpenIdClaims(jsonFile = @ClasspathClaims("ch4mp_auth0.json"))) 14 | public @interface GivenUserIsCh4mpDeprecated { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /samples/tutorials/servlet-resource-server/src/test/resources/ch4mp_auth0.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "ch4mp@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "ch4mp", 18 | "nickname": "ch4mp", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "permissions": [ 28 | "NICE", "AUTHOR" 29 | ], 30 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 31 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 32 | "aud": [ 33 | "demo.c4-soft.com", 34 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 35 | ], 36 | "iat": 1687633329, 37 | "exp": 1687719729, 38 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 39 | "scope": "openid email" 40 | } -------------------------------------------------------------------------------- /samples/webflux-introspecting-default/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webflux-introspecting-default/src/main/java/com/c4_soft/springaddons/samples/webflux_jwtauthenticationtoken/SecretRepo.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_jwtauthenticationtoken; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import reactor.core.publisher.Mono; 7 | 8 | @Repository 9 | public class SecretRepo { 10 | @PreAuthorize("authentication.name eq #a0") 11 | public Mono findSecretByUsername(String username) { 12 | return Mono.just("Don't ever tell it"); 13 | } 14 | } -------------------------------------------------------------------------------- /samples/webflux-introspecting-default/src/main/java/com/c4_soft/springaddons/samples/webflux_jwtauthenticationtoken/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_jwtauthenticationtoken; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; 6 | import org.springframework.security.config.web.server.ServerHttpSecurity; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.reactive.resourceserver.ResourceServerAuthorizeExchangeSpecPostProcessor; 9 | 10 | @EnableReactiveMethodSecurity() 11 | @Configuration 12 | public class SecurityConfig { 13 | 14 | @Bean 15 | ResourceServerAuthorizeExchangeSpecPostProcessor authorizeExchangeSpecPostProcessor() { 16 | // @formatter:off 17 | return (ServerHttpSecurity.AuthorizeExchangeSpec spec) -> spec 18 | .pathMatchers("/secured-route").hasRole("AUTHORIZED_PERSONNEL") 19 | .anyExchange().authenticated(); 20 | // @formatter:on 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /samples/webflux-introspecting-default/src/main/java/com/c4_soft/springaddons/samples/webflux_jwtauthenticationtoken/WebfluxIntrospectingDefault.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_jwtauthenticationtoken; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | 7 | @SpringBootApplication 8 | public class WebfluxIntrospectingDefault { 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(WebfluxIntrospectingDefault.class).web(WebApplicationType.REACTIVE).run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/webflux-introspecting-default/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "ch4mp@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "ch4mp", 5 | "realm_access": { 6 | "roles": [ 7 | "NICE", 8 | "AUTHOR", 9 | "ROLE_AUTHORIZED_PERSONNEL" 10 | ] 11 | }, 12 | "iss": "https://oidc.c4-soft.com/auth/realms/master", 13 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 14 | "aud": [ 15 | "demo.c4-soft.com", 16 | "http://localhost:8080" 17 | ], 18 | "iat": 1687633329, 19 | "exp": 1687719729, 20 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 21 | "scope": "openid email" 22 | } -------------------------------------------------------------------------------- /samples/webflux-introspecting-default/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /samples/webflux-introspecting-default/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "tonton-pirate@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "tonton-pirate", 5 | "realm_access": { 6 | "roles": [ 7 | "UNCLE", 8 | "PIRATE" 9 | ] 10 | }, 11 | "iss": "https://oidc.c4-soft.com/auth/realms/master", 12 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 13 | "aud": [ 14 | "demo.c4-soft.com", 15 | "http://localhost:8080" 16 | ], 17 | "iat": 1687633329, 18 | "exp": 1687719729, 19 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 20 | "scope": "openid email" 21 | } -------------------------------------------------------------------------------- /samples/webflux-introspecting-oauthentication/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webflux-introspecting-oauthentication/src/main/java/com/c4_soft/springaddons/samples/webflux_jwtauthenticationtoken/SecretRepo.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_jwtauthenticationtoken; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import reactor.core.publisher.Mono; 7 | 8 | @Repository 9 | public class SecretRepo { 10 | @PreAuthorize("authentication.name eq #a0") 11 | public Mono findSecretByUsername(String username) { 12 | return Mono.just("Don't ever tell it"); 13 | } 14 | } -------------------------------------------------------------------------------- /samples/webflux-introspecting-oauthentication/src/main/java/com/c4_soft/springaddons/samples/webflux_jwtauthenticationtoken/WebfluxIntrospectingOAthentication.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_jwtauthenticationtoken; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | 7 | @SpringBootApplication 8 | public class WebfluxIntrospectingOAthentication { 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(WebfluxIntrospectingOAthentication.class).web(WebApplicationType.REACTIVE).run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/webflux-introspecting-oauthentication/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "ch4mp@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "ch4mp", 5 | "realm_access": { 6 | "roles": [ 7 | "NICE", 8 | "AUTHOR", 9 | "ROLE_AUTHORIZED_PERSONNEL" 10 | ] 11 | }, 12 | "iss": "https://oidc.c4-soft.com/auth/realms/master", 13 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 14 | "aud": [ 15 | "demo.c4-soft.com", 16 | "http://localhost:8080" 17 | ], 18 | "iat": 1687633329, 19 | "exp": 1687719729, 20 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 21 | "scope": "openid email" 22 | } -------------------------------------------------------------------------------- /samples/webflux-introspecting-oauthentication/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /samples/webflux-introspecting-oauthentication/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "tonton-pirate@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "tonton-pirate", 5 | "realm_access": { 6 | "roles": [ 7 | "UNCLE", 8 | "PIRATE" 9 | ] 10 | }, 11 | "iss": "https://oidc.c4-soft.com/auth/realms/master", 12 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 13 | "aud": [ 14 | "demo.c4-soft.com", 15 | "http://localhost:8080" 16 | ], 17 | "iat": 1687633329, 18 | "exp": 1687719729, 19 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 20 | "scope": "openid email" 21 | } -------------------------------------------------------------------------------- /samples/webflux-jwt-default/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webflux-jwt-default/src/main/java/com/c4_soft/springaddons/samples/webflux_jwtauthenticationtoken/SecretRepo.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_jwtauthenticationtoken; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import reactor.core.publisher.Mono; 7 | 8 | @Repository 9 | public class SecretRepo { 10 | @PreAuthorize("authentication.name eq #a0") 11 | public Mono findSecretByUsername(String username) { 12 | return Mono.just("Don't ever tell it"); 13 | } 14 | } -------------------------------------------------------------------------------- /samples/webflux-jwt-default/src/main/java/com/c4_soft/springaddons/samples/webflux_jwtauthenticationtoken/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_jwtauthenticationtoken; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; 6 | import org.springframework.security.config.web.server.ServerHttpSecurity; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.reactive.resourceserver.ResourceServerAuthorizeExchangeSpecPostProcessor; 9 | 10 | @EnableReactiveMethodSecurity() 11 | @Configuration 12 | public class SecurityConfig { 13 | 14 | @Bean 15 | ResourceServerAuthorizeExchangeSpecPostProcessor authorizeExchangeSpecPostProcessor() { 16 | // @formatter:off 17 | return (ServerHttpSecurity.AuthorizeExchangeSpec spec) -> spec 18 | .pathMatchers("/secured-route").hasRole("AUTHORIZED_PERSONNEL") 19 | .anyExchange().authenticated(); 20 | // @formatter:on 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /samples/webflux-jwt-default/src/main/java/com/c4_soft/springaddons/samples/webflux_jwtauthenticationtoken/WebfluxJwtDefault.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_jwtauthenticationtoken; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | 7 | @SpringBootApplication 8 | public class WebfluxJwtDefault { 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(WebfluxJwtDefault.class).web(WebApplicationType.REACTIVE).run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/webflux-jwt-default/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "ch4mp@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "ch4mp", 18 | "nickname": "ch4mp", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR", "ROLE_AUTHORIZED_PERSONNEL" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "https://c4-soft.com/authorities": [ 28 | "NICE", 29 | "AUTHOR" 30 | ], 31 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 32 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 33 | "aud": [ 34 | "demo.c4-soft.com", 35 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 36 | ], 37 | "iat": 1687633329, 38 | "exp": 1687719729, 39 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 40 | "scope": "openid email" 41 | } -------------------------------------------------------------------------------- /samples/webflux-jwt-default/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /samples/webflux-jwt-default/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "tonton-pirate@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "Tonton Pirate", 18 | "nickname": "Tonton Pirate", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "https://c4-soft.com/authorities": [ 28 | "UNCLE", 29 | "SKIPPER" 30 | ], 31 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 32 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 33 | "aud": [ 34 | "demo.c4-soft.com", 35 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 36 | ], 37 | "iat": 1687633329, 38 | "exp": 1687719729, 39 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 40 | "scope": "openid email" 41 | } -------------------------------------------------------------------------------- /samples/webflux-jwt-oauthentication/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webflux-jwt-oauthentication/src/main/java/com/c4_soft/springaddons/samples/webflux_oidcauthentication/SecretRepo.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_oidcauthentication; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import reactor.core.publisher.Mono; 7 | 8 | @Repository 9 | public class SecretRepo { 10 | @PreAuthorize("authentication.name eq #a0") 11 | public Mono findSecretByUsername(String username) { 12 | return Mono.just("Don't ever tell it"); 13 | } 14 | } -------------------------------------------------------------------------------- /samples/webflux-jwt-oauthentication/src/main/java/com/c4_soft/springaddons/samples/webflux_oidcauthentication/WebfluxJwtOauthentication.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webflux_oidcauthentication; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | 7 | @SpringBootApplication 8 | public class WebfluxJwtOauthentication { 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(WebfluxJwtOauthentication.class).web(WebApplicationType.REACTIVE).run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/webflux-jwt-oauthentication/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "ch4mp@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "ch4mp", 18 | "nickname": "ch4mp", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR", "ROLE_AUTHORIZED_PERSONNEL" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "https://c4-soft.com/authorities": [ 28 | "NICE", 29 | "AUTHOR" 30 | ], 31 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 32 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 33 | "aud": [ 34 | "demo.c4-soft.com", 35 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 36 | ], 37 | "iat": 1687633329, 38 | "exp": 1687719729, 39 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 40 | "scope": "openid email" 41 | } -------------------------------------------------------------------------------- /samples/webflux-jwt-oauthentication/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /samples/webflux-jwt-oauthentication/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "tonton-pirate@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "Tonton Pirate", 18 | "nickname": "Tonton Pirate", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "https://c4-soft.com/authorities": [ 28 | "UNCLE", 29 | "SKIPPER" 30 | ], 31 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 32 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 33 | "aud": [ 34 | "demo.c4-soft.com", 35 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 36 | ], 37 | "iat": 1687633329, 38 | "exp": 1687719729, 39 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 40 | "scope": "openid email" 41 | } -------------------------------------------------------------------------------- /samples/webmvc-introspecting-default/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webmvc-introspecting-default/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken/SecretRepo.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public class SecretRepo { 8 | @PreAuthorize("authentication.name eq #a0") 9 | public String findSecretByUsername(String username) { 10 | return "Don't ever tell it"; 11 | } 12 | } -------------------------------------------------------------------------------- /samples/webmvc-introspecting-default/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; 8 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 9 | import com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver.ResourceServerExpressionInterceptUrlRegistryPostProcessor; 10 | 11 | @Configuration 12 | @EnableMethodSecurity 13 | public class SecurityConfig { 14 | @Bean 15 | ResourceServerExpressionInterceptUrlRegistryPostProcessor expressionInterceptUrlRegistryPostProcessor() { 16 | // @formatter:off 17 | return (AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry registry) -> registry 18 | .requestMatchers(new AntPathRequestMatcher("/secured-route")).hasRole("AUTHORIZED_PERSONNEL") 19 | .anyRequest().authenticated(); 20 | // @formatter:on 21 | } 22 | } -------------------------------------------------------------------------------- /samples/webmvc-introspecting-default/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken/WebmvcIntrospectingDefault.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | 7 | @SpringBootApplication 8 | public class WebmvcIntrospectingDefault { 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(WebmvcIntrospectingDefault.class).web(WebApplicationType.SERVLET).run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/webmvc-introspecting-default/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "ch4mp@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "ch4mp", 5 | "realm_access": { 6 | "roles": [ 7 | "NICE", 8 | "AUTHOR", 9 | "ROLE_AUTHORIZED_PERSONNEL" 10 | ] 11 | }, 12 | "iss": "https://oidc.c4-soft.com/auth/realms/master", 13 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 14 | "aud": [ 15 | "demo.c4-soft.com", 16 | "http://localhost:8080" 17 | ], 18 | "iat": 1687633329, 19 | "exp": 1687719729, 20 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 21 | "scope": "openid email" 22 | } -------------------------------------------------------------------------------- /samples/webmvc-introspecting-default/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "tonton-pirate@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "tonton-pirate", 5 | "realm_access": { 6 | "roles": [ 7 | "UNCLE", 8 | "PIRATE" 9 | ] 10 | }, 11 | "iss": "https://oidc.c4-soft.com/auth/realms/master", 12 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 13 | "aud": [ 14 | "demo.c4-soft.com", 15 | "http://localhost:8080" 16 | ], 17 | "iat": 1687633329, 18 | "exp": 1687719729, 19 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 20 | "scope": "openid email" 21 | } -------------------------------------------------------------------------------- /samples/webmvc-introspecting-oauthentication/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webmvc-introspecting-oauthentication/src/main/java/com/c4_soft/springaddons/samples/webmvc_oidcauthentication/SecretRepo.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_oidcauthentication; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public class SecretRepo { 8 | @PreAuthorize("authentication.name eq #a0") 9 | public String findSecretByUsername(String username) { 10 | return "Don't ever tell it"; 11 | } 12 | } -------------------------------------------------------------------------------- /samples/webmvc-introspecting-oauthentication/src/main/java/com/c4_soft/springaddons/samples/webmvc_oidcauthentication/WebmvcIntrospectingOauthentication.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_oidcauthentication; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | 7 | @SpringBootApplication 8 | public class WebmvcIntrospectingOauthentication { 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(WebmvcIntrospectingOauthentication.class).web(WebApplicationType.SERVLET).run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/webmvc-introspecting-oauthentication/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "ch4mp@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "ch4mp", 5 | "realm_access": { 6 | "roles": [ 7 | "NICE", 8 | "AUTHOR", 9 | "ROLE_AUTHORIZED_PERSONNEL" 10 | ] 11 | }, 12 | "iss": "https://oidc.c4-soft.com/auth/realms/master", 13 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 14 | "aud": [ 15 | "demo.c4-soft.com", 16 | "http://localhost:8080" 17 | ], 18 | "iat": 1687633329, 19 | "exp": 1687719729, 20 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 21 | "scope": "openid email" 22 | } -------------------------------------------------------------------------------- /samples/webmvc-introspecting-oauthentication/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "tonton-pirate@c4-soft.com", 3 | "email_verified": true, 4 | "preferred_username": "tonton-pirate", 5 | "realm_access": { 6 | "roles": [ 7 | "UNCLE", 8 | "PIRATE" 9 | ] 10 | }, 11 | "iss": "https://oidc.c4-soft.com/auth/realms/master", 12 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 13 | "aud": [ 14 | "demo.c4-soft.com", 15 | "http://localhost:8080" 16 | ], 17 | "iat": 1687633329, 18 | "exp": 1687719729, 19 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 20 | "scope": "openid email" 21 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken_jpa_authorities/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken_jpa_authorities; 2 | 3 | import java.util.Map; 4 | import org.springframework.security.access.prepost.PreAuthorize; 5 | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | @RestController 10 | public class GreetingController { 11 | private final MessageService messageService; 12 | 13 | public GreetingController(MessageService messageService) { 14 | this.messageService = messageService; 15 | } 16 | 17 | @GetMapping("/greet") 18 | public String greet(JwtAuthenticationToken auth) { 19 | return messageService.greet(auth); 20 | } 21 | 22 | @GetMapping("/secured-route") 23 | public String securedRoute() { 24 | return messageService.getSecret(); 25 | } 26 | 27 | @GetMapping("/secured-method") 28 | @PreAuthorize("hasRole('AUTHORIZED_PERSONNEL')") 29 | public String securedMethod() { 30 | return messageService.getSecret(); 31 | } 32 | 33 | @GetMapping("/claims") 34 | public Map getClaims(JwtAuthenticationToken auth) { 35 | return auth.getTokenAttributes(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken_jpa_authorities/MessageService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the 5 | * License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken_jpa_authorities; 14 | 15 | import org.springframework.security.access.prepost.PreAuthorize; 16 | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; 17 | import org.springframework.stereotype.Service; 18 | 19 | @Service 20 | public class MessageService { 21 | 22 | @PreAuthorize("hasRole('AUTHORIZED_PERSONNEL')") 23 | public String getSecret() { 24 | return "Secret message"; 25 | } 26 | 27 | @PreAuthorize("isAuthenticated()") 28 | public String greet(JwtAuthenticationToken who) { 29 | return String.format("Hello %s! You are granted with %s.", who.getName(), who.getAuthorities()); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken_jpa_authorities/PersistenceConfig.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken_jpa_authorities; 2 | 3 | import org.springframework.boot.autoconfigure.domain.EntityScan; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 6 | import org.springframework.transaction.annotation.EnableTransactionManagement; 7 | 8 | @Configuration(proxyBeanMethods = false) 9 | @EntityScan 10 | @EnableJpaRepositories 11 | @EnableTransactionManagement 12 | public class PersistenceConfig { 13 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken_jpa_authorities/UserAuthorityRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the 5 | * License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken_jpa_authorities; 13 | 14 | import java.util.Collection; 15 | import org.springframework.cache.annotation.Cacheable; 16 | import org.springframework.data.jpa.repository.JpaRepository; 17 | 18 | /** 19 | * @author Jérôme Wacongne <ch4mp@c4-soft.com> 20 | */ 21 | public interface UserAuthorityRepository extends JpaRepository { 22 | 23 | @Cacheable("users-authorities") 24 | Collection findByIdUserSubject(String subject); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken_jpa_authorities/WebmvcJwtDefaultJpaAuthorities.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken_jpa_authorities; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | 8 | @SpringBootApplication 9 | @EnableCaching 10 | public class WebmvcJwtDefaultJpaAuthorities { 11 | public static void main(String[] args) { 12 | new SpringApplicationBuilder(WebmvcJwtDefaultJpaAuthorities.class).web(WebApplicationType.SERVLET).run(args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/src/test/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken_jpa_authorities/TestUserAuthorityRepositoryConf.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken_jpa_authorities; 2 | 3 | import static org.mockito.Mockito.mock; 4 | import static org.mockito.Mockito.when; 5 | import java.util.List; 6 | import org.springframework.boot.test.context.TestConfiguration; 7 | import org.springframework.context.annotation.Bean; 8 | 9 | @TestConfiguration 10 | class TestUserAuthorityRepositoryConf { 11 | @Bean 12 | UserAuthorityRepository userAuthorityRepository() { 13 | final var userAuthorityRepository = mock(UserAuthorityRepository.class); 14 | when(userAuthorityRepository.findByIdUserSubject("oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94")).thenReturn( 15 | List.of(new UserAuthority("oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", "ROLE_AUTHORIZED_PERSONNEL", "AUTHORIZED_PERSONNEL"))); 16 | when(userAuthorityRepository.findByIdUserSubject("oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90")).thenReturn( 17 | List.of( 18 | new UserAuthority("oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", "UNCLE", "UNCLE"), 19 | new UserAuthority("oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", "SKIPPER", "PIRATE"))); 20 | return userAuthorityRepository; 21 | } 22 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "ch4mp@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "ch4mp", 18 | "nickname": "ch4mp", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "updated_at": "2023-06-23T04:53:53.057Z", 21 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 22 | "user_metadata": {} 23 | }, 24 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 25 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 26 | "aud": [ 27 | "demo.c4-soft.com", 28 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 29 | ], 30 | "iat": 1687633329, 31 | "exp": 1687719729, 32 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 33 | "scope": "openid email" 34 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default-jpa-authorities/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "tonton-pirate@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "Tonton Pirate", 18 | "nickname": "Tonton Pirate", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "updated_at": "2023-06-23T04:53:53.057Z", 21 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 22 | "user_metadata": {} 23 | }, 24 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 25 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e90", 26 | "aud": [ 27 | "demo.c4-soft.com", 28 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 29 | ], 30 | "iat": 1687633329, 31 | "exp": 1687719729, 32 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 33 | "scope": "openid email" 34 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webmvc-jwt-default/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken/BasicAuthSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.context.annotation.Profile; 5 | 6 | /** 7 | *

8 | * This is just for demonstration purpose for https://github.com/keycloak/keycloak/discussions/10187 9 | *

10 | *

11 | * Here, we add a security filter chain for requests with Basic authentication. The authentication 12 | * manager in this filter-chain first retrieves tokens using password-grant flow, and then delegates 13 | * to an OAuth2 authentication manger (after replacing the Basic Authorization header to a Bearer 14 | * one containing the just retrieved access token) 15 | *

16 | * 17 | * @author Jerome Wacongne ch4mp@c4-soft.com 18 | */ 19 | @Profile("basic-authentication") 20 | @Configuration 21 | public class BasicAuthSecurityConfig { 22 | } 23 | -------------------------------------------------------------------------------- /samples/webmvc-jwt-default/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken/OAuth2SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; 8 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 9 | import com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver.ResourceServerExpressionInterceptUrlRegistryPostProcessor; 10 | 11 | @Configuration 12 | @EnableMethodSecurity 13 | public class OAuth2SecurityConfig { 14 | @Bean 15 | ResourceServerExpressionInterceptUrlRegistryPostProcessor expressionInterceptUrlRegistryPostProcessor() { 16 | // @formatter:off 17 | return (AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry registry) -> registry 18 | .requestMatchers(new AntPathRequestMatcher("/secured-route")).hasRole("AUTHORIZED_PERSONNEL") 19 | .anyRequest().authenticated(); 20 | // @formatter:on 21 | } 22 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken/SecretRepo.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public class SecretRepo { 8 | @PreAuthorize("authentication.name eq #a0") 9 | public String findSecretByUsername(String username) { 10 | return "Don't ever tell it"; 11 | } 12 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default/src/main/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken/WebmvcJwtDefault.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_jwtauthenticationtoken; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | 7 | @SpringBootApplication 8 | public class WebmvcJwtDefault { 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(WebmvcJwtDefault.class).web(WebApplicationType.SERVLET).run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/webmvc-jwt-default/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "ch4mp@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "ch4mp", 18 | "nickname": "ch4mp", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR", "ROLE_AUTHORIZED_PERSONNEL" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "https://c4-soft.com/authorities": [ 28 | "NICE", 29 | "AUTHOR" 30 | ], 31 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 32 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 33 | "aud": [ 34 | "demo.c4-soft.com", 35 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 36 | ], 37 | "iat": 1687633329, 38 | "exp": 1687719729, 39 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 40 | "scope": "openid email" 41 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-default/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "tonton-pirate@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "Tonton Pirate", 18 | "nickname": "Tonton Pirate", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "https://c4-soft.com/authorities": [ 28 | "UNCLE", 29 | "SKIPPER" 30 | ], 31 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 32 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 33 | "aud": [ 34 | "demo.c4-soft.com", 35 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 36 | ], 37 | "iat": 1687633329, 38 | "exp": 1687719729, 39 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 40 | "scope": "openid email" 41 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-oauthentication/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /samples/webmvc-jwt-oauthentication/src/main/java/com/c4_soft/springaddons/samples/webmvc_oidcauthentication/SecretRepo.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_oidcauthentication; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public class SecretRepo { 8 | @PreAuthorize("authentication.name eq #a0") 9 | public String findSecretByUsername(String username) { 10 | return "Don't ever tell it"; 11 | } 12 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-oauthentication/src/main/java/com/c4_soft/springaddons/samples/webmvc_oidcauthentication/WebmvcJwtOauthentication.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.samples.webmvc_oidcauthentication; 2 | 3 | import org.springframework.boot.WebApplicationType; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | 7 | @SpringBootApplication 8 | public class WebmvcJwtOauthentication { 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(WebmvcJwtOauthentication.class).web(WebApplicationType.SERVLET).run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/webmvc-jwt-oauthentication/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "ch4mp@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "ch4mp", 18 | "nickname": "ch4mp", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR", "ROLE_AUTHORIZED_PERSONNEL" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "https://c4-soft.com/authorities": [ 28 | "NICE", 29 | "AUTHOR" 30 | ], 31 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 32 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 33 | "aud": [ 34 | "demo.c4-soft.com", 35 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 36 | ], 37 | "iat": 1687633329, 38 | "exp": 1687719729, 39 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 40 | "scope": "openid email" 41 | } -------------------------------------------------------------------------------- /samples/webmvc-jwt-oauthentication/src/test/resources/tonton-pirate.json: -------------------------------------------------------------------------------- 1 | { 2 | "https://c4-soft.com/user": { 3 | "app_metadata": {}, 4 | "created_at": "2023-06-01T01:21:37.810Z", 5 | "email": "tonton-pirate@c4-soft.com", 6 | "email_verified": true, 7 | "identities": [ 8 | { 9 | "connection": "c4-soft", 10 | "isSocial": true, 11 | "provider": "oauth2", 12 | "userId": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 13 | "user_id": "c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94" 14 | } 15 | ], 16 | "multifactor": [], 17 | "name": "Tonton Pirate", 18 | "nickname": "Tonton Pirate", 19 | "picture": "https://s.gravatar.com/avatar/f4d00b0a82e9307b1d68b29867fee4e5?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fch.png", 20 | "roles": [ 21 | "USER_ROLES_EDITOR" 22 | ], 23 | "updated_at": "2023-06-23T04:53:53.057Z", 24 | "user_id": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 25 | "user_metadata": {} 26 | }, 27 | "https://c4-soft.com/authorities": [ 28 | "UNCLE", 29 | "SKIPPER" 30 | ], 31 | "iss": "https://dev-ch4mpy.eu.auth0.com/", 32 | "sub": "oauth2|c4-soft|4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 33 | "aud": [ 34 | "demo.c4-soft.com", 35 | "https://dev-ch4mpy.eu.auth0.com/userinfo" 36 | ], 37 | "iat": 1687633329, 38 | "exp": 1687719729, 39 | "azp": "pDy3JpZoenbLk9MqXYCfJK1mpxeUwkKL", 40 | "scope": "openid email" 41 | } -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/AuthenticationBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the 5 | * License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | package com.c4_soft.springaddons.security.oauth2.test; 13 | 14 | import org.springframework.security.core.Authentication; 15 | 16 | /** 17 | * Common interface for test authentication builders 18 | * 19 | * @author Jérôme Wacongne <ch4mp@c4-soft.com> 20 | * @param capture for extending class type 21 | */ 22 | public interface AuthenticationBuilder { 23 | 24 | T build(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/AuthoritiesConverterNotAMockException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the 5 | * License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | package com.c4_soft.springaddons.security.oauth2.test; 14 | 15 | public class AuthoritiesConverterNotAMockException extends RuntimeException { 16 | private static final long serialVersionUID = 535445516846968187L; 17 | 18 | public AuthoritiesConverterNotAMockException() { 19 | super( 20 | "Configured `authoritiesConverter` is not a Mockito Mock. " 21 | + "Please either configure a mock if you want to set \"authorities\" directly" 22 | + "or set relevent claims instead if you configured a \"real\" authorities converter."); 23 | } 24 | } -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/DoubleClaim.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.c4_soft.springaddons.security.oauth2.test.annotations; 15 | 16 | import java.lang.annotation.ElementType; 17 | import java.lang.annotation.Retention; 18 | import java.lang.annotation.RetentionPolicy; 19 | import java.lang.annotation.Target; 20 | 21 | @Target({ ElementType.METHOD, ElementType.TYPE }) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | public @interface DoubleClaim { 24 | String name(); 25 | 26 | double value(); 27 | } 28 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/IntClaim.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.c4_soft.springaddons.security.oauth2.test.annotations; 15 | 16 | import java.lang.annotation.ElementType; 17 | import java.lang.annotation.Retention; 18 | import java.lang.annotation.RetentionPolicy; 19 | import java.lang.annotation.Target; 20 | 21 | @Target({ ElementType.METHOD, ElementType.TYPE }) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | public @interface IntClaim { 24 | String name(); 25 | 26 | int value(); 27 | } 28 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/InvalidClaimException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oauth2.test.annotations; 2 | 3 | public class InvalidClaimException extends RuntimeException { 4 | private static final long serialVersionUID = -2603521800687945747L; 5 | 6 | public InvalidClaimException(Throwable t) { 7 | super(t); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/InvalidJsonException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oauth2.test.annotations; 2 | 3 | public class InvalidJsonException extends RuntimeException { 4 | private static final long serialVersionUID = -2556818332507765648L; 5 | 6 | public InvalidJsonException(Throwable t) { 7 | super(t); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/JsonFileClaim.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the 5 | * License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | package com.c4_soft.springaddons.security.oauth2.test.annotations; 14 | 15 | import java.lang.annotation.ElementType; 16 | import java.lang.annotation.Retention; 17 | import java.lang.annotation.RetentionPolicy; 18 | import java.lang.annotation.Target; 19 | 20 | @Target({ ElementType.METHOD, ElementType.TYPE }) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | public @interface JsonFileClaim { 23 | String name(); 24 | 25 | ClasspathClaims value(); 26 | } 27 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/LongClaim.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.c4_soft.springaddons.security.oauth2.test.annotations; 15 | 16 | import java.lang.annotation.ElementType; 17 | import java.lang.annotation.Retention; 18 | import java.lang.annotation.RetentionPolicy; 19 | import java.lang.annotation.Target; 20 | 21 | @Target({ ElementType.METHOD, ElementType.TYPE }) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | public @interface LongClaim { 24 | String name(); 25 | 26 | long value(); 27 | } 28 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/StringArrayClaim.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.c4_soft.springaddons.security.oauth2.test.annotations; 15 | 16 | import java.lang.annotation.ElementType; 17 | import java.lang.annotation.Retention; 18 | import java.lang.annotation.RetentionPolicy; 19 | import java.lang.annotation.Target; 20 | 21 | @Target({ ElementType.METHOD, ElementType.TYPE }) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | public @interface StringArrayClaim { 24 | String name(); 25 | 26 | String[] value(); 27 | } 28 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/annotations/StringClaim.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.c4_soft.springaddons.security.oauth2.test.annotations; 15 | 16 | import java.lang.annotation.ElementType; 17 | import java.lang.annotation.Retention; 18 | import java.lang.annotation.RetentionPolicy; 19 | import java.lang.annotation.Target; 20 | 21 | @Target({ ElementType.METHOD, ElementType.TYPE }) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | public @interface StringClaim { 24 | String name(); 25 | 26 | String value(); 27 | } 28 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/test/support/web/ByteArrayHttpOutputMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the 5 | * License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | package com.c4_soft.springaddons.test.support.web; 13 | 14 | import java.io.ByteArrayOutputStream; 15 | import java.io.OutputStream; 16 | 17 | import org.springframework.http.HttpHeaders; 18 | import org.springframework.http.HttpOutputMessage; 19 | 20 | public final class ByteArrayHttpOutputMessage implements HttpOutputMessage { 21 | public final ByteArrayOutputStream out = new ByteArrayOutputStream(); 22 | public final HttpHeaders headers = new HttpHeaders(); 23 | 24 | @Override 25 | public OutputStream getBody() { 26 | return out; 27 | } 28 | 29 | @Override 30 | public HttpHeaders getHeaders() { 31 | return headers; 32 | } 33 | } -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/java/com/c4_soft/springaddons/test/support/web/ConversionFailedException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.test.support.web; 2 | 3 | public class ConversionFailedException extends RuntimeException { 4 | private static final long serialVersionUID = 8295304756267987916L; 5 | 6 | public ConversionFailedException(String message) { 7 | super(message); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.c4_soft.springaddons.security.oauth2.test.AuthenticationFactoriesTestConf -------------------------------------------------------------------------------- /spring-addons-oauth2-test/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "preferred_username": "Ch4mp", 3 | "email": "ch4mp@c4-soft.com", 4 | "aud": "https://localhost:7082", 5 | "scope": "openid AUTHORIZED_PERSONNEL" 6 | } -------------------------------------------------------------------------------- /spring-addons-oauth2/src/main/java/com/c4_soft/springaddons/security/oidc/OpenidClaimSet.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc; 2 | 3 | import java.security.Principal; 4 | import java.util.Map; 5 | import org.springframework.security.oauth2.core.oidc.IdTokenClaimAccessor; 6 | import org.springframework.security.oauth2.core.oidc.StandardClaimNames; 7 | import org.springframework.security.oauth2.jwt.JwtClaimNames; 8 | import com.jayway.jsonpath.PathNotFoundException; 9 | import lombok.Getter; 10 | 11 | public class OpenidClaimSet extends UnmodifiableClaimSet 12 | implements IdTokenClaimAccessor, Principal { 13 | private static final long serialVersionUID = -5149299350697429528L; 14 | 15 | /** 16 | * JSON path for the claim to use as "name" source 17 | */ 18 | @Getter 19 | private final String usernameClaim; 20 | 21 | public OpenidClaimSet(Map claims, String usernameClaim) { 22 | super(claims); 23 | this.usernameClaim = usernameClaim; 24 | } 25 | 26 | public OpenidClaimSet(Map claims) { 27 | this(claims, StandardClaimNames.SUB); 28 | } 29 | 30 | @Override 31 | public Map getClaims() { 32 | return this; 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | try { 38 | return getByJsonPath(usernameClaim); 39 | } catch (PathNotFoundException e) { 40 | return getByJsonPath(JwtClaimNames.SUB); 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /spring-addons-oauth2/src/main/java/com/c4_soft/springaddons/security/oidc/OpenidToken.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc; 2 | 3 | import java.time.Instant; 4 | import java.util.Map; 5 | import org.springframework.security.oauth2.core.OAuth2Token; 6 | 7 | public class OpenidToken extends OpenidClaimSet implements OAuth2Token { 8 | private static final long serialVersionUID = 913910545139553602L; 9 | 10 | private final String tokenValue; 11 | 12 | public OpenidToken(Map claims, String usernameClaim, String tokenValue) { 13 | super(claims, usernameClaim); 14 | this.tokenValue = tokenValue; 15 | } 16 | 17 | public OpenidToken(OpenidClaimSet openidClaimSet, String tokenValue) { 18 | super(openidClaimSet, openidClaimSet.getUsernameClaim()); 19 | this.tokenValue = tokenValue; 20 | } 21 | 22 | @Override 23 | public String getTokenValue() { 24 | return tokenValue; 25 | } 26 | 27 | @Override 28 | public Instant getExpiresAt() { 29 | return super.getExpiresAt(); 30 | } 31 | 32 | @Override 33 | public Instant getIssuedAt() { 34 | return super.getIssuedAt(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /spring-addons-oauth2/src/main/java/com/c4_soft/springaddons/security/oidc/UnparsableClaimException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc; 2 | 3 | public class UnparsableClaimException extends RuntimeException { 4 | private static final long serialVersionUID = 5585678138757632513L; 5 | 6 | public UnparsableClaimException(String message) { 7 | super(message); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/webflux/AddonsWebfluxComponentTest.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oauth2.test.webflux; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 8 | import com.c4_soft.springaddons.security.oauth2.test.webmvc.AutoConfigureAddonsWebmvcResourceServerSecurity; 9 | 10 | /** 11 | * To be used when testing secured components which are not controllers 12 | * 13 | * @author Jerome Wacongne ch4mp@c4-soft.com 14 | * @see AutoConfigureAddonsWebfluxClientSecurity 15 | * @see AutoConfigureAddonsWebmvcResourceServerSecurity 16 | */ 17 | @Target(ElementType.TYPE) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @EnableAutoConfiguration() 20 | @AutoConfigureAddonsWebfluxMinimalSecurity 21 | public @interface AddonsWebfluxComponentTest { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/webflux/OidcIdAuthenticationTokenWebTestClientConfigurer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Jérôme Wacongne 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.c4_soft.springaddons.security.oauth2.test.webflux; 16 | 17 | import com.c4_soft.springaddons.security.oauth2.test.OAuthenticationTestingBuilder; 18 | import com.c4_soft.springaddons.security.oidc.OAuthentication; 19 | import com.c4_soft.springaddons.security.oidc.OpenidToken; 20 | 21 | public class OidcIdAuthenticationTokenWebTestClientConfigurer extends OAuthenticationTestingBuilder 22 | implements AuthenticationConfigurer> { 23 | 24 | public static OidcIdAuthenticationTokenWebTestClientConfigurer oidcId() { 25 | return new OidcIdAuthenticationTokenWebTestClientConfigurer(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/webflux/WebTestClientProperties.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oauth2.test.webflux; 2 | 3 | import org.springframework.boot.autoconfigure.AutoConfiguration; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.core.Ordered; 6 | import org.springframework.core.annotation.Order; 7 | 8 | @Order(Ordered.HIGHEST_PRECEDENCE) 9 | @AutoConfiguration 10 | @ConfigurationProperties(prefix = "com.c4-soft.springaddons.test.web") 11 | public class WebTestClientProperties { 12 | private String defaultMediaType = "application/json"; 13 | private String defaultCharset = "utf-8"; 14 | 15 | public String getDefaultMediaType() { 16 | return defaultMediaType; 17 | } 18 | 19 | public void setDefaultMediaType(String defaultMediaType) { 20 | this.defaultMediaType = defaultMediaType; 21 | } 22 | 23 | public String getDefaultCharset() { 24 | return defaultCharset; 25 | } 26 | 27 | public void setDefaultCharset(String defaultCharset) { 28 | this.defaultCharset = defaultCharset; 29 | } 30 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/webmvc/AddonsWebmvcComponentTest.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oauth2.test.webmvc; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 8 | import com.c4_soft.springaddons.security.oauth2.test.webflux.AutoConfigureAddonsWebfluxClientSecurity; 9 | 10 | /** 11 | * To be used when testing secured components which are not controllers 12 | * 13 | * @author Jerome Wacongne ch4mp@c4-soft.com 14 | * @see AutoConfigureAddonsWebfluxClientSecurity 15 | * @see AutoConfigureAddonsWebmvcResourceServerSecurity 16 | */ 17 | @Target(ElementType.TYPE) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @EnableAutoConfiguration() 20 | @AutoConfigureAddonsWebmvcMinimalSecurity 21 | public @interface AddonsWebmvcComponentTest { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/webmvc/MockMvcPerformException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oauth2.test.webmvc; 2 | 3 | public class MockMvcPerformException extends RuntimeException { 4 | private static final long serialVersionUID = 4812927101282656196L; 5 | 6 | public MockMvcPerformException(Throwable cause) { 7 | super(cause); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc-test/src/main/java/com/c4_soft/springaddons/security/oauth2/test/webmvc/MockMvcProperties.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oauth2.test.webmvc; 2 | 3 | import org.springframework.boot.autoconfigure.AutoConfiguration; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import lombok.Data; 6 | 7 | @Data 8 | @AutoConfiguration 9 | @ConfigurationProperties(prefix = "com.c4-soft.springaddons.test.web") 10 | public class MockMvcProperties { 11 | private String defaultMediaType = "application/json"; 12 | private String defaultCharset = "utf-8"; 13 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/AdditionalParamsAuthorizationRequestCustomizer.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter; 2 | 3 | import java.util.function.Consumer; 4 | import java.util.stream.Collectors; 5 | 6 | import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; 7 | import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest.Builder; 8 | import org.springframework.util.MultiValueMap; 9 | 10 | import lombok.RequiredArgsConstructor; 11 | 12 | @RequiredArgsConstructor 13 | public class AdditionalParamsAuthorizationRequestCustomizer implements Consumer { 14 | private final MultiValueMap additionalParams; 15 | 16 | @Override 17 | public void accept(Builder t) { 18 | t.additionalParameters(params -> { 19 | additionalParams.forEach((k, v) -> { 20 | params.put(k, v.stream().collect(Collectors.joining(","))); 21 | }); 22 | }); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/ByIssuerOpenidProviderPropertiesResolver.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter; 2 | 3 | import java.net.URI; 4 | import java.util.Map; 5 | import java.util.Objects; 6 | import java.util.Optional; 7 | 8 | import org.springframework.security.oauth2.jwt.JwtClaimNames; 9 | 10 | import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties; 11 | import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties.OpenidProviderProperties; 12 | 13 | import lombok.RequiredArgsConstructor; 14 | 15 | @RequiredArgsConstructor 16 | public class ByIssuerOpenidProviderPropertiesResolver implements OpenidProviderPropertiesResolver { 17 | private final SpringAddonsOidcProperties properties; 18 | 19 | @Override 20 | public Optional resolve(Map claimSet) { 21 | final var iss = Optional.ofNullable(claimSet.get(JwtClaimNames.ISS)).map(Object::toString).orElse(null); 22 | return properties 23 | .getOps() 24 | .stream() 25 | .filter(issuerProps -> Objects.equals(Optional.ofNullable(issuerProps.getIss()).map(URI::toString).orElse(null), iss)) 26 | .findAny(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/ClaimSetAuthoritiesConverter.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter; 2 | 3 | import java.util.Collection; 4 | import java.util.Map; 5 | 6 | import org.springframework.core.convert.converter.Converter; 7 | import org.springframework.security.core.GrantedAuthority; 8 | 9 | public interface ClaimSetAuthoritiesConverter extends Converter, Collection> { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/LogoutRequestUriBuilder.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter; 2 | 3 | import java.net.URI; 4 | import java.util.Optional; 5 | 6 | import org.springframework.security.oauth2.client.registration.ClientRegistration; 7 | 8 | /** 9 | * @author Jerome Wacongne ch4mp@c4-soft.com 10 | */ 11 | public interface LogoutRequestUriBuilder { 12 | 13 | Optional getLogoutRequestUri(ClientRegistration clientRegistration, String idToken); 14 | 15 | Optional getLogoutRequestUri(ClientRegistration clientRegistration, String idToken, Optional postLogoutUri); 16 | } 17 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/OpenidProviderPropertiesResolver.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter; 2 | 3 | import java.util.Map; 4 | import java.util.Optional; 5 | 6 | import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties.OpenidProviderProperties; 7 | 8 | /** 9 | * Resolves OpenID Provider configuration properties from OAuth2 / OpenID claims (decoded from a JWT, introspected from an opaque token or 10 | * retrieved from userinfo endpoint) 11 | */ 12 | public interface OpenidProviderPropertiesResolver { 13 | Optional resolve(Map claimSet); 14 | } 15 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/CorsProperties.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Data; 6 | 7 | @Data 8 | public class CorsProperties { 9 | /** 10 | * Path matcher to which this configuration entry applies 11 | */ 12 | private String path = "/**"; 13 | 14 | /** 15 | * Default is null 16 | */ 17 | private Boolean allowCredentials = null; 18 | 19 | /** 20 | * Default is "*" which allows all origins 21 | */ 22 | private List allowedOriginPatterns = List.of("*"); 23 | 24 | /** 25 | * Default is "*" which allows all methods 26 | */ 27 | private List allowedMethods = List.of("*"); 28 | 29 | /** 30 | * Default is "*" which allows all headers 31 | */ 32 | private List allowedHeaders = List.of("*"); 33 | 34 | /** 35 | * Default is "*" which exposes all headers 36 | */ 37 | private List exposedHeaders = List.of("*"); 38 | 39 | private Long maxAge = null; 40 | 41 | /** 42 | * If left to false, OPTIONS requests are added to permit-all for the {@link CorsProperties#path path matchers} of this {@link CorsProperties} 43 | */ 44 | private boolean disableAnonymousOptions = false; 45 | } 46 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/InvalidRedirectionUriException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties; 2 | 3 | import java.net.URI; 4 | 5 | public class InvalidRedirectionUriException extends RuntimeException { 6 | private static final long serialVersionUID = 5011144097823445001L; 7 | 8 | public InvalidRedirectionUriException(URI redirectionUri) { 9 | super("%s doesn't match accepted post login/logout redirection URI patterns" 10 | .formatted(redirectionUri)); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/MisconfiguredPostLoginUriException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties; 2 | 3 | import java.net.URI; 4 | import java.util.Collection; 5 | import java.util.regex.Pattern; 6 | import java.util.stream.Collectors; 7 | 8 | public class MisconfiguredPostLoginUriException extends RuntimeException { 9 | private static final long serialVersionUID = -2294844735831156498L; 10 | 11 | public MisconfiguredPostLoginUriException(URI redirectionUri, 12 | Collection allowedPatterns) { 13 | super( 14 | "%s does not patch allowed post-login patterns %s".formatted(redirectionUri, allowedPatterns 15 | .stream().map(Pattern::toString).collect(Collectors.joining("/; /", "[/", "/]")))); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/MisconfiguredPostLogoutUriException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties; 2 | 3 | import java.net.URI; 4 | import java.util.Collection; 5 | import java.util.regex.Pattern; 6 | import java.util.stream.Collectors; 7 | 8 | public class MisconfiguredPostLogoutUriException extends RuntimeException { 9 | private static final long serialVersionUID = 244159916740008306L; 10 | 11 | public MisconfiguredPostLogoutUriException(URI redirectionUri, 12 | Collection allowedPatterns) { 13 | super("%s does not patch allowed post-logout patterns %s".formatted(redirectionUri, 14 | allowedPatterns.stream().map(Pattern::toString).collect(Collectors.joining(" ")))); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/NotAConfiguredOpenidProviderException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.web.bind.annotation.ResponseStatus; 7 | 8 | @ResponseStatus(HttpStatus.UNAUTHORIZED) 9 | public class NotAConfiguredOpenidProviderException extends RuntimeException { 10 | private static final long serialVersionUID = 5189849969622154264L; 11 | 12 | public NotAConfiguredOpenidProviderException(Map claims) { 13 | super( 14 | "Could not resolve OpenID Provider configuration properties from a JWT with %s as issuer and %s as audience" 15 | .formatted(claims.get("iss"), claims.get("aud"))); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/HasClientCorsPropertiesCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition; 2 | 3 | @Deprecated(forRemoval = true) 4 | /** 5 | * @deprecated default CORS configuration is now made with a filter which is unique in the app (applies to all filter-chains). Use 6 | * {@link HasCorsPropertiesCondition} 7 | */ 8 | public class HasClientCorsPropertiesCondition extends HasPropertyPrefixCondition { 9 | 10 | public HasClientCorsPropertiesCondition() { 11 | super("com.c4-soft.springaddons.oidc.client.cors"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/HasCorsPropertiesCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition; 2 | 3 | public class HasCorsPropertiesCondition extends HasPropertyPrefixCondition { 4 | 5 | public HasCorsPropertiesCondition() { 6 | super("com.c4-soft.springaddons.oidc.cors"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/HasOAuth2RegistrationPropertiesCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition; 2 | 3 | public class HasOAuth2RegistrationPropertiesCondition extends HasPropertyPrefixCondition { 4 | 5 | public HasOAuth2RegistrationPropertiesCondition() { 6 | super("spring.security.oauth2.client.registration"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/HasResourceServerCorsPropertiesCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition; 2 | 3 | @Deprecated(forRemoval = true) 4 | /** 5 | * @deprecated default CORS configuration is now made with a filter which is unique in the app (applies to all filter-chains). Use 6 | * {@link HasCorsPropertiesCondition} 7 | */ 8 | public class HasResourceServerCorsPropertiesCondition extends HasPropertyPrefixCondition { 9 | 10 | public HasResourceServerCorsPropertiesCondition() { 11 | super("com.c4-soft.springaddons.oidc.resourceserver.cors"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/AuthenticationConverterMissingCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.context.annotation.Condition; 4 | import org.springframework.context.annotation.ConditionContext; 5 | import org.springframework.core.ResolvableType; 6 | import org.springframework.core.convert.converter.Converter; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | import org.springframework.lang.NonNull; 9 | import org.springframework.security.authentication.AbstractAuthenticationToken; 10 | import com.nimbusds.jwt.JWT; 11 | 12 | public class AuthenticationConverterMissingCondition implements Condition { 13 | 14 | @Override 15 | public boolean matches(@NonNull ConditionContext context, 16 | @NonNull AnnotatedTypeMetadata metadata) { 17 | return context.getBeanFactory().getBeanNamesForType(ResolvableType.forClassWithGenerics( 18 | Converter.class, JWT.class, AbstractAuthenticationToken.class)).length < 1; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/CookieCsrfCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 5 | 6 | public class CookieCsrfCondition extends AnyNestedCondition { 7 | 8 | public CookieCsrfCondition() { 9 | super(ConfigurationPhase.REGISTER_BEAN); 10 | } 11 | 12 | @ConditionalOnProperty(name = "com.c4-soft.springaddons.oidc.client.csrf", havingValue = "cookie-accessible-from-js") 13 | static class ClientCookieAccessibleFromJsCondition { 14 | } 15 | 16 | @ConditionalOnProperty(name = "com.c4-soft.springaddons.oidc.resourceserver.csrf", havingValue = "cookie-accessible-from-js") 17 | static class ResourceServerCookieAccessibleFromJsCondition { 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultAuthenticationEntryPointCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 4 | import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; 5 | import org.springframework.security.web.AuthenticationEntryPoint; 6 | import org.springframework.security.web.server.ServerAuthenticationEntryPoint; 7 | 8 | public class DefaultAuthenticationEntryPointCondition extends NoneNestedConditions { 9 | 10 | public DefaultAuthenticationEntryPointCondition() { 11 | super(ConfigurationPhase.REGISTER_BEAN); 12 | } 13 | 14 | @ConditionalOnBean(AuthenticationEntryPoint.class) 15 | static class AuthenticationEntryPointCondition { 16 | } 17 | 18 | @ConditionalOnBean(ServerAuthenticationEntryPoint.class) 19 | static class ServerAuthenticationEntryPointCondition { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultAuthenticationFailureHandlerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 4 | import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; 5 | import org.springframework.security.web.authentication.AuthenticationFailureHandler; 6 | import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler; 7 | 8 | public class DefaultAuthenticationFailureHandlerCondition extends NoneNestedConditions { 9 | 10 | public DefaultAuthenticationFailureHandlerCondition() { 11 | super(ConfigurationPhase.REGISTER_BEAN); 12 | } 13 | 14 | @ConditionalOnBean(AuthenticationFailureHandler.class) 15 | static class AuthenticationFailureHandlerProvidedCondition { 16 | } 17 | 18 | @ConditionalOnBean(ServerAuthenticationFailureHandler.class) 19 | static class ServerAuthenticationFailureHandlerProvidedCondition { 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultAuthenticationManagerResolverCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.security.authentication.AuthenticationManagerResolver; 7 | import org.springframework.security.authentication.ReactiveAuthenticationManagerResolver; 8 | 9 | public class DefaultAuthenticationManagerResolverCondition extends AllNestedConditions { 10 | 11 | DefaultAuthenticationManagerResolverCondition() { 12 | super(ConfigurationPhase.REGISTER_BEAN); 13 | } 14 | 15 | @Conditional(IsJwtDecoderResourceServerCondition.class) 16 | static class IsJwtResourceServer { 17 | } 18 | 19 | @ConditionalOnMissingBean(AuthenticationManagerResolver.class) 20 | static class CustomAuthenticationManagerResolverNotProvided { 21 | } 22 | 23 | @ConditionalOnMissingBean(ReactiveAuthenticationManagerResolver.class) 24 | static class CustomReactiveAuthenticationManagerResolverNotProvided { 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultAuthenticationSuccessHandlerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 4 | import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; 5 | import org.springframework.security.web.authentication.AuthenticationSuccessHandler; 6 | import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler; 7 | 8 | public class DefaultAuthenticationSuccessHandlerCondition extends NoneNestedConditions { 9 | 10 | public DefaultAuthenticationSuccessHandlerCondition() { 11 | super(ConfigurationPhase.REGISTER_BEAN); 12 | } 13 | 14 | @ConditionalOnBean(AuthenticationSuccessHandler.class) 15 | static class AuthenticationSuccessHandlerProvidedCondition { 16 | } 17 | 18 | @ConditionalOnBean(ServerAuthenticationSuccessHandler.class) 19 | static class ServerAuthenticationSuccessHandlerProvidedCondition { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultCorsFilterCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.web.filter.CorsFilter; 7 | 8 | public class DefaultCorsFilterCondition extends AllNestedConditions { 9 | 10 | public DefaultCorsFilterCondition() { 11 | super(ConfigurationPhase.REGISTER_BEAN); 12 | } 13 | 14 | @Conditional(BackwardCompatibleCorsPropertiesCondition.class) 15 | static class HasCorsPropertiesCondition {} 16 | 17 | @ConditionalOnMissingBean(CorsFilter.class) 18 | static class NoCorsFilterRegisteredCondition {} 19 | 20 | } 21 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultCorsWebFilterCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.web.cors.reactive.CorsWebFilter; 7 | 8 | public class DefaultCorsWebFilterCondition extends AllNestedConditions { 9 | 10 | public DefaultCorsWebFilterCondition() { 11 | super(ConfigurationPhase.REGISTER_BEAN); 12 | } 13 | 14 | @Conditional(BackwardCompatibleCorsPropertiesCondition.class) 15 | static class HasCorsPropertiesCondition {} 16 | 17 | @ConditionalOnMissingBean(CorsWebFilter.class) 18 | static class NoCorsFilterRegisteredCondition {} 19 | 20 | } 21 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultGrantedAuthoritiesMapperCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.properties.condition.configuration.IsClientWithLoginCondition; 9 | 10 | public class DefaultGrantedAuthoritiesMapperCondition extends AllNestedConditions { 11 | DefaultGrantedAuthoritiesMapperCondition() { 12 | super(ConfigurationPhase.REGISTER_BEAN); 13 | } 14 | 15 | @Conditional(IsClientWithLoginCondition.class) 16 | static class SpringAddonsOidcClientEnabled { 17 | } 18 | 19 | @ConditionalOnMissingBean(GrantedAuthoritiesMapper.class) 20 | static class CustomGrantedAuthoritiesMapperNotProvided { 21 | } 22 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultOAuth2AuthorizedClientManagerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.properties.condition.HasOAuth2RegistrationPropertiesCondition; 9 | 10 | public class DefaultOAuth2AuthorizedClientManagerCondition extends AllNestedConditions { 11 | 12 | public DefaultOAuth2AuthorizedClientManagerCondition() { 13 | super(ConfigurationPhase.REGISTER_BEAN); 14 | } 15 | 16 | @Conditional(HasOAuth2RegistrationPropertiesCondition.class) 17 | static class HasOAuth2RegistrationCondition {} 18 | 19 | @ConditionalOnMissingBean(OAuth2AuthorizedClientManager.class) 20 | static class MissingOAuth2AuthorizedClientManagerCondition {} 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultOAuth2AuthorizedClientProviderCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.properties.condition.HasOAuth2RegistrationPropertiesCondition; 9 | 10 | public class DefaultOAuth2AuthorizedClientProviderCondition extends AllNestedConditions { 11 | 12 | public DefaultOAuth2AuthorizedClientProviderCondition() { 13 | super(ConfigurationPhase.REGISTER_BEAN); 14 | } 15 | 16 | @Conditional(HasOAuth2RegistrationPropertiesCondition.class) 17 | static class HasOAuth2RegistrationCondition {} 18 | 19 | @ConditionalOnMissingBean(OAuth2AuthorizedClientProvider.class) 20 | static class MissingOAuth2AuthorizedClientProviderCondition {} 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultOidcBackChannelLogoutHandlerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | import org.springframework.security.config.annotation.web.configurers.oauth2.client.OidcBackChannelLogoutHandler; 7 | import org.springframework.security.config.web.server.OidcBackChannelServerLogoutHandler; 8 | 9 | public class DefaultOidcBackChannelLogoutHandlerCondition extends AllNestedConditions { 10 | 11 | public DefaultOidcBackChannelLogoutHandlerCondition() { 12 | super(ConfigurationPhase.REGISTER_BEAN); 13 | } 14 | 15 | @ConditionalOnProperty(name = "com.c4-soft.springaddons.oidc.client.back-channel-logout.enabled") 16 | static class BackChannelLogoutEnabledCondition { 17 | } 18 | 19 | @ConditionalOnMissingBean(OidcBackChannelLogoutHandler.class) 20 | static class NoOidcBackChannelLogoutHandlerCondition { 21 | } 22 | 23 | @ConditionalOnMissingBean(OidcBackChannelServerLogoutHandler.class) 24 | static class NoOidcBackChannelServerLogoutHandlerCondition { 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultOidcSessionRegistryCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | import org.springframework.security.oauth2.client.oidc.server.session.ReactiveOidcSessionRegistry; 7 | import org.springframework.security.oauth2.client.oidc.session.OidcSessionRegistry; 8 | 9 | public class DefaultOidcSessionRegistryCondition extends AllNestedConditions { 10 | 11 | public DefaultOidcSessionRegistryCondition() { 12 | super(ConfigurationPhase.REGISTER_BEAN); 13 | } 14 | 15 | @ConditionalOnProperty(name = "com.c4-soft.springaddons.oidc.client.back-channel-logout.enabled") 16 | static class BackChannelLogoutEnabledCondition {} 17 | 18 | @ConditionalOnMissingBean(OidcSessionRegistry.class) 19 | static class NoOidcSessionRegistryCondition {} 20 | 21 | @ConditionalOnMissingBean(ReactiveOidcSessionRegistry.class) 22 | static class NoReactiveOidcSessionRegistryCondition {} 23 | 24 | } 25 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultReactiveOAuth2AuthorizedClientManagerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.properties.condition.HasOAuth2RegistrationPropertiesCondition; 9 | 10 | public class DefaultReactiveOAuth2AuthorizedClientManagerCondition extends AllNestedConditions { 11 | 12 | public DefaultReactiveOAuth2AuthorizedClientManagerCondition() { 13 | super(ConfigurationPhase.REGISTER_BEAN); 14 | } 15 | 16 | @Conditional(HasOAuth2RegistrationPropertiesCondition.class) 17 | static class HasOAuth2RegistrationCondition {} 18 | 19 | @ConditionalOnMissingBean(ReactiveOAuth2AuthorizedClientManager.class) 20 | static class MissingReactiveOAuth2AuthorizedClientManagerCondition {} 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/DefaultReactiveOAuth2AuthorizedClientProviderCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.properties.condition.HasOAuth2RegistrationPropertiesCondition; 9 | 10 | public class DefaultReactiveOAuth2AuthorizedClientProviderCondition extends AllNestedConditions { 11 | 12 | public DefaultReactiveOAuth2AuthorizedClientProviderCondition() { 13 | super(ConfigurationPhase.REGISTER_BEAN); 14 | } 15 | 16 | @Conditional(HasOAuth2RegistrationPropertiesCondition.class) 17 | static class HasOAuth2RegistrationCondition {} 18 | 19 | @ConditionalOnMissingBean(ReactiveOAuth2AuthorizedClientProvider.class) 20 | static class MissingReactiveOAuth2AuthorizedClientProviderCondition {} 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/IsIntrospectingResourceServerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 5 | 6 | public class IsIntrospectingResourceServerCondition extends AnyNestedCondition { 7 | 8 | IsIntrospectingResourceServerCondition() { 9 | super(ConfigurationPhase.REGISTER_BEAN); 10 | } 11 | 12 | @ConditionalOnProperty("spring.security.oauth2.resourceserver.opaquetoken.introspection-uri") 13 | static class IsOpaqueTokenIntrospectionUriDeclared { 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/bean/IsJwtDecoderResourceServerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.bean; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; 5 | 6 | public class IsJwtDecoderResourceServerCondition extends NoneNestedConditions { 7 | 8 | IsJwtDecoderResourceServerCondition() { 9 | super(ConfigurationPhase.REGISTER_BEAN); 10 | } 11 | 12 | @ConditionalOnProperty("spring.security.oauth2.resourceserver.opaquetoken.introspection-uri") 13 | static class IsOpaqueTokenIntrospectionUriDeclared { 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/configuration/IsClientWithLoginCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.configuration; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | 7 | public class IsClientWithLoginCondition extends AnyNestedCondition { 8 | 9 | public IsClientWithLoginCondition() { 10 | super(ConfigurationPhase.PARSE_CONFIGURATION); 11 | } 12 | 13 | @ConditionalOnExpression("!(T(org.springframework.util.StringUtils).isEmpty('${com.c4-soft.springaddons.oidc.client.security-matchers:}') && T(org.springframework.util.StringUtils).isEmpty('${com.c4-soft.springaddons.oidc.client.security-matchers[0]:}'))") 14 | static class Value1Condition { 15 | 16 | } 17 | 18 | @ConditionalOnProperty(name = "com.c4-soft.springaddons.oidc.client.security-matchers[0]") 19 | static class Value2Condition { 20 | 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/configuration/IsNotServlet.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.configuration; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 5 | import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; 6 | 7 | public class IsNotServlet extends NoneNestedConditions { 8 | 9 | public IsNotServlet() { 10 | super(ConfigurationPhase.PARSE_CONFIGURATION); 11 | } 12 | 13 | @ConditionalOnWebApplication(type = Type.SERVLET) 14 | static class IsServletWebApp { 15 | 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/configuration/IsOidcResourceServerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.configuration; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | import org.springframework.security.oauth2.server.resource.web.HeaderBearerTokenResolver; 7 | 8 | public class IsOidcResourceServerCondition extends AllNestedConditions { 9 | 10 | IsOidcResourceServerCondition() { 11 | super(ConfigurationPhase.PARSE_CONFIGURATION); 12 | } 13 | 14 | @ConditionalOnProperty(prefix = "com.c4-soft.springaddons.oidc.resourceserver", name = "enabled", matchIfMissing = true) 15 | static class SpringAddonsResourceServerEnabled { 16 | } 17 | 18 | @ConditionalOnClass(HeaderBearerTokenResolver.class) 19 | static class BearerTokenAuthenticationFilterIsOnClassPath { 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/configuration/IsReactiveOauth2ClientCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.configuration; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 7 | import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; 8 | 9 | public class IsReactiveOauth2ClientCondition extends AllNestedConditions { 10 | 11 | public IsReactiveOauth2ClientCondition() { 12 | super(ConfigurationPhase.PARSE_CONFIGURATION); 13 | } 14 | 15 | @ConditionalOnClass(ReactiveOAuth2AuthorizedClientManager.class) 16 | static class IsAuthorizedClientManagerClassOnTheClasspath { 17 | 18 | } 19 | 20 | @ConditionalOnWebApplication(type = Type.REACTIVE) 21 | static class IsReactiveApp { 22 | 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/properties/condition/configuration/IsServletOauth2ClientCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.properties.condition.configuration; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 7 | import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; 8 | 9 | public class IsServletOauth2ClientCondition extends AllNestedConditions { 10 | 11 | public IsServletOauth2ClientCondition() { 12 | super(ConfigurationPhase.PARSE_CONFIGURATION); 13 | } 14 | 15 | @ConditionalOnClass(OAuth2AuthorizedClientManager.class) 16 | static class IsAuthorizedClientManagerClassOnTheClasspath { 17 | 18 | } 19 | 20 | @ConditionalOnWebApplication(type = Type.SERVLET) 21 | static class IsServlet { 22 | 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/reactive/AuthorizeExchangeSpecPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive; 2 | 3 | import org.springframework.security.config.web.server.ServerHttpSecurity; 4 | 5 | /** 6 | * Customize access-control for routes which where not listed in spring-addons "permit-all" properties for client and resource server filter chains 7 | * 8 | * @author ch4mp 9 | */ 10 | public interface AuthorizeExchangeSpecPostProcessor { 11 | ServerHttpSecurity.AuthorizeExchangeSpec authorizeHttpRequests(ServerHttpSecurity.AuthorizeExchangeSpec spec); 12 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/reactive/ReactiveHttpSecurityPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive; 2 | 3 | import org.springframework.security.config.web.server.ServerHttpSecurity; 4 | 5 | /** 6 | * Process {@link ServerHttpSecurity} of default security filter-chain after it was processed by spring-addons. This enables to override anything that was 7 | * auto-configured (or add to it). 8 | * 9 | * @author ch4mp 10 | */ 11 | public interface ReactiveHttpSecurityPostProcessor { 12 | ServerHttpSecurity process(ServerHttpSecurity serverHttpSecurity); 13 | } 14 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/reactive/client/ClientAuthorizeExchangeSpecPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive.client; 2 | 3 | import com.c4_soft.springaddons.security.oidc.starter.reactive.AuthorizeExchangeSpecPostProcessor; 4 | 5 | public interface ClientAuthorizeExchangeSpecPostProcessor extends AuthorizeExchangeSpecPostProcessor { 6 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/reactive/client/ClientReactiveHttpSecurityPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive.client; 2 | 3 | import com.c4_soft.springaddons.security.oidc.starter.reactive.ReactiveHttpSecurityPostProcessor; 4 | 5 | public interface ClientReactiveHttpSecurityPostProcessor extends ReactiveHttpSecurityPostProcessor { 6 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/reactive/resourceserver/ReactiveJwtAbstractAuthenticationTokenConverter.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive.resourceserver; 2 | 3 | import org.springframework.core.convert.converter.Converter; 4 | import org.springframework.security.authentication.AbstractAuthenticationToken; 5 | import org.springframework.security.oauth2.jwt.Jwt; 6 | 7 | import reactor.core.publisher.Mono; 8 | 9 | public interface ReactiveJwtAbstractAuthenticationTokenConverter extends Converter> { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/reactive/resourceserver/ResourceServerAuthorizeExchangeSpecPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive.resourceserver; 2 | 3 | import com.c4_soft.springaddons.security.oidc.starter.reactive.AuthorizeExchangeSpecPostProcessor; 4 | 5 | /** 6 | * Customize access-control for routes which where not listed in 7 | * {@link com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcClientProperties#permitAll SpringAddonsOidcClientProperties::permit-all} or 8 | * {@link com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcResourceServerProperties#permitAll 9 | * SpringAddonsOidcResourceServerProperties::permit-all} 10 | * 11 | * @author ch4mp 12 | */ 13 | public interface ResourceServerAuthorizeExchangeSpecPostProcessor extends AuthorizeExchangeSpecPostProcessor { 14 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/reactive/resourceserver/ResourceServerReactiveHttpSecurityPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive.resourceserver; 2 | 3 | import org.springframework.security.config.web.server.ServerHttpSecurity; 4 | 5 | import com.c4_soft.springaddons.security.oidc.starter.reactive.ReactiveHttpSecurityPostProcessor; 6 | 7 | /** 8 | * Process {@link ServerHttpSecurity} of default security filter-chain after it was processed by spring-addons. This enables to override anything that was 9 | * auto-configured (or add to it). 10 | * 11 | * @author ch4mp 12 | */ 13 | public interface ResourceServerReactiveHttpSecurityPostProcessor extends ReactiveHttpSecurityPostProcessor { 14 | } 15 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/reactive/resourceserver/SpringAddonsReactiveJwtDecoderFactory.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive.resourceserver; 2 | 3 | import java.net.URI; 4 | import java.util.Optional; 5 | 6 | import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.OpenidProviderPropertiesResolver; 9 | 10 | /** 11 | *

12 | * Provides with a JwtDecoder (configured with the required validators). Both JWK-set and issuer URIs are optional, but at least one should be provided. 13 | *

14 | *

15 | * {@link DefaultSpringAddonsReactiveJwtDecoderFactory}, the default implementation uses {@link OpenidProviderPropertiesResolver} to resolve the matching OpenID Provider 16 | * configuration properties and throws an exception if none are found (the token issuer is not trusted). 17 | *

18 | */ 19 | public interface SpringAddonsReactiveJwtDecoderFactory { 20 | ReactiveJwtDecoder create(Optional jwkSetUri, Optional issuer, Optional audience); 21 | } 22 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/ExpressionInterceptUrlRegistryPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised; 2 | 3 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 4 | import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; 5 | 6 | import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcClientProperties; 7 | import com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcResourceServerProperties; 8 | 9 | /** 10 | * Customize access-control for routes which where not listed in {@link SpringAddonsOidcClientProperties#permitAll} or 11 | * {@link SpringAddonsOidcResourceServerProperties#permitAll} 12 | * 13 | * @author ch4mp 14 | */ 15 | public interface ExpressionInterceptUrlRegistryPostProcessor { 16 | AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry 17 | authorizeHttpRequests(AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry registry); 18 | } 19 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/SynchronizedHttpSecurityPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised; 2 | 3 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 4 | 5 | public interface SynchronizedHttpSecurityPostProcessor { 6 | HttpSecurity process(HttpSecurity httpSecurity) throws Exception; 7 | } 8 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/client/ClientExpressionInterceptUrlRegistryPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised.client; 2 | 3 | import com.c4_soft.springaddons.security.oidc.starter.synchronised.ExpressionInterceptUrlRegistryPostProcessor; 4 | 5 | /** 6 | * Post processor for access control in Java configuration. 7 | * 8 | * @author Jerome Wacongne ch4mp@c4-soft.com 9 | */ 10 | public interface ClientExpressionInterceptUrlRegistryPostProcessor extends ExpressionInterceptUrlRegistryPostProcessor { 11 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/client/ClientSynchronizedHttpSecurityPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised.client; 2 | 3 | import com.c4_soft.springaddons.security.oidc.starter.synchronised.SynchronizedHttpSecurityPostProcessor; 4 | 5 | /** 6 | * A post-processor to override anything from spring-addons client security filter-chain auto-configuration. 7 | * 8 | * @author Jerome Wacongne ch4mp@c4-soft.com 9 | */ 10 | public interface ClientSynchronizedHttpSecurityPostProcessor extends SynchronizedHttpSecurityPostProcessor { 11 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/client/PreAuthorizationCodeRedirectStrategy.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised.client; 2 | 3 | import org.springframework.security.web.RedirectStrategy; 4 | 5 | public interface PreAuthorizationCodeRedirectStrategy extends RedirectStrategy {} -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/resourceserver/JwtAbstractAuthenticationTokenConverter.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver; 2 | 3 | import org.springframework.core.convert.converter.Converter; 4 | import org.springframework.security.authentication.AbstractAuthenticationToken; 5 | import org.springframework.security.oauth2.jwt.Jwt; 6 | 7 | public interface JwtAbstractAuthenticationTokenConverter extends Converter { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/resourceserver/ResourceServerExpressionInterceptUrlRegistryPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver; 2 | 3 | import com.c4_soft.springaddons.security.oidc.starter.synchronised.ExpressionInterceptUrlRegistryPostProcessor; 4 | 5 | public interface ResourceServerExpressionInterceptUrlRegistryPostProcessor extends ExpressionInterceptUrlRegistryPostProcessor { 6 | } 7 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/resourceserver/ResourceServerSynchronizedHttpSecurityPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver; 2 | 3 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 4 | 5 | import com.c4_soft.springaddons.security.oidc.starter.synchronised.SynchronizedHttpSecurityPostProcessor; 6 | 7 | /** 8 | * Process {@link HttpSecurity} of default security filter-chain after it was processed by spring-addons. This enables to override anything that was 9 | * auto-configured (or add to it). 10 | * 11 | * @author ch4mp 12 | */ 13 | public interface ResourceServerSynchronizedHttpSecurityPostProcessor extends SynchronizedHttpSecurityPostProcessor { 14 | } 15 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/resourceserver/SpringAddonsJwtDecoderFactory.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver; 2 | 3 | import java.net.URI; 4 | import java.util.Optional; 5 | 6 | import org.springframework.security.oauth2.jwt.JwtDecoder; 7 | 8 | import com.c4_soft.springaddons.security.oidc.starter.OpenidProviderPropertiesResolver; 9 | 10 | /** 11 | *

12 | * Provides with a JwtDecoder (configured with the required validators). Both JWK-set and issuer URIs are optional, but at least one should be provided. 13 | *

14 | *

15 | * {@link DefaultSpringAddonsJwtDecoderFactory}, the default implementation uses {@link OpenidProviderPropertiesResolver} to resolve the matching OpenID Provider 16 | * configuration properties and throws an exception if none are found (the token issuer is not trusted). 17 | *

18 | */ 19 | public interface SpringAddonsJwtDecoderFactory { 20 | JwtDecoder create(Optional jwkSetUri, Optional issuer, Optional audience); 21 | } -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.c4_soft.springaddons.security.oidc.starter.properties.SpringAddonsOidcProperties 2 | 3 | com.c4_soft.springaddons.security.oidc.starter.reactive.client.ReactiveSpringAddonsOAuth2AuthorizedClientBeans 4 | com.c4_soft.springaddons.security.oidc.starter.reactive.client.ReactiveSpringAddonsOidcClientWithLoginBeans 5 | com.c4_soft.springaddons.security.oidc.starter.reactive.resourceserver.ReactiveSpringAddonsOidcResourceServerBeans 6 | 7 | com.c4_soft.springaddons.security.oidc.starter.synchronised.client.SpringAddonsOAuth2AuthorizedClientBeans 8 | com.c4_soft.springaddons.security.oidc.starter.synchronised.client.SpringAddonsOidcClientWithLoginBeans 9 | com.c4_soft.springaddons.security.oidc.starter.synchronised.resourceserver.SpringAddonsOidcResourceServerBeans 10 | -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/main/resources/c4-spring-addons.properties: -------------------------------------------------------------------------------- 1 | spring.aop.proxy-target-class=false -------------------------------------------------------------------------------- /spring-addons-starter-oidc/src/test/java/com/c4_soft/springaddons/security/oidc/starter/reactive/client/SpringAddonsServerOAuth2AuthorizationRequestResolverTest.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.security.oidc.starter.reactive.client; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertNull; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | class SpringAddonsServerOAuth2AuthorizationRequestResolverTest { 9 | 10 | @Test 11 | void whenRequestPathMatchesAuthorizationCodePattern_thenClientRegistrationIdIsReturned() { 12 | final var actual = SpringAddonsServerOAuth2AuthorizationRequestResolver.resolveRegistrationId("/oauth2/authorization/authorization-code"); 13 | assertEquals("authorization-code", actual); 14 | } 15 | 16 | @Test 17 | void whenRequestPathDoesNotMatchAuthorizationCodePattern_thenClientRegistrationIdIsReturned() { 18 | final var actual = SpringAddonsServerOAuth2AuthorizationRequestResolver.resolveRegistrationId("/login/authorization/authorization-code"); 19 | assertNull(actual); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-addons-starter-openapi/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.c4-soft.springaddons 5 | spring-addons 6 | 8.1.16-SNAPSHOT 7 | .. 8 | 9 | spring-addons-starter-openapi 10 | 11 | https://github.com/ch4mpy/spring-addons/ 12 | 13 | scm:git:git://github.com/ch4mpy/spring-addons.git 14 | scm:git:git@github.com:ch4mpy/spring-addons.git 15 | https://github.com/ch4mpy/spring-addons 16 | spring-addons-7.8.8 17 | 18 | 19 | 20 | 21 | org.springdoc 22 | springdoc-openapi-starter-webflux-api 23 | true 24 | 25 | 26 | org.springdoc 27 | springdoc-openapi-starter-webmvc-api 28 | true 29 | 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | provided 35 | 36 | 37 | -------------------------------------------------------------------------------- /spring-addons-starter-openapi/src/main/java/com/c4_soft/springaddons/openapi/EnumPossibleValuesExtractor.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.openapi; 2 | 3 | import java.util.Set; 4 | 5 | public interface EnumPossibleValuesExtractor { 6 | Set getValues(Class> enumClass); 7 | } -------------------------------------------------------------------------------- /spring-addons-starter-openapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.c4_soft.springaddons.openapi.SpringAddonsOpenapiAutoConfiguration 2 | -------------------------------------------------------------------------------- /spring-addons-starter-recaptcha/src/main/java/com/c4_soft/springaddons/starter/recaptcha/C4ReCaptchaSettings.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.starter.recaptcha; 2 | 3 | import java.net.URL; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.boot.context.properties.NestedConfigurationProperty; 7 | import org.springframework.stereotype.Component; 8 | import com.c4_soft.springaddons.rest.SpringAddonsRestProperties.RestClientProperties.ClientHttpRequestFactoryProperties; 9 | import lombok.Data; 10 | 11 | @Data 12 | @Component 13 | @ConfigurationProperties(prefix = "com.c4-soft.springaddons.recaptcha") 14 | public class C4ReCaptchaSettings { 15 | 16 | private String secretKey; 17 | 18 | @Value("${siteverify-url:https://www.google.com/recaptcha/api/siteverify}") 19 | private URL siteverifyUrl; 20 | 21 | private double v3Threshold = .5; 22 | 23 | @NestedConfigurationProperty 24 | private ClientHttpRequestFactoryProperties http; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /spring-addons-starter-recaptcha/src/main/java/com/c4_soft/springaddons/starter/recaptcha/ReCaptchaValidationException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.starter.recaptcha; 2 | 3 | /** 4 | * @author Jérôme Wacongne ch4mp@c4-soft.com 5 | */ 6 | public class ReCaptchaValidationException extends RuntimeException { 7 | private static final long serialVersionUID = 6903170315686842893L; 8 | 9 | public ReCaptchaValidationException(String message) { 10 | super(message); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-addons-starter-recaptcha/src/main/java/com/c4_soft/springaddons/starter/recaptcha/SpringBootAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.starter.recaptcha; 2 | 3 | import org.springframework.boot.autoconfigure.AutoConfiguration; 4 | import org.springframework.context.annotation.Import; 5 | 6 | @AutoConfiguration 7 | @Import({ C4ReCaptchaSettings.class, C4ReCaptchaValidationService.class }) 8 | public class SpringBootAutoConfiguration { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /spring-addons-starter-recaptcha/src/main/java/com/c4_soft/springaddons/starter/recaptcha/V2ValidationResponseDto.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.starter.recaptcha; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @author Jérôme Wacongne ch4mp@c4-soft.com 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class V2ValidationResponseDto implements Serializable { 17 | private static final long serialVersionUID = -5003891633297808293L; 18 | 19 | /** 20 | * whether this request was a valid reCAPTCHA token for your site 21 | */ 22 | private boolean success; 23 | 24 | /** 25 | * timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ) 26 | */ 27 | private String challengeTs; 28 | 29 | /** 30 | * the hostname of the site where the reCAPTCHA was solved 31 | */ 32 | private String hostname; 33 | 34 | /** 35 | * optional 36 | */ 37 | private List errorCodes; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /spring-addons-starter-recaptcha/src/main/java/com/c4_soft/springaddons/starter/recaptcha/V3ValidationResponseDto.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.starter.recaptcha; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author Jérôme Wacongne ch4mp@c4-soft.com 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = true) 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class V3ValidationResponseDto extends V2ValidationResponseDto { 16 | private static final long serialVersionUID = 3873084888623735286L; 17 | 18 | /** 19 | * the score for this request (0.0 - 1.0) 20 | */ 21 | private double score; 22 | 23 | /** 24 | * the action name for this request (important to verify) 25 | */ 26 | private String action; 27 | } 28 | -------------------------------------------------------------------------------- /spring-addons-starter-recaptcha/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.c4_soft.springaddons.starter.recaptcha.SpringBootAutoConfiguration -------------------------------------------------------------------------------- /spring-addons-starter-recaptcha/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.ssl.enabled=false 2 | 3 | com.c4-soft.springaddons.recaptcha.secret-key=machin 4 | com.c4-soft.springaddons.recaptcha.siteverify-url=https://localhost/recaptcha/api/siteverify 5 | com.c4-soft.springaddons.recaptcha.v3-threshold=0.8 6 | 7 | #--- 8 | spring.config.activate.on-profile=proxy 9 | http_proxy=https://machin:truc@env-proxy:8080 10 | no_proxy=localhost,bravo-ch4mp,.env-domain.pf -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/main/java/com/c4_soft/springaddons/rest/RestConfigurationNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest; 2 | 3 | public class RestConfigurationNotFoundException extends RuntimeException { 4 | private static final long serialVersionUID = -1174591896184901571L; 5 | 6 | public RestConfigurationNotFoundException(String clientName) { 7 | super("No spring-addons OAuth2 client properties for a REST client named %s".formatted(clientName)); 8 | } 9 | } -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/main/java/com/c4_soft/springaddons/rest/RestMisconfigurationException.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest; 2 | 3 | public class RestMisconfigurationException extends RuntimeException { 4 | private static final long serialVersionUID = 681577983030933423L; 5 | 6 | public RestMisconfigurationException(String message) { 7 | super(message); 8 | } 9 | 10 | public RestMisconfigurationException(Throwable e) { 11 | super(e); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/main/java/com/c4_soft/springaddons/rest/reactive/DefaultReactiveAuthorizationFailureHandlerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest.reactive; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 6 | import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizationFailureHandler; 7 | import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; 8 | 9 | public class DefaultReactiveAuthorizationFailureHandlerCondition extends AllNestedConditions { 10 | 11 | DefaultReactiveAuthorizationFailureHandlerCondition() { 12 | super(ConfigurationPhase.REGISTER_BEAN); 13 | } 14 | 15 | @ConditionalOnMissingBean(ReactiveOAuth2AuthorizationFailureHandler.class) 16 | static class OAuth2AuthorizationFailureHandlerNotProvided { 17 | } 18 | 19 | @ConditionalOnBean(ServerOAuth2AuthorizedClientRepository.class) 20 | static class AuthorizedClientRepositoryProvided { 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/main/java/com/c4_soft/springaddons/rest/reactive/ServerWebClientBuilderFactoryBean.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest.reactive; 2 | 3 | import java.util.Optional; 4 | import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; 5 | import org.springframework.web.reactive.function.client.ExchangeFilterFunction; 6 | import com.c4_soft.springaddons.rest.AbstractWebClientBuilderFactoryBean; 7 | import lombok.Setter; 8 | 9 | @Setter 10 | public class ServerWebClientBuilderFactoryBean extends AbstractWebClientBuilderFactoryBean { 11 | private Optional authorizedClientManager; 12 | 13 | @Override 14 | protected ExchangeFilterFunction registrationExchangeFilterFunction(String Oauth2RegistrationId) { 15 | return SpringAddonsServerWebClientSupport 16 | .registrationExchangeFilterFunction(authorizedClientManager.get(), Oauth2RegistrationId); 17 | } 18 | 19 | @Override 20 | protected ExchangeFilterFunction forwardingBearerExchangeFilterFunction() { 21 | return SpringAddonsServerWebClientSupport.forwardingBearerExchangeFilterFunction(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/main/java/com/c4_soft/springaddons/rest/synchronised/DefaultAuthorizationFailureHandlerCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest.synchronised; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 6 | import org.springframework.security.oauth2.client.OAuth2AuthorizationFailureHandler; 7 | import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; 8 | 9 | public class DefaultAuthorizationFailureHandlerCondition extends AllNestedConditions { 10 | 11 | DefaultAuthorizationFailureHandlerCondition() { 12 | super(ConfigurationPhase.REGISTER_BEAN); 13 | } 14 | 15 | @ConditionalOnMissingBean(OAuth2AuthorizationFailureHandler.class) 16 | static class OAuth2AuthorizationFailureHandlerNotProvided { 17 | } 18 | 19 | @ConditionalOnBean(OAuth2AuthorizedClientRepository.class) 20 | static class AuthorizedClientRepositoryProvided { 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/main/java/com/c4_soft/springaddons/rest/synchronised/IsServletWithWebClientCondition.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest.synchronised; 2 | 3 | import org.springframework.boot.autoconfigure.condition.AllNestedConditions; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 7 | import org.springframework.web.reactive.function.client.WebClient; 8 | 9 | /** 10 | * A conditon to apply @Configuration only if an application is a servlet and if 11 | * {@link WebClient} is on the class-path 12 | * 13 | * @author Jérôme Wacongne <ch4mp@c4-soft.com> 14 | */ 15 | public class IsServletWithWebClientCondition extends AllNestedConditions { 16 | 17 | IsServletWithWebClientCondition() { 18 | super(ConfigurationPhase.PARSE_CONFIGURATION); 19 | } 20 | 21 | @ConditionalOnWebApplication(type = Type.SERVLET) 22 | static class IsServlet { 23 | } 24 | 25 | @ConditionalOnClass(WebClient.class) 26 | static class IsWebClientOnClasspath { 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/main/java/com/c4_soft/springaddons/rest/synchronised/SpringAddonsRestClientBeans.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest.synchronised; 2 | 3 | import org.springframework.boot.autoconfigure.AutoConfiguration; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.core.env.Environment; 8 | 9 | /** 10 | * Applied only in servlet applications. 11 | * 12 | * @author Jérôme Wacongne <ch4mp@c4-soft.com> 13 | */ 14 | @ConditionalOnWebApplication(type = Type.SERVLET) 15 | @AutoConfiguration 16 | public class SpringAddonsRestClientBeans { 17 | 18 | @Bean 19 | SpringAddonsRestClientBeanDefinitionRegistryPostProcessor springAddonsRestClientBeanDefinitionRegistryPostProcessor( 20 | Environment environment) { 21 | return new SpringAddonsRestClientBeanDefinitionRegistryPostProcessor(environment); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.c4_soft.springaddons.rest.SystemProxyProperties 2 | com.c4_soft.springaddons.rest.SpringAddonsRestProperties 3 | com.c4_soft.springaddons.rest.synchronised.SpringAddonsRestClientBeans 4 | com.c4_soft.springaddons.rest.reactive.SpringAddonsServerWebClientBeans 5 | com.c4_soft.springaddons.rest.synchronised.SpringAddonsServletWebClientBeans -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/test/java/com/c4_soft/springaddons/rest/SpringAddonsClientHttpRequestFactoryDisabledTest.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | import java.io.IOException; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.ActiveProfiles; 8 | 9 | @SpringBootTest(classes = StubBootApplication.class) 10 | @ActiveProfiles("proxy-disabled") 11 | class SpringAddonsClientHttpRequestFactoryDisabledTest 12 | extends AbstractSpringAddonsClientHttpRequestFactoryTest { 13 | 14 | @Test 15 | void test() throws IOException, IllegalArgumentException, IllegalAccessException, 16 | NoSuchFieldException, SecurityException { 17 | assertFalse(isUsingProxy("http://server.external.com/foo")); 18 | assertFalse(isUsingProxy("http://localhost/foo")); 19 | assertFalse(isUsingProxy("http://bravo-ch4mp/foo")); 20 | assertFalse(isUsingProxy("http://server.corporate-domain.pf/foo")); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/test/java/com/c4_soft/springaddons/rest/SpringAddonsClientHttpRequestFactoryFullTest.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | import java.io.IOException; 6 | import org.junit.jupiter.api.Test; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.ActiveProfiles; 9 | 10 | @SpringBootTest(classes = StubBootApplication.class) 11 | @ActiveProfiles("proxy-full") 12 | class SpringAddonsClientHttpRequestFactoryFullTest 13 | extends AbstractSpringAddonsClientHttpRequestFactoryTest { 14 | 15 | @Test 16 | void test() throws IOException, IllegalArgumentException, IllegalAccessException, 17 | NoSuchFieldException, SecurityException { 18 | assertTrue(isUsingProxy("http://server.external.com/foo")); 19 | assertFalse(isUsingProxy("http://localhost/foo")); 20 | assertFalse(isUsingProxy("http://bravo-ch4mp/foo")); 21 | assertFalse(isUsingProxy("http://server.corporate-domain.pf/foo")); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/test/java/com/c4_soft/springaddons/rest/SpringAddonsClientHttpRequestFactoryMinimalTest.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | import java.io.IOException; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.ActiveProfiles; 8 | import org.wiremock.spring.EnableWireMock; 9 | 10 | @SpringBootTest(classes = StubBootApplication.class) 11 | @ActiveProfiles("proxy-minimal") 12 | @EnableWireMock 13 | class SpringAddonsClientHttpRequestFactoryMinimalTest 14 | extends AbstractSpringAddonsClientHttpRequestFactoryTest { 15 | 16 | @Test 17 | void test() throws IOException, IllegalArgumentException, IllegalAccessException, 18 | NoSuchFieldException, SecurityException { 19 | assertTrue(isUsingProxy("http://server.external.com/foo")); 20 | assertTrue(isUsingProxy("http://localhost/foo")); 21 | assertTrue(isUsingProxy("http://bravo-ch4mp/foo")); 22 | assertTrue(isUsingProxy("http://server.corporate-domain.pf/foo")); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/test/java/com/c4_soft/springaddons/rest/SpringAddonsClientHttpRequestFactoryStdEnvVarsTest.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | import java.io.IOException; 6 | import org.junit.jupiter.api.Test; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.ActiveProfiles; 9 | 10 | @SpringBootTest(classes = StubBootApplication.class) 11 | @ActiveProfiles("proxy-std-env-vars") 12 | class SpringAddonsClientHttpRequestFactoryStdEnvVarsTest 13 | extends AbstractSpringAddonsClientHttpRequestFactoryTest { 14 | 15 | @Test 16 | void test() throws IOException, IllegalArgumentException, IllegalAccessException, 17 | NoSuchFieldException, SecurityException { 18 | assertTrue(isUsingProxy("http://server.external.com/foo")); 19 | assertFalse(isUsingProxy("http://localhost/foo")); 20 | assertFalse(isUsingProxy("http://bravo-ch4mp/foo")); 21 | assertFalse(isUsingProxy("http://server.corporate-domain.pf/foo")); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/test/java/com/c4_soft/springaddons/rest/StubBootApplication.java: -------------------------------------------------------------------------------- 1 | package com.c4_soft.springaddons.rest; 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication; 4 | import org.springframework.context.annotation.Bean; 5 | import com.c4_soft.springaddons.rest.synchronised.SpringAddonsClientHttpRequestFactory; 6 | 7 | @SpringBootApplication 8 | class StubBootApplication { 9 | 10 | @Bean 11 | SpringAddonsClientHttpRequestFactory springAddonsClientHttpRequestFactory( 12 | SystemProxyProperties systemProperties, SpringAddonsRestProperties addonsProperties) { 13 | return new SpringAddonsClientHttpRequestFactory(systemProperties, 14 | addonsProperties.getClient().get("foo-client").getHttp()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spring-addons-starter-rest/src/test/resources/ch4mp.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm_access": { 3 | "roles": [ 4 | "NICE", "AUTHOR" 5 | ] 6 | }, 7 | "iss": "http://localhost:7080/auth/realms/spring-addons", 8 | "sub": "4dd56dbb-71ef-4fe2-9358-3ae3240a9e94", 9 | "scope": "openid email" 10 | } 11 | --------------------------------------------------------------------------------