{"id":48836505,"url":"https://github.com/andrei-punko/oauth-server","last_synced_at":"2026-04-14T23:36:02.839Z","repository":{"id":105078824,"uuid":"265630688","full_name":"andrei-punko/oauth-server","owner":"andrei-punko","description":"Service with OAuth2 usage","archived":false,"fork":false,"pushed_at":"2026-04-10T22:10:56.000Z","size":413,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-11T00:10:08.690Z","etag":null,"topics":["oauth2","oauth2-server","spring-oauth2","spring-oauth2-sample","spring-security","spring-security-oauth2"],"latest_commit_sha":null,"homepage":"","language":"Java","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/andrei-punko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-05-20T16:54:58.000Z","updated_at":"2026-04-10T22:11:00.000Z","dependencies_parsed_at":"2023-12-09T13:23:29.472Z","dependency_job_id":"6c3923a4-96ab-4a83-b92d-4abf07e9fea7","html_url":"https://github.com/andrei-punko/oauth-server","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/andrei-punko/oauth-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrei-punko%2Foauth-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrei-punko%2Foauth-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrei-punko%2Foauth-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrei-punko%2Foauth-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrei-punko","download_url":"https://codeload.github.com/andrei-punko/oauth-server/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrei-punko%2Foauth-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31820113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T18:05:02.291Z","status":"ssl_error","status_checked_at":"2026-04-14T18:05:01.765Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["oauth2","oauth2-server","spring-oauth2","spring-oauth2-sample","spring-security","spring-security-oauth2"],"created_at":"2026-04-14T23:36:01.559Z","updated_at":"2026-04-14T23:36:02.814Z","avatar_url":"https://github.com/andrei-punko.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring Boot with REST API secured by JSON Web Token (JWT)\n\n![Java CI with Gradle](https://github.com/andrei-punko/oauth-server/workflows/Java%20CI%20with%20Gradle/badge.svg)\n[![Coverage](.github/badges/jacoco.svg)](https://github.com/andrei-punko/oauth-server/actions/workflows/gradle.yml)\n\n## Prerequisites\n\n- Maven 3\n- JDK 21\n\nUse https://jwt.io to decode your generated token  \nUse https://base64encode.org to encode/decode to/from Base64\n\n## How to build jar\n\n    ./gradlew clean build\n\n## How to build Docker image\n\n    docker build ./ -t oauth-service-app\n\n## How to run jars\n\n```bash\njava -jar ./build/libs/auth-server-0.1-SNAPSHOT.jar --auth.profile=mvpd\njava -jar ./build/libs/auth-server-0.1-SNAPSHOT.jar --auth.profile=ott\n```\n\n## How to run in Docker\n\n    docker-compose up\n\n## How to run both services in Docker containers with rebuild of images\n\n    docker-compose up --build --force-recreate --no-deps\n\n## Configuration info\n\n* Client: `entitlements`\n* Secret:\n    * `ott` (for `auth.profile=ott`)\n    * `mvpd` (for `auth.profile=mvpd`)\n* Username / password:\n    * `alice/password`\n    * `bob/password`\n    * `clara/password`\n\nSee [this article](https://alexbilbie.com/guide-to-oauth-2-grants) for info about different types of OAuth 2.0 grants\n\n## Authorization Grant cases\n\n### 1. Authorisation Code Grant\n\nAuthorize using login form on authorization server, get authorization code, exchange it to access token.\nVery familiar if you’ve ever signed into an application using your Facebook or Google account.\n\n#### Flow, part one: authorize using login form on authorization server\n\nUse\nlink: http://localhost:9090/oauth/authorize?client_id=entitlements\u0026state=abc-123\u0026response_type=code\u0026redirect_uri=http://localhost:9191/x\u0026node-name=hulu\n\nThe `state` here is CSRF token. This parameter is optional but recommended. You should store the value of the CSRF token\nin the user’s session to be validated when they return.\n\nThe user will then be asked to login to the authorization server and approve the client.\n\nPut `bob/ott` login/password pair into form and click `Approve`\n\n(The login/password pairs populated into in-memory DB H2. For details check sql scripts in resources folder if needed)\n\nIf the user approves the client they will be redirected from the authorisation server back to the client (specifically\nto the redirect URI).\nAfter some delay (due to redirection to some fake non-existing resource localhost:9191) you get string like next in\nbrowser address field:\nhttp://localhost:9191/x?code=qjGBjC\u0026state=abc-123.  \nGet code `qjGBjC` for future reuse in next actions.  \nThe returned state `abc-123` used to compare with the state parameter sent in the original request.\n\n#### Generate access token using authorization code from previous step\n\nUse the following generic command to generate an access token:\n\nFor this specific application, to generate an access token for the user bob, run next command:\n\n```bash\ncurl http://localhost:9090/oauth/token \\\n  -H \"Content-type: application/x-www-form-urlencoded\" \\\n  -d 'grant_type=authorization_code\u0026redirect_uri=http://localhost:9191/x\u0026code=qjGBjC' \\\n  -u entitlements:ott\n```\n\nAs you see - already generated for bob code `qjGBjC` was used\n\nYou'll receive responses similar to below\n\n```json\n{\n  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImV4cCI6MTU4NTIyOTMyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjIxODEwZWUxLWI5MGQtNDQ4My1hYTE1LTJlNjZkOTc4MjhlZSIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.5Ef4wabYaGi5Ed56kD9bLip92BDx6-WeKNfmwh7P-wI\",\n  \"token_type\": \"bearer\",\n  \"refresh_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImF0aSI6IjIxODEwZWUxLWI5MGQtNDQ4My1hYTE1LTJlNjZkOTc4MjhlZSIsImV4cCI6MTU4NzczNDkyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6ImFmOTk4NzNlLTVkMzItNDk1MS04YWFmLWFjN2VjYmViZjE4YiIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.pwDQPzq_pMzOMb5f_0GcZWo_mcd2ncT4oI-qbneOI_Y\",\n  \"expires_in\": 86399,\n  \"scope\": \"read\",\n  \"non_pii_id\": \"2f8-4da\",\n  \"jti\": \"21810ee1-b90d-4483-aa15-2e66d97828ee\"\n}\n```\n\n### 2. Resource owner credentials grant\n\nGet access token using login/password.\nUsed for trusted first party clients both on the web and in native device applications.\n\n#### Generate access token using password\n\n```bash\ncurl -X POST http://localhost:9090/oauth/token \\\n  -H 'Authorization: Basic ZW50aXRsZW1lbnRzOm90dA==' \\\n  -H 'Content-type: application/x-www-form-urlencoded' \\\n  -d 'grant_type=password' -d 'username=bob' -d 'password=ott'\n```\n\nHere we use header for basic authorization client_name:client_secret encoded into Base64:\n\n```\nentitlements:ott -\u003e ZW50aXRsZW1lbnRzOm90dA==\n```\n\nYou'll receive response similar to below\n\n```json\n{\n  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsic3Vic2NyaXB0aW9ucyIsInVzZXJzIl0sInVzZXJfbmFtZSI6ImJvYiIsInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNjUwNzA1MzY3LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiM2MwNjA2MjctM2FiNy00YTQyLTg4MmMtMjA4OWJkZjBlZTg1IiwiY2xpZW50X2lkIjoiZW50aXRsZW1lbnRzIiwibm9uX3BpaV9pZCI6IjJmOC00ZGEifQ.l_VgIDAXEuJu7Osv6mxmFv0J--MVJ7ZL8PwgnH-l2e0\",\n  \"token_type\": \"bearer\",\n  \"refresh_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsic3Vic2NyaXB0aW9ucyIsInVzZXJzIl0sInVzZXJfbmFtZSI6ImJvYiIsInNjb3BlIjpbInJlYWQiXSwiYXRpIjoiM2MwNjA2MjctM2FiNy00YTQyLTg4MmMtMjA4OWJkZjBlZTg1IiwiZXhwIjoxNjUzMjEwOTY3LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiNTI2YjBiY2YtYzc5OS00NzBlLThkNmYtNzY0ZGMzZDQ4NTI0IiwiY2xpZW50X2lkIjoiZW50aXRsZW1lbnRzIiwibm9uX3BpaV9pZCI6IjJmOC00ZGEifQ.NlH1NftfyuQLQ3sGwrzVL5wg9alvIS_2MOnSMpxrWZg\",\n  \"expires_in\": 86399,\n  \"scope\": \"read\",\n  \"non_pii_id\": \"2f8-4da\",\n  \"jti\": \"3c060627-3ab7-4a42-882c-2089bdf0ee85\"\n}\n```\n\n### 3. Client credentials grant\n\nThe simplest of OAuth 2.0 grants, it is suitable for machine-to-machine authentication where a specific user’s\npermission to access data is not required.\n\n#### Generate access token using password\n\n```bash\ncurl -X POST http://localhost:9090/oauth/token \\\n  -H 'Authorization: Basic ZW50aXRsZW1lbnRzOm90dA==' \\\n  -H \"Content-type: application/x-www-form-urlencoded\" \\\n  -d 'grant_type=client_credentials'\n```\n\nHere we use header for basic authorization client_name:client_secret encoded into Base64:\n\n```\nentitlements:ott -\u003e ZW50aXRsZW1lbnRzOm90dA==\n```\n\nYou'll receive response similar to below\n\n```json\n{\n  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsic3Vic2NyaXB0aW9ucyIsInVzZXJzIl0sInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNjUwNzA1MTQ5LCJqdGkiOiJmNGY3MWJmNy04YmRlLTQ0YWYtOGI5Zi00NzY1YzY0OGFlNmYiLCJjbGllbnRfaWQiOiJlbnRpdGxlbWVudHMifQ.kJXmS4e0dNzzYnJayKwH3VMU1bYnAa2ENV1aNMnIzAQ\",\n  \"token_type\": \"bearer\",\n  \"expires_in\": 86399,\n  \"scope\": \"read\",\n  \"jti\": \"f4f71bf7-8bde-44af-8b9f-4765c648ae6f\"\n}\n```\n\n## Check existing token\n\nTo check existing token use:\n\n```bash\ncurl -X POST client:secret@localhost:9090/oauth/check_token?token=TOKEN_HERE\n```\n\nFor our case it should be:\n\n```bash\ncurl -X POST entitlements:ott@localhost:9090/oauth/check_token?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImV4cCI6MTU4NTIyOTMyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjIxODEwZWUxLWI5MGQtNDQ4My1hYTE1LTJlNjZkOTc4MjhlZSIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.5Ef4wabYaGi5Ed56kD9bLip92BDx6-WeKNfmwh7P-wI\n```\n\nYou'll receive a response similar to below\n\n```json\n{\n  \"aud\": [\n    \"non_pii_id\"\n  ],\n  \"user_name\": \"bob\",\n  \"scope\": [\n    \"read\"\n  ],\n  \"active\": true,\n  \"exp\": 1585229328,\n  \"authorities\": [\n    \"ROLE_USER\"\n  ],\n  \"jti\": \"21810ee1-b90d-4483-aa15-2e66d97828ee\",\n  \"client_id\": \"entitlements\",\n  \"non_pii_id\": \"2f8-4da\"\n}\n```\n\nor next\n\n```json\n{\n  \"error\": \"invalid_token\",\n  \"error_description\": \"Encoded token is a refresh token\"\n}\n```\n\n## Get new token pair using refresh token\n\nTo get new token pair using existing refresh token use:\n\n```bash\ncurl -X POST -d refresh_token=REFRESH_TOKEN_HERE -d grant_type=refresh_token client:secret@localhost:9090/oauth/token\n```\n\nFor our case it should be:\n\n```bash\ncurl -X POST -d refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImF0aSI6IjIxODEwZWUxLWI5MGQtNDQ4My1hYTE1LTJlNjZkOTc4MjhlZSIsImV4cCI6MTU4NzczNDkyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6ImFmOTk4NzNlLTVkMzItNDk1MS04YWFmLWFjN2VjYmViZjE4YiIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.pwDQPzq_pMzOMb5f_0GcZWo_mcd2ncT4oI-qbneOI_Y -d grant_type=refresh_token entitlements:ott@localhost:9090/oauth/token\n```\n\nYou'll receive a response similar to below\n\n```json\n{\n  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImV4cCI6MTU4NTIyOTY5MywiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjRkMmNmNWIwLWNkZTYtNDgyNS05NWExLTc1MTVkNWM5OTM3OCIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.XqP3T4hrROecgNqHIAgL1sBUhraN-I6pM3q0rbJjSus\",\n  \"token_type\": \"bearer\",\n  \"refresh_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImF0aSI6IjRkMmNmNWIwLWNkZTYtNDgyNS05NWExLTc1MTVkNWM5OTM3OCIsImV4cCI6MTU4NzczNDkyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6ImFmOTk4NzNlLTVkMzItNDk1MS04YWFmLWFjN2VjYmViZjE4YiIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.XNjkVBwrldmX16ziIgdIZNGGcdrLPoLxkf4YWXxX1xU\",\n  \"expires_in\": 86399,\n  \"scope\": \"read\",\n  \"non_pii_id\": \"2f8-4da\",\n  \"jti\": \"4d2cf5b0-cde6-4825-95a1-7515d5c99378\"\n}\n```\n\n## Use tokens to access resources through your REST-ful API\n\nUse the generated token as the value of the Bearer in the Authorization header as follows:\n\n```bash\ncurl http://localhost:9091/YOUR_RESOURCE_PATH -H \"Authorization: Bearer ACCESS_TOKEN_HERE\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrei-punko%2Foauth-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrei-punko%2Foauth-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrei-punko%2Foauth-server/lists"}