{"id":26412654,"url":"https://github.com/7mza/authumn","last_synced_at":"2026-04-18T06:35:16.554Z","repository":{"id":257939202,"uuid":"873727437","full_name":"7mza/authumn","owner":"7mza","description":"lightweight oauth2 authorization server, based on Spring Authorization Server","archived":false,"fork":false,"pushed_at":"2024-10-20T21:04:06.000Z","size":274,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-21T14:13:26.856Z","etag":null,"topics":["java","kotlin","oauth2","spring-authorization-server","spring-boot","spring-security"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/7mza.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":"2024-10-16T16:05:27.000Z","updated_at":"2024-10-19T18:39:26.000Z","dependencies_parsed_at":"2024-10-31T00:34:35.296Z","dependency_job_id":null,"html_url":"https://github.com/7mza/authumn","commit_stats":null,"previous_names":["7mza/authumn"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7mza%2Fauthumn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7mza%2Fauthumn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7mza%2Fauthumn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7mza%2Fauthumn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/7mza","download_url":"https://codeload.github.com/7mza/authumn/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244117652,"owners_count":20400743,"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":["java","kotlin","oauth2","spring-authorization-server","spring-boot","spring-security"],"created_at":"2025-03-17T22:08:23.454Z","updated_at":"2026-04-18T06:35:11.526Z","avatar_url":"https://github.com/7mza.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Build Status](https://github.com/7mza/authumn/actions/workflows/build.yml/badge.svg) ![Coverage](https://github.com/7mza/authumn/blob/badges/jacoco.svg)\n\n# ![](./authumn.png) authumn\n\nlightweight oauth2 authorization server, based\non [Spring Authorization Server](https://github.com/spring-projects/spring-authorization-server)\n\nstill in early stages but the purpose is to provide a generic SSO server, that integrate seamlessly with spring\ncloud, can be extended with ease \u0026 supports:\n\n- rbac\n- persistence\n- horizontal scaling\n- key management\n- dynamic oauth2-client creation\n\n### how to use\n\n#### oauth-resource server\n\ncan be configured easily (0 code) using [ch4mpy/spring-addons](https://github.com/ch4mpy/spring-addons/)\n\n```yaml\ncom:\n  c4-soft:\n    springaddons:\n      oidc:\n        ops:\n          - iss: http://${authum.host}:${authumn.port}\n            authorities:\n              # this will allow you to map any claim in access token to GrantedAuthorities\n              # that can be used following SPEL @*Authorize(\"hasAuthority('role')\")\n              - path: $.scope\n                #caze: upper\n                #prefix: AUTH_\n              - path: $.roles\n        resourceserver:\n          permit-all:\n            - /actuator/health\n            - ...\n```\n\n#### oauth2-client app\n\ncan also be configured using spring-addons or using sboot + yml if you need more ctrl\n\n```kotlin\n// this is for webflux, adapt it if using servlet\n\n@Bean\nfun tokenSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {\n    http\n        .securityMatcher(PathPatternParserServerWebExchangeMatcher(\"/oauth2/token\", HttpMethod.POST))\n        .authorizeExchange { it.anyExchange().permitAll() }\n        .csrf { it.disable() } // if you need to use client credentials flow for testing or M2M\n    return http.build()\n}\n\n@Bean\nfun defaultSecurityFilterChain(\n    http: ServerHttpSecurity,\n    @Value(\"\\${spring.security.permit-all}\") permitAll: Array\u003cString\u003e,\n    @Value(\"\\${spring.security.permit-origins}\") origins: Array\u003cString\u003e,\n): SecurityWebFilterChain {\n    http\n        .authorizeExchange {\n            it\n                .pathMatchers(*permitAll)\n                .permitAll()\n                .anyExchange()\n                .authenticated()\n        }\n        .oauth2ResourceServer { it.jwt(Customizer.withDefaults()) } // if your client is also a gateway that need to forward tokens\n        .oauth2Client(Customizer.withDefaults())\n        .oauth2Login(Customizer.withDefaults()) // if you want your client to use auth server html\n        .csrf { it.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse()) }\n        .cors { it.configurationSource(urlBasedCorsConfigurationSource(origins)) }\n    // .requestCache { it.disable() }\n    return http.build()\n}\n\nfun urlBasedCorsConfigurationSource(origins: Array\u003cString\u003e): UrlBasedCorsConfigurationSource =\n    UrlBasedCorsConfigurationSource().apply {\n        registerCorsConfiguration(\n            \"/**\",\n            CorsConfiguration().apply {\n                allowedOriginPatterns = origins.asList()\n                setAllowedMethods(listOf(\"*\"))\n                allowedHeaders = listOf(\"*\")\n                exposedHeaders = listOf(\"*\")\n            },\n        )\n    }\n```\n\n```yaml\n# your own clients\n\nspring:\n  security:\n    oauth2:\n      client:\n        provider:\n          spring:\n            issuer-uri: http://${authumn.host}:${authumn.port}\n        registration:\n          client-credentials:\n            authorization-grant-type: client_credentials\n            client-id: client-credentials\n            client-name: client-credentials\n            client-secret: secret\n            provider: spring\n            scope: role1, role2, ...\n          client-authorization:\n            authorization-grant-type: authorization_code\n            client-authentication-method: client_secret_post\n            client-id: client-authorization\n            client-name: client-authorization\n            client-secret: secret\n            provider: spring\n            redirect-uri: \"{baseUrl}/login/oauth2/code/{registrationId}\"\n            scope: openid, profile, ...\n      resourceserver:\n        jwt:\n          issuer-uri: http://${authumn.host}:${authumn.port}\n    permit-all: /actuator/health, ...\n    permit-origins: \"*\"\n```\n\n### how to h scale\n\nif using oauth2Login in your client apps, authorization flow happens via user-agent redirection, auth-server need to be\nexposed. you can hide your instances behind a gateway or a lb like [haproxy example](./haproxy/authumn/haproxy.cfg) \u0026\njust\nscale using\ndocker\n\n```shell\ndocker compose up --scale authumn=N --build\n```\n\nthen have your resource servers and oauth client apps point to the lb\n\n### TODO\n\n- htmx/thymeleaf crud\n- account creation validation by email\n- pwd validation\n- email \u0026 pwd change flow\n- paging \u0026 sorting\n- search \u0026 filter\n- caching\n- redis/postgres replication\n- move to coroutines\n- simple ldap integration\n-\n\n### build\n\n```shell\n./gradlew clean ktlintFormat ktlintCheck build\n```\n\n### run\n\n```shell\ndocker compose up --build\n```\n\ninit data is configured in [application.yml](./src/main/resources/application.yml), will populate db if run with\nprofile \"init\"\n\nadd `-Dspring.profiles.active=default,dev,init` if run with IDE\n\nprofile \"dev\" will empty DB on shutdown\n\n### generate \u0026 use a (client credentials) token\n\n```shell\n# apt install curl jq\nTOKEN=$(curl -k \"http://127.0.0.1:9000/oauth2/token\" \\\n-H \"Content-Type: application/x-www-form-urlencoded\" \\\n-d \"grant_type=client_credentials\" \\\n-d \"client_id=client-credentials\" \\\n-d \"client_secret=secret2\" \\\n-d \"scope=admin user\" \\\n-s | jq .access_token -r)\n\ncurl -k \"http://127.0.0.1:9000/api/user\" \\\n-H \"Accept: application/json\" -H \"authorization: Bearer $TOKEN\"\n```\n\nauthorization code flow is browser based, it can also be tested\nusing [ClientAuthorizationTokenTest.kt](src/test/kotlin/com/authumn/authumn/tokens/ClientAuthorizationTokenTest.kt)\n\n### decode token\n\n```shell\n# apt install jq\nHEADER=$(echo $TOKEN | cut -d '.' -f 1)\nPAYLOAD=$(echo $TOKEN | cut -d '.' -f 2)\necho $HEADER | sed 's/-/+/g; s/_/\\//g' | base64 -d | jq\necho $PAYLOAD | sed 's/-/+/g; s/_/\\//g' | base64 -d | jq\n```\n\n### introspect token\n\n```shell\n# apt install jq\ncurl -k \"http://127.0.0.1:9000/oauth2/introspect\" \\\n-H \"Content-Type: application/x-www-form-urlencoded\" \\\n-H \"Accept: application/json\" \\\n-d \"token=$TOKEN\" \\\n-d \"client_id=client-credentials\" \\\n-d \"client_secret=secret2\" \\\n-s | jq\n```\n\n### revoke token\n\n```shell\n# apt install jq\ncurl -k \"http://127.0.0.1:9000/oauth2/revoke\" \\\n-H \"Content-Type: application/x-www-form-urlencoded\" \\\n-d \"token=$TOKEN\" \\\n-d \"token_type_hint=access_token\" \\\n-d \"client_id=client-credentials\" \\\n-d \"client_secret=secret2\" \\\n-s\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F7mza%2Fauthumn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F7mza%2Fauthumn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F7mza%2Fauthumn/lists"}