{"id":15044756,"url":"https://github.com/giannivh/oauth-desktop","last_synced_at":"2026-02-14T14:31:00.975Z","repository":{"id":74112073,"uuid":"497643031","full_name":"giannivh/oauth-desktop","owner":"giannivh","description":"Open source OAuth2 desktop library for Java.","archived":false,"fork":false,"pushed_at":"2022-06-11T09:53:36.000Z","size":66,"stargazers_count":2,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-05T05:49:59.717Z","etag":null,"topics":["java","java-11","java-module","java11","oauth","oauth-client","oauth2","oauth2-client"],"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/giannivh.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}},"created_at":"2022-05-29T16:17:48.000Z","updated_at":"2024-04-16T23:40:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"bf2cd7f0-d879-4a8a-8b73-f4f2e3bcbcf9","html_url":"https://github.com/giannivh/oauth-desktop","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/giannivh/oauth-desktop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giannivh%2Foauth-desktop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giannivh%2Foauth-desktop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giannivh%2Foauth-desktop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giannivh%2Foauth-desktop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giannivh","download_url":"https://codeload.github.com/giannivh/oauth-desktop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giannivh%2Foauth-desktop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29447184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T14:10:32.461Z","status":"ssl_error","status_checked_at":"2026-02-14T14:09:49.945Z","response_time":53,"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":["java","java-11","java-module","java11","oauth","oauth-client","oauth2","oauth2-client"],"created_at":"2024-09-24T20:50:59.813Z","updated_at":"2026-02-14T14:31:00.961Z","avatar_url":"https://github.com/giannivh.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OAuth2 Desktop Library\n\nOpen source OAuth2 desktop library for Java.\n\nThis library allows you to:\n* Start an authorization code flow with PKCE, using the system's browser\n* Get user info by access token\n* Exchange a refresh token into new tokens\n\n## Motivation\n\nWe had to write a native modular desktop application in Java where the user had to log in using Keycloak.\n\nWe were using the Keycloak Installed adapter, and that worked up until Keycloak version 16. The adapter redirected back \nto `/delegated` but that endpoint got removed in version 16. They didn't update the adapter. Our users would see a `404` \nafter successfully logging in. That caused confusion.\n\nAlso, we had to hack modularity in the Keycloak Installed adapter, as it is not modular. Next to that, the adapter \npulled in a lot of heavy dependencies like Undertow, JBoss RESTEasy, and whatnot. It also relied on Java EE, which has been deprecated \nsince Java 9. Generating a jlink image was a pain.\n\nWe had to replace the Keycloak Installed adapter with something else, but what was available to use was either \ndiscontinued, not modular, or bloatware pulling in a lot of dependencies.\n\nFor our little needs, we decided it's better to write our own library with the following requirements:\n* It has to be lightweight\n* It needs to support Java modularity\n* It should rely on as little as possible third-party dependencies\n* It needs to be easy to use\n              \n## Support\n\nThis has only been tested using Keycloak as an authorization server.\n\n## Quickstart\n            \n### Dependency\n\nIf you are using Maven, add this to your pom.xml file:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.giannivanhoecke.oauth\u003c/groupId\u003e\n  \u003cartifactId\u003eoauth-desktop\u003c/artifactId\u003e\n  \u003cversion\u003e1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nIf you are using Gradle, add this to your dependencies:\n\n```groovy\nimplementation 'com.giannivanhoecke.oauth:oauth-desktop:1.0'\n```\n\n### Java module\n\nIn your `module-info.java`, add:\n\n```java\nrequires com.giannivanhoecke.oauth.desktop;\n```\n\n## Usage\n         \n### Configuration\n\nStart by configuring your authorization server using the default configuration:\n\n```java\nAuthorizationServerConfig config = AuthorizationServerConfig\n        .newBuilder()\n        .withBaseUrl(\"http://localhost:8082/auth/realms/test/protocol/openid-connect\")\n        .withClientId(\"myclient\")\n        .build();\n```\n\nThis will show a built-in HTML success page after authorization.\n\nAlternatively, you can override the `auth`, `userinfo`, and `token` endpoints, as well as the `scope`:\n\n```java\nAuthorizationServerConfig config = AuthorizationServerConfig\n        .newBuilder()\n        .withBaseUrl(\"http://localhost:8082/auth/realms/test/protocol/openid-connect\")\n        .withEndpointAuth(\"/auth\")\n        .withEndpointUserInfo(\"/userinfo\")\n        .withEndpointToken(\"/token\")\n        .withClientId(\"myclient\")\n        .withAuthScope(\"openid offline_access email profile\")\n        .withSuccessRedirectUri(\"http://localhost/success.html\")\n        .build();\n```\n\nThe optional `.withSuccessRedirectUri(\"http://localhost/success.html\")` will redirect to your page of choice instead of showing\nthe built-in HTML success page.\n     \n### Instantiate\n\nNext, instantiate using the system's default browser:\n\n```java\nauthorizationCodeFlowWithPkce = new AuthorizationCodeFlowWithPkce(config);\n```\n\nAlternatively, you can supply your own `Browser` implementation, if the native Java `Desktop` isn't suitable for your use case:\n\n```java\nauthorizationCodeFlowWithPkce = new AuthorizationCodeFlowWithPkce(config, this::open);\n```\n\n### Authorize\n\nTo start the authorization flow using PKCE:\n\n```java\nFuture\u003cAccessTokenResponse\u003e accessTokenResponseFuture = authorizationCodeFlowWithPkce.authorize();\nAccessTokenResponse accessTokenResponse = accessTokenResponseFuture.get(5, TimeUnit.MINUTES);\n\nLOGGER.info(\"Success! I got:\");\nLOGGER.info(\"  -\u003e access token:  \" + accessTokenResponse.getAccessToken());\nLOGGER.info(\"  -\u003e refresh token: \" + accessTokenResponse.getRefreshToken());\n```\n\nYou will get a `Future\u003cAccessTokenResponse\u003e` instance, as we need to wait on an external action (the user authorizing in the browser).\n\n### Exchange refresh token\n           \nIn order to exchange a refresh token for new tokens:\n\n```java\nAccessTokenResponse accessTokenResponse = authorizationCodeFlowWithPkce.refresh(refreshToken);\n\nLOGGER.info(\"Success! I got:\");\nLOGGER.info(\"  -\u003e access token:  \" + accessTokenResponse.getAccessToken());\nLOGGER.info(\"  -\u003e refresh token: \" + accessTokenResponse.getRefreshToken());\n```\n\n### Get user info\n\nIf you want retrieve some basic user info, or if you just want to test if your access token is still valid:\n\n```java\nUserInfoResponse userInfoResponse = authorizationCodeFlowWithPkce.getUserInfo(accessToken);\n\nLOGGER.info(\"Success! I got:\");\nLOGGER.info(\"  -\u003e ID:       \" + userInfoResponse.getId());\nLOGGER.info(\"  -\u003e Username: \" + userInfoResponse.getUsername());\nLOGGER.info(\"  -\u003e Name:     \" + userInfoResponse.getName());\nLOGGER.info(\"  -\u003e Email:    \" + userInfoResponse.getEmail());\n```\n\n### Exceptions   \n\nThe OAuth2 Desktop Library throws unchecked exceptions. Check the JavaDocs for each method.\nIf you want to catch all at once, it suffices to catch `OAuth2Exception` for any method.\n\n## License\n\nMIT license - See [LICENSE](LICENSE) for more information.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiannivh%2Foauth-desktop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiannivh%2Foauth-desktop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiannivh%2Foauth-desktop/lists"}