{"id":21528192,"url":"https://github.com/znsio/specmatic-order-api-java-with-oauth","last_synced_at":"2025-04-09T23:41:26.982Z","repository":{"id":198059930,"uuid":"690364752","full_name":"znsio/specmatic-order-api-java-with-oauth","owner":"znsio","description":"A sample project to describe how to use Specmatic with a Java Spring Boot application with OAuth","archived":false,"fork":false,"pushed_at":"2025-03-20T12:01:48.000Z","size":1478,"stargazers_count":1,"open_issues_count":11,"forks_count":1,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-24T01:35:18.818Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/znsio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-12T03:54:34.000Z","updated_at":"2024-10-04T16:19:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"aecf4f36-185e-497a-91bd-0288c61479c5","html_url":"https://github.com/znsio/specmatic-order-api-java-with-oauth","commit_stats":null,"previous_names":["znsio/specmatic-order-api-java-with-oauth"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/znsio%2Fspecmatic-order-api-java-with-oauth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/znsio%2Fspecmatic-order-api-java-with-oauth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/znsio%2Fspecmatic-order-api-java-with-oauth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/znsio%2Fspecmatic-order-api-java-with-oauth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/znsio","download_url":"https://codeload.github.com/znsio/specmatic-order-api-java-with-oauth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248131468,"owners_count":21052819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-24T01:52:06.937Z","updated_at":"2025-04-09T23:41:26.962Z","avatar_url":"https://github.com/znsio.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Specmatic Sample Application to demonstrate OpenAPI OAuth2 security scheme support\n![Specmatic Sample Application to demonstrate OpenAPI OAuth2 security scheme support](assets/SpecmaticOAuth.gif)\n\nSpec: [OpenAPI Specification](https://github.com/znsio/specmatic-order-contracts/blob/main/io/specmatic/examples/store/openapi/api_order_with_oauth_v3.yaml) representing endpoints exposed by this application.\n\nThis project demonstrates how to leverage OpenAPI specifications as a Contract Test with Specmatic when the specification includes [OAuth2 security schemes](https://spec.openapis.org/oas/v3.0.1#security-scheme-object) to protect the endpoints.\nWe have used below tools to demonstrate the same.\n- Spring Boot\n- Keycloak\n- Spring Security\n- Specmatic\n- Open API Specification\n\nThe system under test here is a service that implements the OpenAPI specification and acts an OAuth2 resource server.\n\n## Running the application:\nIn this mode, we'll run Keycloak locally which we will leverage as our OAuth authorization server.  \nWe use a Spring Security Configuration (refer ```src/main/java/com/store/config/SecurityConfig.kt```) which secures every endpoint with scope : 'email'.  \nThis means, to access any endpoint, the request must contain a token with the 'email' scope in the Authorization header.  \nThe application validates the token received in every request by calling the ```spring.security.oauth2.resourceserver.jwt.issuer-uri``` url defined in the ```application.properties``` file.  \n\nHere are the steps to the run project in dev mode to take it for a spin.\n\n#### Start Keycloak\nFrom the project root folder, run:\n\n```shell\ndocker compose up\n```\nThis will start the Keycloak server on localhost:8083 and pre-load with a sample realm called \"specmatic\".\n\n#### Start the application\nFrom the project root folder, run:\n\n```shell\nmvn clean spring-boot:run -Dspring-boot.run.profiles=prod\n```\nThis will start the application on localhost:8080.\n\n#### Generate OAuth token\n* Open Postman.  \n* Create a new request with method:  ```GET``` and url: ```http://localhost:8080/products/10```  \n* Under the authorization tab select type as OAuth 2.0 and click on Get New Access Token button with below details\n```\nAuth URL = http://localhost:8083/realms/specmatic/protocol/openid-connect/auth\nAccess Token URL = http://localhost:8083/realms/specmatic/protocol/openid-connect/token\nCLient ID = order-api\nClient Secret = \u003cblank\u003e\nScope = profile email\n```\n* And select \"Authorize using browser\" and click \"Get New Access Token\"  \n* When redirected to browser enter the following user credentials:  \n```\nusername: user1\npassword: password\n```\n* Click the Signin button.  \n* You should then be able to see the generated access token with a ```Use Token``` button on top right.  \n* Click the ```Use Token``` button.  \n* This will take you back to your Postman request tab with the oauth token already added to the Authorization header. (The Authorization header might be hidden in the default view, but you can click on the hidden headers to see it)\n\n#### Optional\nIf you would like to take a look at the realm configuration of the Keycloak server launch admin console with http://localhost8083 in an incognito window (since your regular window you may have already logged in with the realm user credentials above) and login with username: admin and password: admin.\n\n#### Make request with OAuth token\nClick on the ```Send``` button in Postman. You should see the following response:  \n```json\n{\n\"name\": \"XYZ Phone\",\n\"type\": \"gadget\",\n\"inventory\": 6,\n\"id\": 10\n}\n```\n\nYou may want to debug through the application to understand and explore the flow better.\n\n## Running contract tests:\nWithin the context of contract tests, certain concerns such as authentication and authorization are orthogonal because the priority is to verify if the application is adhering to the specification itself.\nHowever, we do want to make sure that security schemes defined in the specification are also validated at least to the extent that appropriate fields such as headers are populated.\n\nIncluding other aspects such as having to run a keycloak server locally or pointing to a remote server, impedes the ability to isolate our System Under Test and thereby getting quick feedback.\n\nSo in test mode, application uses a dummy security configuration ((refer ```src/main/java/com/store/config/DummySecurityConfig.kt```)) which only checks if the Authorization header contains a string which starts with \"Bearer \".\nThe actual token is not validated.\n\nSpecmatic will use the Order API's open api specification, read the security scheme, generate a token and send it in the appropriate header while making a request.\nFrom the open api spec we can see that the service uses the ```oAuth2AuthCode``` security scheme, which is defined as follows:\n```yaml\n  securitySchemes:\n    oAuth2AuthCode:\n      type: oauth2\n      description: keycloak based oauth security example\n      flows:\n        authorizationCode:\n          authorizationUrl: http://localhost:8083/realms/specmatic/protocol/openid-connect/auth\n          tokenUrl: http://localhost:8083/realms/specmatic/protocol/openid-connect/token\n\nsecurity:\n  - oAuth2AuthCode: []\n```\n\nSpecmatic will check if an Open API security scheme named ```oAuth2AuthCode``` is defined in the ```security``` section in specmatic.json.  \nIf it finds it, it will pick up the token defined for the theme and use it to run tests.  \nIf no such theme is defined in specmatic.json, Specmatic will auto-generate a random string to be sent as the token.  \n\nWe can see that we do have the ```oAuth2AuthCode``` security scheme defined in specmatic.json:\n```json\n{\n  \"security\": {\n    \"OpenAPI\": {\n      \"securitySchemes\": {\n        \"oAuth2AuthCode\": {\n          \"type\": \"oauth2\",\n          \"token\": \"OAUTH1234\"\n        }\n      }\n    }\n  }\n}\n```\n\n#### Running Tests\nGo to the ContractTest class at ```src/test/java/com/store/ContractTest```  \nRun the contract tests (Ctrl+Shift+R)  \nAll tests should pass.  \nYou should see the Authorization header set for every test as:\n```\nRequest to http://localhost:8080 at 2023-9-27 6:59:20.607\n    GET /products/10\n    Authorization: Bearer OAUTH1234\n    Accept-Charset: UTF-8\n    Accept: */*\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fznsio%2Fspecmatic-order-api-java-with-oauth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fznsio%2Fspecmatic-order-api-java-with-oauth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fznsio%2Fspecmatic-order-api-java-with-oauth/lists"}