├── .dockerignore ├── .github └── workflows │ └── docker-image.yml ├── .gitignore ├── .pre-commit-config.yaml ├── Dockerfile ├── LICENSE ├── Makefile ├── Pipfile ├── Pipfile.lock ├── README.md ├── db └── .gitkeep ├── docker-demo ├── .env ├── Makefile ├── docker-compose.yml └── nginx │ └── default.conf ├── manage.py ├── oidc_server ├── __init__.py ├── oidc_provider_settings.py ├── settings.py ├── templates │ ├── base.html │ ├── home.html │ ├── login.html │ └── oidc_provider │ │ ├── authorize.html │ │ └── error.html ├── urls.py └── wsgi.py ├── pyproject.toml ├── screenshot ├── client.png └── user.png └── setup.cfg /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .github 3 | static_root 4 | docker-demo 5 | screenshot 6 | db/db.sqlite3 7 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image Build 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - 17 | name: Set up QEMU 18 | uses: docker/setup-qemu-action@v1 19 | - 20 | name: Set up Docker Buildx 21 | uses: docker/setup-buildx-action@v1 22 | - 23 | name: Login to DockerHub 24 | uses: docker/login-action@v1 25 | with: 26 | username: ${{ secrets.DOCKERHUB_USERNAME }} 27 | password: ${{ secrets.DOCKERHUB_TOKEN }} 28 | - 29 | name: Build and push 30 | uses: docker/build-push-action@v2 31 | with: 32 | push: true 33 | platforms: linux/amd64,linux/arm64 34 | tags: vicalloy/oidc-server:latest 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | db/db.sqlite3 2 | static_root 3 | docker-demo/data/ 4 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | exclude: ^(coverage_html/) 2 | repos: 3 | - repo: git://github.com/pre-commit/pre-commit-hooks 4 | rev: v3.4.0 5 | hooks: 6 | - id: check-case-conflict 7 | - id: check-merge-conflict 8 | - id: check-symlinks 9 | - id: check-xml 10 | - id: check-yaml 11 | - id: detect-private-key 12 | - id: trailing-whitespace 13 | - id: debug-statements 14 | - id: end-of-file-fixer 15 | - repo: https://github.com/pycqa/isort 16 | rev: 5.10.1 17 | hooks: 18 | - id: isort 19 | name: isort (python) 20 | - repo: https://github.com/ambv/black 21 | rev: 22.1.0 22 | hooks: 23 | - id: black 24 | language_version: python3.8 25 | - repo: https://gitlab.com/pycqa/flake8 26 | rev: 3.9.0 27 | hooks: 28 | - id: flake8 29 | additional_dependencies: 30 | - flake8-bugbear 31 | - flake8-comprehensions 32 | - flake8-simplify 33 | - flake8-isort 34 | args: ['--config=setup.cfg'] 35 | types: [python] 36 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | pkg-config \ 5 | --no-install-recommends 6 | 7 | RUN pip install --upgrade pip setuptools pipenv gunicorn 8 | 9 | RUN mkdir /app 10 | WORKDIR /app 11 | 12 | COPY ./ ./ 13 | RUN pipenv install -d --skip-lock --system 14 | 15 | EXPOSE 8000 16 | CMD ["make", "run"] 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 vicalloy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | run: 2 | python manage.py collectstatic --noinput 3 | python manage.py migrate 4 | gunicorn oidc_server.wsgi:application -w 2 -b :8000 5 | 6 | run-dev: 7 | python manage.py runserver 0.0.0.0:8000 8 | 9 | init: 10 | python manage.py creatersakey 11 | python manage.py createsuperuser 12 | 13 | init-pre-commit: 14 | pre-commit install 15 | pre-commit run --all-files 16 | 17 | black: 18 | black ./ 19 | 20 | isort: 21 | isort ./ 22 | 23 | build_docker_image: 24 | docker build -t vicalloy/oidc-server . 25 | 26 | run_docker_container: 27 | docker run -d -p 8000:8000 --rm --name oidc-server vicalloy/oidc-server 28 | 29 | docker-pull: 30 | docker pull vicalloy/oidc-server 31 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | # url = "https://pypi.python.org/simple" 3 | url = "https://mirrors.aliyun.com/pypi/simple/" 4 | verify_ssl = true 5 | name = "pypi" 6 | 7 | [packages] 8 | django = "<3.0" 9 | django-oidc-provider = {editable = true, ref = "develop", git = "https://github.com/juanifioren/django-oidc-provider.git"} 10 | 11 | [dev-packages] 12 | pre-commit = "*" 13 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "4afc6bf653e8b1b57106c8d06181f279eed2090efcb22d112e2beee1dcbb716f" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": {}, 8 | "sources": [ 9 | { 10 | "name": "pypi", 11 | "url": "https://mirrors.aliyun.com/pypi/simple/", 12 | "verify_ssl": true 13 | } 14 | ] 15 | }, 16 | "default": { 17 | "certifi": { 18 | "hashes": [ 19 | "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", 20 | "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" 21 | ], 22 | "version": "==2021.10.8" 23 | }, 24 | "charset-normalizer": { 25 | "hashes": [ 26 | "sha256:2842d8f5e82a1f6aa437380934d5e1cd4fcf2003b06fed6940769c164a480a45", 27 | "sha256:98398a9d69ee80548c762ba991a4728bfc3836768ed226b3945908d1a688371c" 28 | ], 29 | "markers": "python_version >= '3'", 30 | "version": "==2.0.11" 31 | }, 32 | "django": { 33 | "hashes": [ 34 | "sha256:1ee37046b0bf2b61e83b3a01d067323516ec3b6f2b17cd49b1326dd4ba9dc913", 35 | "sha256:90763c764738586b11d7e1f44828032c153366e43ad7f782908193a1bb2d6d92" 36 | ], 37 | "index": "pypi", 38 | "version": "==2.2.27" 39 | }, 40 | "django-oidc-provider": { 41 | "editable": true, 42 | "git": "https://github.com/juanifioren/django-oidc-provider.git", 43 | "ref": "2c4983d524dcc4296312a0a86dc9cf3772bde214" 44 | }, 45 | "future": { 46 | "hashes": [ 47 | "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" 48 | ], 49 | "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", 50 | "version": "==0.18.2" 51 | }, 52 | "idna": { 53 | "hashes": [ 54 | "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", 55 | "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" 56 | ], 57 | "markers": "python_version >= '3'", 58 | "version": "==3.3" 59 | }, 60 | "pycryptodomex": { 61 | "hashes": [ 62 | "sha256:1ca8e1b4c62038bb2da55451385246f51f412c5f5eabd64812c01766a5989b4a", 63 | "sha256:298c00ea41a81a491d5b244d295d18369e5aac4b61b77b2de5b249ca61cd6659", 64 | "sha256:2aa887683eee493e015545bd69d3d21ac8d5ad582674ec98f4af84511e353e45", 65 | "sha256:2ce76ed0081fd6ac8c74edc75b9d14eca2064173af79843c24fa62573263c1f2", 66 | "sha256:3da13c2535b7aea94cc2a6d1b1b37746814c74b6e80790daddd55ca5c120a489", 67 | "sha256:406ec8cfe0c098fadb18d597dc2ee6de4428d640c0ccafa453f3d9b2e58d29e2", 68 | "sha256:4d0db8df9ffae36f416897ad184608d9d7a8c2b46c4612c6bc759b26c073f750", 69 | "sha256:530756d2faa40af4c1f74123e1d889bd07feae45bac2fd32f259a35f7aa74151", 70 | "sha256:77931df40bb5ce5e13f4de2bfc982b2ddc0198971fbd947776c8bb5050896eb2", 71 | "sha256:797a36bd1f69df9e2798e33edb4bd04e5a30478efc08f9428c087f17f65a7045", 72 | "sha256:8085bd0ad2034352eee4d4f3e2da985c2749cb7344b939f4d95ead38c2520859", 73 | "sha256:8536bc08d130cae6dcba1ea689f2913dfd332d06113904d171f2f56da6228e89", 74 | "sha256:a4d412eba5679ede84b41dbe48b1bed8f33131ab9db06c238a235334733acc5e", 75 | "sha256:aebecde2adc4a6847094d3bd6a8a9538ef3438a5ea84ac1983fcb167db614461", 76 | "sha256:b276cc4deb4a80f9dfd47a41ebb464b1fe91efd8b1b8620cf5ccf8b824b850d6", 77 | "sha256:b5a185ae79f899b01ca49f365bdf15a45d78d9856f09b0de1a41b92afce1a07f", 78 | "sha256:c4d8977ccda886d88dc3ca789de2f1adc714df912ff3934b3d0a3f3d777deafb", 79 | "sha256:c5dd3ffa663c982d7f1be9eb494a8924f6d40e2e2f7d1d27384cfab1b2ac0662", 80 | "sha256:ca88f2f7020002638276439a01ffbb0355634907d1aa5ca91f3dc0c2e44e8f3b", 81 | "sha256:d2cce1c82a7845d7e2e8a0956c6b7ed3f1661c9acf18eb120fc71e098ab5c6fe", 82 | "sha256:d709572d64825d8d59ea112e11cc7faf6007f294e9951324b7574af4251e4de8", 83 | "sha256:da8db8374295fb532b4b0c467e66800ef17d100e4d5faa2bbbd6df35502da125", 84 | "sha256:e36c7e3b5382cd5669cf199c4a04a0279a43b2a3bdd77627e9b89778ac9ec08c", 85 | "sha256:e95a4a6c54d27a84a4624d2af8bb9ee178111604653194ca6880c98dcad92f48", 86 | "sha256:ee835def05622e0c8b1435a906491760a43d0c462f065ec9143ec4b8d79f8bff", 87 | "sha256:f75009715dcf4a3d680c2338ab19dac5498f8121173a929872950f4fb3a48fbf", 88 | "sha256:f8524b8bc89470cec7ac51734907818d3620fb1637f8f8b542d650ebec42a126" 89 | ], 90 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", 91 | "version": "==3.14.1" 92 | }, 93 | "pyjwkest": { 94 | "hashes": [ 95 | "sha256:5560fd5ba08655f29ff6ad1df1e15dc05abc9d976fcbcec8d2b5167f49b70222" 96 | ], 97 | "version": "==1.4.2" 98 | }, 99 | "pytz": { 100 | "hashes": [ 101 | "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c", 102 | "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326" 103 | ], 104 | "version": "==2021.3" 105 | }, 106 | "requests": { 107 | "hashes": [ 108 | "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", 109 | "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" 110 | ], 111 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", 112 | "version": "==2.27.1" 113 | }, 114 | "six": { 115 | "hashes": [ 116 | "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", 117 | "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" 118 | ], 119 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 120 | "version": "==1.16.0" 121 | }, 122 | "sqlparse": { 123 | "hashes": [ 124 | "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae", 125 | "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d" 126 | ], 127 | "markers": "python_version >= '3.5'", 128 | "version": "==0.4.2" 129 | }, 130 | "urllib3": { 131 | "hashes": [ 132 | "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed", 133 | "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c" 134 | ], 135 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", 136 | "version": "==1.26.8" 137 | } 138 | }, 139 | "develop": { 140 | "cfgv": { 141 | "hashes": [ 142 | "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426", 143 | "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736" 144 | ], 145 | "markers": "python_full_version >= '3.6.1'", 146 | "version": "==3.3.1" 147 | }, 148 | "distlib": { 149 | "hashes": [ 150 | "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b", 151 | "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579" 152 | ], 153 | "version": "==0.3.4" 154 | }, 155 | "filelock": { 156 | "hashes": [ 157 | "sha256:38b4f4c989f9d06d44524df1b24bd19e167d851f19b50bf3e3559952dddc5b80", 158 | "sha256:cf0fc6a2f8d26bd900f19bf33915ca70ba4dd8c56903eeb14e1e7a2fd7590146" 159 | ], 160 | "markers": "python_version >= '3.7'", 161 | "version": "==3.4.2" 162 | }, 163 | "identify": { 164 | "hashes": [ 165 | "sha256:bff7c4959d68510bc28b99d664b6a623e36c6eadc933f89a4e0a9ddff9b4fee4", 166 | "sha256:e926ae3b3dc142b6a7a9c65433eb14ccac751b724ee255f7c2ed3b5970d764fb" 167 | ], 168 | "markers": "python_version >= '3.7'", 169 | "version": "==2.4.9" 170 | }, 171 | "nodeenv": { 172 | "hashes": [ 173 | "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b", 174 | "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7" 175 | ], 176 | "version": "==1.6.0" 177 | }, 178 | "platformdirs": { 179 | "hashes": [ 180 | "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca", 181 | "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda" 182 | ], 183 | "markers": "python_version >= '3.7'", 184 | "version": "==2.4.1" 185 | }, 186 | "pre-commit": { 187 | "hashes": [ 188 | "sha256:725fa7459782d7bec5ead072810e47351de01709be838c2ce1726b9591dad616", 189 | "sha256:c1a8040ff15ad3d648c70cc3e55b93e4d2d5b687320955505587fd79bbaed06a" 190 | ], 191 | "index": "pypi", 192 | "version": "==2.17.0" 193 | }, 194 | "pyyaml": { 195 | "hashes": [ 196 | "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", 197 | "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", 198 | "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", 199 | "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", 200 | "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", 201 | "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", 202 | "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", 203 | "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", 204 | "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", 205 | "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", 206 | "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", 207 | "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", 208 | "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", 209 | "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", 210 | "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", 211 | "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", 212 | "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", 213 | "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", 214 | "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", 215 | "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", 216 | "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", 217 | "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", 218 | "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", 219 | "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", 220 | "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", 221 | "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", 222 | "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", 223 | "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", 224 | "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", 225 | "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", 226 | "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", 227 | "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", 228 | "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" 229 | ], 230 | "markers": "python_version >= '3.6'", 231 | "version": "==6.0" 232 | }, 233 | "six": { 234 | "hashes": [ 235 | "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", 236 | "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" 237 | ], 238 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 239 | "version": "==1.16.0" 240 | }, 241 | "toml": { 242 | "hashes": [ 243 | "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", 244 | "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" 245 | ], 246 | "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", 247 | "version": "==0.10.2" 248 | }, 249 | "virtualenv": { 250 | "hashes": [ 251 | "sha256:45e1d053cad4cd453181ae877c4ffc053546ae99e7dd049b9ff1d9be7491abf7", 252 | "sha256:e0621bcbf4160e4e1030f05065c8834b4e93f4fcc223255db2a823440aca9c14" 253 | ], 254 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", 255 | "version": "==20.13.1" 256 | } 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # oidc-server 2 | 3 | A self-hosted OIDC server. 4 | 5 | oidc-server heavily borrows from `django-oidc-provider/example`.😁 6 | 7 | ## run via docker-compose 8 | 9 | 1. start oidc server and config it. 10 | ``` 11 | cd docker-demo 12 | # all config is in .env 13 | make run 14 | make init # create a rsa key and a super user 15 | ``` 16 | 1. Open `http://127.0.0.1:8888/admin/` and add client. 17 | 1. The uri for client. 18 | ``` 19 | OIDC_AUTH_URI=http://localhost:8888/oauth/authorize/ 20 | OIDC_TOKEN_URI=http://localhost:8888/oauth/token/ 21 | OIDC_USERINFO_URI=http://localhost:8888/oauth/userinfo/ 22 | ``` 23 | 1. Open `http://127.0.0.1:8888/admin/auth/user/` to add user. 24 | 25 | ## screenshots 26 | 27 | 1. Add OIDC Client 28 |  29 | 1. Add new user 30 |  31 | -------------------------------------------------------------------------------- /db/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vicalloy/oidc-server/fbef282dc3c33f29e857d35fea05fc2a49b0a6d2/db/.gitkeep -------------------------------------------------------------------------------- /docker-demo/.env: -------------------------------------------------------------------------------- 1 | DEBUG=1 2 | LANGUAGE_CODE=en_US 3 | TIME_ZONE=UTC 4 | FORCE_SCRIPT_NAME= 5 | SECRET_KEY=e296a781609f4fbe227b67f38cdb510f87f496dae7b9f784ec5f2cc6ac657874c0a9e5a16d5c88b976613480e21acc40c9b9 6 | -------------------------------------------------------------------------------- /docker-demo/Makefile: -------------------------------------------------------------------------------- 1 | oidc_server_container=docker-demo_oidc-server_1 2 | 3 | run: 4 | docker-compose up -d 5 | 6 | down: 7 | docker-compose down 8 | 9 | stop: 10 | docker-compose stop 11 | 12 | init: 13 | docker exec -it ${oidc_server_container} bash -c "make init" 14 | 15 | clean-data: 16 | rm -rfv ./data 17 | 18 | update-images: 19 | docker pull vicalloy/oidc-server 20 | -------------------------------------------------------------------------------- /docker-demo/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | oidc-server: 4 | image: vicalloy/oidc-server 5 | volumes: 6 | - ./data/db:/app/db:z 7 | - ./data/static_root:/app/static_root:z 8 | restart: always 9 | nginx: 10 | image: nginx 11 | ports: 12 | - 8888:80 13 | volumes: 14 | - ./nginx/:/etc/nginx/conf.d/:ro 15 | - ./data/static_root:/static_root:ro 16 | restart: always 17 | -------------------------------------------------------------------------------- /docker-demo/nginx/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | client_max_body_size 100m; 4 | 5 | # Static file FOR OIDC Server 6 | location /static { 7 | alias /static_root; 8 | } 9 | 10 | # OIDC Server 11 | location / { 12 | proxy_pass http://oidc-server:8000; 13 | proxy_set_header X-Real-IP $remote_addr; 14 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 15 | proxy_set_header X-Forwarded-Proto $scheme; 16 | proxy_set_header Host $http_host; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oidc_server.settings") 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /oidc_server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vicalloy/oidc-server/fbef282dc3c33f29e857d35fea05fc2a49b0a6d2/oidc_server/__init__.py -------------------------------------------------------------------------------- /oidc_server/oidc_provider_settings.py: -------------------------------------------------------------------------------- 1 | def userinfo(claims, user): 2 | claims["name"] = user.username 3 | claims["preferred_username"] = user.username 4 | return claims 5 | -------------------------------------------------------------------------------- /oidc_server/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for oidc_server project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.2.27. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.2/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = os.environ.get( 24 | "SECRET_KEY", default="e46i&!jtggfvuvjojyl@ns@s&m5r_!hw$gnwrp2yh0%q3zezx-" 25 | ) 26 | 27 | # SECURITY WARNING: don't run with debug turned on in production! 28 | DEBUG = int(os.environ.get("DEBUG", default=1)) 29 | 30 | ALLOWED_HOSTS = ["*"] 31 | 32 | 33 | # Application definition 34 | 35 | INSTALLED_APPS = [ 36 | "django.contrib.admin", 37 | "django.contrib.auth", 38 | "django.contrib.contenttypes", 39 | "django.contrib.sessions", 40 | "django.contrib.messages", 41 | "django.contrib.staticfiles", 42 | "oidc_server", 43 | "oidc_provider", 44 | ] 45 | 46 | MIDDLEWARE = [ 47 | "django.middleware.security.SecurityMiddleware", 48 | "django.contrib.sessions.middleware.SessionMiddleware", 49 | "django.middleware.common.CommonMiddleware", 50 | "django.middleware.csrf.CsrfViewMiddleware", 51 | "django.contrib.auth.middleware.AuthenticationMiddleware", 52 | "django.contrib.messages.middleware.MessageMiddleware", 53 | "django.middleware.clickjacking.XFrameOptionsMiddleware", 54 | ] 55 | 56 | ROOT_URLCONF = "oidc_server.urls" 57 | 58 | TEMPLATES = [ 59 | { 60 | "BACKEND": "django.template.backends.django.DjangoTemplates", 61 | "DIRS": [], 62 | "APP_DIRS": True, 63 | "OPTIONS": { 64 | "context_processors": [ 65 | "django.template.context_processors.debug", 66 | "django.template.context_processors.request", 67 | "django.contrib.auth.context_processors.auth", 68 | "django.contrib.messages.context_processors.messages", 69 | ], 70 | }, 71 | }, 72 | ] 73 | 74 | WSGI_APPLICATION = "oidc_server.wsgi.application" 75 | 76 | 77 | # Database 78 | # https://docs.djangoproject.com/en/2.2/ref/settings/#databases 79 | 80 | DATABASES = { 81 | "default": { 82 | "ENGINE": "django.db.backends.sqlite3", 83 | "NAME": os.path.join(BASE_DIR, "db", "db.sqlite3"), 84 | } 85 | } 86 | 87 | 88 | # Password validation 89 | # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 90 | 91 | AUTH_PASSWORD_VALIDATORS = [ 92 | { 93 | "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", 94 | }, 95 | { 96 | "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", 97 | }, 98 | { 99 | "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", 100 | }, 101 | { 102 | "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", 103 | }, 104 | ] 105 | 106 | 107 | # Internationalization 108 | # https://docs.djangoproject.com/en/2.2/topics/i18n/ 109 | 110 | LANGUAGE_CODE = os.environ.get("LANGUAGE_CODE", default="en-us").replace( 111 | "_", "-" 112 | ) 113 | 114 | TIME_ZONE = os.environ.get("TIME_ZONE", default="UTC") 115 | 116 | USE_I18N = True 117 | 118 | USE_L10N = True 119 | 120 | USE_TZ = True 121 | 122 | OIDC_USERINFO = "oidc_server.oidc_provider_settings.userinfo" 123 | 124 | # Static files (CSS, JavaScript, Images) 125 | # https://docs.djangoproject.com/en/2.2/howto/static-files/ 126 | 127 | FORCE_SCRIPT_NAME = os.environ.get("FORCE_SCRIPT_NAME", default="") # /uc 128 | if FORCE_SCRIPT_NAME: 129 | USE_X_FORWARDED_HOST = True 130 | 131 | STATIC_URL = FORCE_SCRIPT_NAME + "/static/" 132 | STATIC_ROOT = os.path.join(BASE_DIR, "static_root") 133 | LOGIN_URL = FORCE_SCRIPT_NAME + "/accounts/login/" 134 | -------------------------------------------------------------------------------- /oidc_server/templates/base.html: -------------------------------------------------------------------------------- 1 | {% load i18n staticfiles %} 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 |