From cda99c5c03e34459ce8c365d077b1e54ed8ec2c2 Mon Sep 17 00:00:00 2001 From: jkuensem <jkuensem@physik.uni-bielefeld.de> Date: Mon, 20 Jan 2020 11:47:29 +0100 Subject: [PATCH] TMSS-134: Adapt TMSS to use a local OpenID Connect identity provider, add pyop example code --- SAS/TMSS/src/tmss/settings.py | 65 +- SAS/TMSS/src/tmss/urls.py | 2 +- SAS/TMSS/test/oidc/create-keycloak-user.sh | 9 + SAS/TMSS/test/oidc/example/README.md | 8 + SAS/TMSS/test/oidc/example/__init__.py | 0 .../__pycache__/__init__.cpython-34.pyc | Bin 0 -> 170 bytes .../example/__pycache__/app.cpython-34.pyc | Bin 0 -> 2407 bytes .../example/__pycache__/views.cpython-34.pyc | Bin 0 -> 5088 bytes .../example/__pycache__/wsgi.cpython-34.pyc | Bin 0 -> 309 bytes SAS/TMSS/test/oidc/example/app.py | 60 + SAS/TMSS/test/oidc/example/application.cfg | 5 + SAS/TMSS/test/oidc/example/https.crt | 24 + SAS/TMSS/test/oidc/example/https.key | 27 + SAS/TMSS/test/oidc/example/requirements.txt | 3 + SAS/TMSS/test/oidc/example/signing_key.pem | 15 + .../test/oidc/example/templates/logout.jinja2 | 8 + SAS/TMSS/test/oidc/example/views.py | 124 ++ SAS/TMSS/test/oidc/example/wsgi.py | 7 + SAS/TMSS/test/oidc/realm-export.json | 1808 +++++++++++++++++ SAS/TMSS/test/oidc/tmss_keycloak_Dockerfile | 10 + 20 files changed, 2170 insertions(+), 5 deletions(-) create mode 100644 SAS/TMSS/test/oidc/create-keycloak-user.sh create mode 100644 SAS/TMSS/test/oidc/example/README.md create mode 100644 SAS/TMSS/test/oidc/example/__init__.py create mode 100644 SAS/TMSS/test/oidc/example/__pycache__/__init__.cpython-34.pyc create mode 100644 SAS/TMSS/test/oidc/example/__pycache__/app.cpython-34.pyc create mode 100644 SAS/TMSS/test/oidc/example/__pycache__/views.cpython-34.pyc create mode 100644 SAS/TMSS/test/oidc/example/__pycache__/wsgi.cpython-34.pyc create mode 100644 SAS/TMSS/test/oidc/example/app.py create mode 100644 SAS/TMSS/test/oidc/example/application.cfg create mode 100644 SAS/TMSS/test/oidc/example/https.crt create mode 100644 SAS/TMSS/test/oidc/example/https.key create mode 100644 SAS/TMSS/test/oidc/example/requirements.txt create mode 100644 SAS/TMSS/test/oidc/example/signing_key.pem create mode 100644 SAS/TMSS/test/oidc/example/templates/logout.jinja2 create mode 100644 SAS/TMSS/test/oidc/example/views.py create mode 100644 SAS/TMSS/test/oidc/example/wsgi.py create mode 100644 SAS/TMSS/test/oidc/realm-export.json create mode 100644 SAS/TMSS/test/oidc/tmss_keycloak_Dockerfile diff --git a/SAS/TMSS/src/tmss/settings.py b/SAS/TMSS/src/tmss/settings.py index 046f8de3590..2e90189375c 100644 --- a/SAS/TMSS/src/tmss/settings.py +++ b/SAS/TMSS/src/tmss/settings.py @@ -18,8 +18,54 @@ from lofar.common import dbcredentials # logger logger = logging.getLogger('django_auth_ldap') logger.addHandler(logging.StreamHandler()) -logger.setLevel(logging.INFO) - +logger.setLevel(logging.DEBUG) + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse', + }, + 'require_debug_true': { + '()': 'django.utils.log.RequireDebugTrue', + }, + }, + 'formatters': { + 'django.server': { + '()': 'django.utils.log.ServerFormatter', + 'format': '[%(server_time)s] %(message)s', + }, + }, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'filters': ['require_debug_true'], + 'class': 'logging.StreamHandler', + }, + 'django.server': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'django.server', + }, + 'mail_admins': { + 'level': 'ERROR', + 'filters': ['require_debug_false'], + 'class': 'django.utils.log.AdminEmailHandler' + }, + }, + 'loggers': { + 'django': { + 'handlers': ['console', 'mail_admins'], + 'level': 'DEBUG', + }, + 'django.server': { + 'handlers': ['django.server'], + 'level': 'DEBUG', + 'propagate': False, + }, + } +} # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -55,6 +101,7 @@ INSTALLED_APPS = [ 'jsoneditor', 'drf_yasg', 'django_filters', + 'mozilla_django_oidc', # Load after auth ] MIDDLEWARE = [ @@ -129,6 +176,7 @@ REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', + 'mozilla_django_oidc.contrib.drf.OIDCAuthentication', ), 'DEFAULT_PERMISSION_CLASSES': [ #'rest_framework.permissions.AllowAny', @@ -171,9 +219,18 @@ AUTH_LDAP_USER_ATTR_MAP = { "email": "mail" } +# OPEN-ID CONNECT + +OIDC_RP_CLIENT_ID = os.environ.get('OIDC_RP_CLIENT_ID', 'id') # Secret, do not put real credentials on Git +OIDC_RP_CLIENT_SECRET = os.environ.get('OIDC_RP_CLIENT_SECRET', 'secret') # Secret, do not put real credentials on Git +OIDC_OP_AUTHORIZATION_ENDPOINT = "https://localhost:9090/authentication" +OIDC_OP_TOKEN_ENDPOINT = "https://localhost:9090/token" +OIDC_OP_USER_ENDPOINT = "https://localhost:9090/userinfo" + AUTHENTICATION_BACKENDS = ( - 'django_auth_ldap.backend.LDAPBackend', - 'django.contrib.auth.backends.ModelBackend', + #'django_auth_ldap.backend.LDAPBackend', + #'django.contrib.auth.backends.ModelBackend', + 'mozilla_django_oidc.auth.OIDCAuthenticationBackend', ) # Password validation diff --git a/SAS/TMSS/src/tmss/urls.py b/SAS/TMSS/src/tmss/urls.py index c96864991dd..1bc27fb4b0f 100644 --- a/SAS/TMSS/src/tmss/urls.py +++ b/SAS/TMSS/src/tmss/urls.py @@ -145,4 +145,4 @@ router.register(r'task_blueprint_C', viewsets.TaskBlueprintViewSetJSONeditorOnli urlpatterns.extend(router.urls) # prefix everything for proxy -urlpatterns = [url(r'^api/', include(urlpatterns))] \ No newline at end of file +urlpatterns = [url(r'^api/', include(urlpatterns)), url(r'^oidc/', include('mozilla_django_oidc.urls')),] \ No newline at end of file diff --git a/SAS/TMSS/test/oidc/create-keycloak-user.sh b/SAS/TMSS/test/oidc/create-keycloak-user.sh new file mode 100644 index 00000000000..1ede32adf3d --- /dev/null +++ b/SAS/TMSS/test/oidc/create-keycloak-user.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +cd keycloak/bin +./kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password admin + +USERID=$(./kcadm.sh create users -r demo -s username=monitoring-user -s enabled=true -o --fields id | jq '.id' | tr -d '"') +echo $USERID +./kcadm.sh update users/$USERID/reset-password -r demo -s type=password -s value=default -s temporary=false -n +./kcadm.sh add-roles --uusername monitoring-user --rolename monitoring -r demo + diff --git a/SAS/TMSS/test/oidc/example/README.md b/SAS/TMSS/test/oidc/example/README.md new file mode 100644 index 00000000000..eaff811bdcd --- /dev/null +++ b/SAS/TMSS/test/oidc/example/README.md @@ -0,0 +1,8 @@ +# pyOP example application +To run the example application, execute the following commands: + +```bash +cd example/ +pip install -r requirements.txt # install the dependencies +gunicorn wsgi:app -b :9090 --certfile https.crt --keyfile https.key # run the application +``` \ No newline at end of file diff --git a/SAS/TMSS/test/oidc/example/__init__.py b/SAS/TMSS/test/oidc/example/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/SAS/TMSS/test/oidc/example/__pycache__/__init__.cpython-34.pyc b/SAS/TMSS/test/oidc/example/__pycache__/__init__.cpython-34.pyc new file mode 100644 index 0000000000000000000000000000000000000000..819d68a23dababb1257d69f3b39b35a9d08a0ef0 GIT binary patch literal 170 zcmaFI!^_opL@|y52p)q77+?f49Dul(1xTbYFa&Ed`mJOr0tq9CU*Y<>sVSL>`dQhf zsd>ezx%y_tsRjl{#^$=_mKJHcCWc9tx=Ch<X}YQA#-`>ehAGLZrk48U`9;}D`stY^ t`UREw1^THKiMa(isrvEpnR%Hd@$q^EmA5!-a`RJ4b5iX<78V0B0|4o)Dck@6 literal 0 HcmV?d00001 diff --git a/SAS/TMSS/test/oidc/example/__pycache__/app.cpython-34.pyc b/SAS/TMSS/test/oidc/example/__pycache__/app.cpython-34.pyc new file mode 100644 index 0000000000000000000000000000000000000000..004bd471eec2552f614d26573477e473b8be185d GIT binary patch literal 2407 zcmZ`)Npl-T6n-<KWwcp}o!D_!X9Gl)r7T1y6h+|#QVCElh#a8$K-XxxrL;X8-J>{C z$p<Ro%!wbt|KL~5l~XSK050&l<!zFn(Y$%@_3Q4p_1Ayb8`WR_yz<ku0`M1{_&Lab zj<5P13B$hy0YGR0vB1)@4S@}z1H_rj4g>`Vi$IDHmVlJz+5!Y+2wfoVTrNUTfv^gs zI+sfj)F7+_sn6vy1PurmfGnWw0;|9)0MZ0j1y%!Ahgax9ON;$><2AYlZ7VB23_P`q zOnEE=I*eu8&Pq@En_u%u=1S$!AodszFK&+0XR#DhFBNgrPra0**8Nt-&jsTW`74h+ z_3XZ<IO~rGJKRqnGajX4D7bv+`DrXCdcsr1rHF>HZ)pecSI4)3?*n|*_o$r#>;Sw3 z_{|3^wRHAgBE__|;a3}0_bt#`M{D<O!xs$i7`|xug5gVsFB-mV_>$pW!<XR)T=lyj z#RAN5!3y+dw$4s(=IDg=W(A$J-mD0$fu9nv1^kqOHKE5akEdXS_KPSi0Xq%s46tPw z;iMH*odvdP#?PT}9@qsVTtwj#jBvNh$gLUf3UXJ0U4!1f3#o15p9fcg6j!?rDSB{2 zyUgAL_CBV@-mgMhf>{-2IHe4!Yi3n|eE_Ryhkt>Itia16?AKsc!-{{nHC>7Y^J#KW zvW|!tfALz^VR|D!;$f|I?R-;g$|IJ<B1)&rd9$6pT}8*(6BqLOG~VUW@vO`F(eXhC z92;EA8%RD9DwS{SeKl`{K2gP$!e%^LC@Tr2#$1wR9l%ku9*?_+9%l=AAG1?$d6k`c zrytqrckN6{al#|PNEx#`6agnK<)cbbHBORPrkrI3KW2Q|&~!~OY8;qWjX39*azkrI zNzO{Hk~mVFrjz`7#h)=$JfuVEjY6!}3DXewII%TZ%;!VzLtGIif$&92&WxlNrEjiJ z+{6=dPbf}S)ciodWwPW40(Ztj_>!k|;3?sg8~M~yy*CXx7KEMfX`7t$15bpCCZ6<g zn9CEna(4M-+Eii`iD*Po=p;NOju(tb@k#&o-5xpJe|rC`FCT2v$6wG#oBc<$zxmDf z>wodru9BLUB-D?il)p%&Mq`N(4OvkaS;>M{6g4SpQqsgll9h1EP>kC3%)td@4RvJY zf6ju`xFt1k$puZCnzWFR)%hypg9g@MCqvWBq;}M0Y(Q!!!pq#lQ~3wTbGXVsPr4yz z!t3trjyYC8?Dp>Pn>TOY*;wDW_wjK3qg#V}>w}&*T<05i?ryMK%;$ISb@yVqJLrx? z+D#^L(&aBaEHdw6G@WFUEs98_G<S}4jOr64U^T2|tA6w>+KyGuJq>FKZ5mcpKTgv+ zZ&maRTVBA~TmB)Q>vZc38$6GZK|D_o$pH32gD;8*PYB|OxjQ!OAl4edvIK$_LL5S> zgNRr_sI`D1{vr6`O=oUKgnLU*D+3}mu3~B6GqbgAMf3f3d28ClfU&nt(mVceG_7xQ zm0~NcZDFfrg$OCBq^P61BC?8Z;^mabNBUgwJ=LyeE~R<`rP4+_xq^h$hB6LmGSO#U zE^AHEn9EC=Uz|e+w)7wv^8_!v)MQDn;%M8E7x5#{YNE|e!RO>Widi0IsVN!;)WtES zI}A*bTK0<FvKmg)mTRbMpCXl^zREkgb+x0UF_)k5Akl5F3qz`ifEacMKgZ{Qv~;(0 zbf-_L(pS4V6r^F)hn;Co3t2I`LqNc*|KN%@C+J|tVV9dzHxFF9cp^^S;?e}`eu`i< W4)|xfe@u8St7R=?Xy$S1*Z%_n)tFiU literal 0 HcmV?d00001 diff --git a/SAS/TMSS/test/oidc/example/__pycache__/views.cpython-34.pyc b/SAS/TMSS/test/oidc/example/__pycache__/views.cpython-34.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f4d528467e3f5573f883a850f931ff5a4c697dc GIT binary patch literal 5088 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 IGv&&E0WV^oFaQ7m literal 0 HcmV?d00001 diff --git a/SAS/TMSS/test/oidc/example/__pycache__/wsgi.cpython-34.pyc b/SAS/TMSS/test/oidc/example/__pycache__/wsgi.cpython-34.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d49e3aecb16e15abd0ed70fdceb8eb407a468ec GIT binary patch literal 309 zcmY+6Jx&8L5QWFyY!b*uqN1nVg7^XmAt0ioL1|pD+Qfr#Vy`W4en^RO6e{k)Dcn-g zZ~!Vs1R*h+d3rN?^L-Y>!{@h?`xgLsr}?Xl+yzZLCQ;N3EP&j54wixAAUQCVfy@9o zU<Nw|vI7V(&q3`?7k0oHeczS&2ch7$Wa-!&HLF7OYojn$rZLN^4nYq8-BWIHjkfHi zp7mOrM#}*{)h<{ZQ95#>rA|{jOd0KIFs)lNyYkJ0(J8+kUrugbAs$fbN4`$QqjxCg uixoC4I<fI_F%{Y@McDcve$isnYBLJk)IW1xtt_51BD8&yf*<iNE7&*8olx`u literal 0 HcmV?d00001 diff --git a/SAS/TMSS/test/oidc/example/app.py b/SAS/TMSS/test/oidc/example/app.py new file mode 100644 index 00000000000..806dc4cab84 --- /dev/null +++ b/SAS/TMSS/test/oidc/example/app.py @@ -0,0 +1,60 @@ +from flask.app import Flask +from flask.helpers import url_for +from jwkest.jwk import RSAKey, rsa_load + +from pyop.authz_state import AuthorizationState +from pyop.provider import Provider +from pyop.subject_identifier import HashBasedSubjectIdentifierFactory +from pyop.userinfo import Userinfo + + +def init_oidc_provider(app): + with app.app_context(): + issuer = url_for('oidc_provider.index')[:-1] + authentication_endpoint = url_for('oidc_provider.authentication_endpoint') + jwks_uri = url_for('oidc_provider.jwks_uri') + token_endpoint = url_for('oidc_provider.token_endpoint') + userinfo_endpoint = url_for('oidc_provider.userinfo_endpoint') + registration_endpoint = url_for('oidc_provider.registration_endpoint') + end_session_endpoint = url_for('oidc_provider.end_session_endpoint') + + configuration_information = { + 'issuer': issuer, + 'authorization_endpoint': authentication_endpoint, + 'jwks_uri': jwks_uri, + 'token_endpoint': token_endpoint, + 'userinfo_endpoint': userinfo_endpoint, + 'registration_endpoint': registration_endpoint, + 'end_session_endpoint': end_session_endpoint, + 'scopes_supported': ['openid', 'profile'], + 'response_types_supported': ['code', 'code id_token', 'code token', 'code id_token token'], # code and hybrid + 'response_modes_supported': ['query', 'fragment'], + 'grant_types_supported': ['authorization_code', 'implicit'], + 'subject_types_supported': ['pairwise'], + 'token_endpoint_auth_methods_supported': ['client_secret_basic'], + 'claims_parameter_supported': True + } + + userinfo_db = Userinfo(app.users) + signing_key = RSAKey(key=rsa_load('signing_key.pem'), alg='RS256') + provider = Provider(signing_key, configuration_information, + AuthorizationState(HashBasedSubjectIdentifierFactory(app.config['SUBJECT_ID_HASH_SALT'])), + {}, userinfo_db) + + return provider + + +def oidc_provider_init_app(name=None): + name = name or __name__ + app = Flask(name) + app.config.from_pyfile('application.cfg') + + app.users = {'test_user': {'name': 'Testing Name'}} + + from .views import oidc_provider_views + app.register_blueprint(oidc_provider_views) + + # Initialize the oidc_provider after views to be able to set correct urls + app.provider = init_oidc_provider(app) + + return app diff --git a/SAS/TMSS/test/oidc/example/application.cfg b/SAS/TMSS/test/oidc/example/application.cfg new file mode 100644 index 00000000000..36a1da67232 --- /dev/null +++ b/SAS/TMSS/test/oidc/example/application.cfg @@ -0,0 +1,5 @@ +SERVER_NAME = 'localhost:9090' +SECRET_KEY = 'secret_key' +SESSION_COOKIE_NAME='pyop_session' +SUBJECT_ID_HASH_SALT = 'salt' +PREFERRED_URL_SCHEME = 'https' \ No newline at end of file diff --git a/SAS/TMSS/test/oidc/example/https.crt b/SAS/TMSS/test/oidc/example/https.crt new file mode 100644 index 00000000000..20a202d8992 --- /dev/null +++ b/SAS/TMSS/test/oidc/example/https.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBjCCAu6gAwIBAgIJAIybVu7kfIK0MA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxGDAWBgNVBAMTD2xva2kuaXRzLnVtdS5zZTAeFw0xNTEy +MTAxNDQyMDFaFw0yNTEyMDcxNDQyMDFaMF8xCzAJBgNVBAYTAkFVMRMwEQYDVQQI +EwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQx +GDAWBgNVBAMTD2xva2kuaXRzLnVtdS5zZTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALiLDBwIteIobC+7JHoNeQRrTIbws9BghN4UUzyLo7+xeP9YwHaS +tq6HqYK4cVLyx8k06Siw/4PwqMPNj9/B4f/ZXhEkXgbBP5TP36UgKrUIk4zInRFb +Rjy+DcqjSZdgW1CKBKWJstXjSYen5rPm+voM/0msi164NPcfDMQIZmcQWh0MmEfG +qlvdwTvjdaAQt8p7CGsxIdu4gPfhubknbTQKu+BVq5/RCVP7VU830PSr1RYhthX8 +Gt8ir32jEdDdjIrfA/zFx6PChyLkQFXtg/9WymnIM1j2ngNreL2nppwnqMYRnI9i +C/y7MY4al3WeL9IETrtgh1jzXUNpgpJ03B0CAwEAAaOBxDCBwTAdBgNVHQ4EFgQU +cTNphzIIRpQBQ2VT0Vx9xQYzNN0wgZEGA1UdIwSBiTCBhoAUcTNphzIIRpQBQ2VT +0Vx9xQYzNN2hY6RhMF8xCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRl +MSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxGDAWBgNVBAMTD2xv +a2kuaXRzLnVtdS5zZYIJAIybVu7kfIK0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN +AQEFBQADggEBAJYJfUqOPTyZ+tflKoN4l+scIXpBxqtQbjX+MYli6VHpl+M8y163 +KsCglXPddL7Z58KBrUDx1m6f7dFQ3PMYn/S2dUcRrNOdfaDKZ5QgyYj/iVr8HSOh +6i1OtMFaBqW5WyqA5YgvUz63hZ2kDOBHZcEfSn2+roylBUiueV9gFNKDWneNMLo2 +PMZxcGWZ3wIQbu9ahakbJUvTigFStKeLoY1A2ZSTH7W4elB5DDxYOKZSzd/KZpfn +/o/Pc7YbbEUYgIyf3QNusdH+t2pw9ZkrlKMhiv9ZAmjAWMDY7O/i3r7u7AkODu7z +OHbH3rJqkbaiS8/q0cMZG6AMUzPRglzsTc4= +-----END CERTIFICATE----- diff --git a/SAS/TMSS/test/oidc/example/https.key b/SAS/TMSS/test/oidc/example/https.key new file mode 100644 index 00000000000..2abb725087f --- /dev/null +++ b/SAS/TMSS/test/oidc/example/https.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuIsMHAi14ihsL7skeg15BGtMhvCz0GCE3hRTPIujv7F4/1jA +dpK2roepgrhxUvLHyTTpKLD/g/Cow82P38Hh/9leESReBsE/lM/fpSAqtQiTjMid +EVtGPL4NyqNJl2BbUIoEpYmy1eNJh6fms+b6+gz/SayLXrg09x8MxAhmZxBaHQyY +R8aqW93BO+N1oBC3ynsIazEh27iA9+G5uSdtNAq74FWrn9EJU/tVTzfQ9KvVFiG2 +Ffwa3yKvfaMR0N2Mit8D/MXHo8KHIuRAVe2D/1bKacgzWPaeA2t4vaemnCeoxhGc +j2IL/LsxjhqXdZ4v0gROu2CHWPNdQ2mCknTcHQIDAQABAoIBAQCooAWUqDDqUl1o +z+voyt7FtvXaZ58mzMsb0h6suDwMMTKKwKI8tprOp4+wrrB+RvFfXUWftPwFp6XO +JMtOfm7vxcM6jqyMJ5DdfYSx8c6UVR3eCoHbFjf70P3xJ3tbIuTNlw/f4w7Sejj6 +B+W6hVjXm4C55TwEdPWQyYJ0rehESxITn7DDjDNXxxwDqwAv8yPTYf8m7mb7qh3V +EBnvZPIWpgEIVqV2crQSfHJwg29KhS7cnExJBYEPppBQ4aoUGyMqJN0EyBL4DrRo +Ds6hPttLaXEmB+ACm/OQzhEeFKduob5OIKRSyp9Z8t6/B9uHiIKCENRU4O4zux57 +jZ8MIypRAoGBAO0anHYHlniyP5f/8u4kvTnW3wbDtRJ3L3zVSKN8shQmQnjNWmsI +LhLWLU2OTRsXlJB7oYqNBojUBdeGimYot9kmjx4XkxELB6XAaYDG6pDvM7axC5qH +iuC4jVHdEsIfy9dP6wZ/b+A+JOWWpS1vdAizfvgWI32JLGDPkjjUlzNvAoGBAMdA +F5KZZLZFYsZM470/bb20qFMURDRI+5yz0VUHTNUQEr/xhMcYFske6ox14A7gXzwd +SHAvTDkV8DsGu/FzSWzZmVhNc1EtdM3Cbe3Y7WJoIQoupuxBDEvrBE9riyOjW61q +dYIO2ymfJfc2Vx6d7LAK9itXdqa3RIo7ZPK7EbMzAoGAAR1C5vsaJe8QhXJafewG +R6NO4QVCcJfGzVtjQAFyBM45OcAdUKt1K/l9tQOaMSpnNFagZ7pJ8ZKthFnJhLlk +Q8z+lzGdK1NV8d15oXVN3OiC4bTrTQqeCHhVkbDsSaVEm/pwLFOk/vTLz5hpplED +xpaxXhEckZZ3cu0GzuWQ4FkCgYAb34tspqjAFtTKiNcTElx3vV4OwTcJWWxZb45J +JsxIwgbdcxvv/h6x4/FL1PGTIzAvaKlJiFRRaBBDMZ35GPeckpQxFiSbppBAeIKI +U2Bh888rbXtMcY0W0bm4ooLEaYXZrJrjptBh8jGNc7ycO9twhRgK2CFxERI1hDmK ++0BuoQKBgHLRFdJYFkNKB+j56vTlB5AFTXcjs6x0dZ4j0SDAqVYgIHErpd2bhgOz +s698rfdadwbYN4UEqvV/2NhDLx/jag4BvCermK71HaXvYnvqKw3UHGAG8K/dCCFR +eSuZnxTSoWAPjMLi64hRzbWVT+oeZuy83lG6qDygbI1z1nlYWdo3 +-----END RSA PRIVATE KEY----- diff --git a/SAS/TMSS/test/oidc/example/requirements.txt b/SAS/TMSS/test/oidc/example/requirements.txt new file mode 100644 index 00000000000..e6b8e9f26cf --- /dev/null +++ b/SAS/TMSS/test/oidc/example/requirements.txt @@ -0,0 +1,3 @@ +pyop +Flask +gunicorn \ No newline at end of file diff --git a/SAS/TMSS/test/oidc/example/signing_key.pem b/SAS/TMSS/test/oidc/example/signing_key.pem new file mode 100644 index 00000000000..74fe00d413e --- /dev/null +++ b/SAS/TMSS/test/oidc/example/signing_key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCi7nye2Ye1MrUD/sZAplfkpMkXHYduydvfvv/+Ihx1ClxKS/KG +/1EhqyBVVvhHLRs9pimKMyLm2pBE51rGOt//XKhsoFAa37VID2iz7DQuV6DGgyBS +FaKgaYBpinEQy2WcjU4eABnABV2r+K2UmGkqVJheqHqOqHUKasT4gy/6kQIDAQAB +AoGAf7u+YX6ioNCvDwHHBVojn/H8YK3axmVkhiYkZWTysGM99VVTPridL2sMfzse +jBZ1u8Av4tOyMg/5eLtz8+KmRjljpeAEFfsA1htWE8vESXnvDFwKldXD9Vi/kppb +CYqASGCBUX3i1LPYffvjUxIgD+Tjx4k56c5EN5G331flDV0CQQDP8fWraegLJ+K1 +iXGNQzpaqG3EI3vf35Yb2bJpmD39QIXFIcJJ5MZHVW+1TyvgiavM4hS2+LGA8kGh +OvMWfbYTAkEAyJWGBUmAW9mooo1Vw4tJjEWAHjHvzcQ4dqIju+WN8Xy5JTWkDD6Z +VgKGtgLt2HfpSsgej14+Rh5mrjo4SbYxSwJAKG0syq9jOk/9xjc7STBJtvhJprkT +SxnHsBBpnBfJ7WNO3l1KzVzZo2Kbvg7vQ87gBIvrZQsCT0RJuBOi0LuN2wJAAInm +Qj1gSt7axRT8FfpZyDankW0w56yPOkJVNjv3lZ5wINl0B1RjtQdstTBs0xf/WGQR +MPFf2XBbdjxRymDi4QJBAM3MUYPOlUk1UVCSQKyCkBwL3zMaPjBjD5LXkhGJzxsb +T74NznwmCib/r0Rl/KmD7/bAq7R4aheOS/OMaZyhbkk= +-----END RSA PRIVATE KEY----- diff --git a/SAS/TMSS/test/oidc/example/templates/logout.jinja2 b/SAS/TMSS/test/oidc/example/templates/logout.jinja2 new file mode 100644 index 00000000000..4322588f219 --- /dev/null +++ b/SAS/TMSS/test/oidc/example/templates/logout.jinja2 @@ -0,0 +1,8 @@ +<!doctype html> +<title>Logout</title> + +Do you really want to logout? +<form method="POST"> + <button type="submit" name="logout" value="logout">Yes, logout</button> + <button type="submit" name="no_logout" value="no_logout">No, cancel logout</button> +</form> \ No newline at end of file diff --git a/SAS/TMSS/test/oidc/example/views.py b/SAS/TMSS/test/oidc/example/views.py new file mode 100644 index 00000000000..7d7335bb224 --- /dev/null +++ b/SAS/TMSS/test/oidc/example/views.py @@ -0,0 +1,124 @@ +from urllib.parse import urlencode, parse_qs + +import flask +from flask import Blueprint, redirect +from flask import current_app +from flask import jsonify +from flask.helpers import make_response +from flask.templating import render_template +from oic.oic.message import TokenErrorResponse, UserInfoErrorResponse, EndSessionRequest + +from pyop.access_token import AccessToken, BearerTokenError +from pyop.exceptions import InvalidAuthenticationRequest, InvalidAccessToken, InvalidClientAuthentication, OAuthError, \ + InvalidSubjectIdentifier, InvalidClientRegistrationRequest +from pyop.util import should_fragment_encode + +oidc_provider_views = Blueprint('oidc_provider', __name__, url_prefix='') + + +@oidc_provider_views.route('/') +def index(): + return 'Hello world!' + + +@oidc_provider_views.route('/registration', methods=['POST']) +def registration_endpoint(): + try: + response = current_app.provider.handle_client_registration_request(flask.request.get_data().decode('utf-8')) + return make_response(jsonify(response.to_dict()), 201) + except InvalidClientRegistrationRequest as e: + return make_response(jsonify(e.to_dict()), status=400) + + +@oidc_provider_views.route('/authentication', methods=['GET']) +def authentication_endpoint(): + # parse authentication request + try: + auth_req = current_app.provider.parse_authentication_request(urlencode(flask.request.args), + flask.request.headers) + except InvalidAuthenticationRequest as e: + current_app.logger.debug('received invalid authn request', exc_info=True) + error_url = e.to_error_url() + if error_url: + return redirect(error_url, 303) + else: + # show error to user + return make_response('Something went wrong: {}'.format(str(e)), 400) + + # automagic authentication + authn_response = current_app.provider.authorize(auth_req, 'test_user') + response_url = authn_response.request(auth_req['redirect_uri'], should_fragment_encode(auth_req)) + return redirect(response_url, 303) + + +@oidc_provider_views.route('/.well-known/openid-configuration') +def provider_configuration(): + return jsonify(current_app.provider.provider_configuration.to_dict()) + + +@oidc_provider_views.route('/jwks') +def jwks_uri(): + return jsonify(current_app.provider.jwks) + + +@oidc_provider_views.route('/token', methods=['POST']) +def token_endpoint(): + try: + token_response = current_app.provider.handle_token_request(flask.request.get_data().decode('utf-8'), + flask.request.headers) + return jsonify(token_response.to_dict()) + except InvalidClientAuthentication as e: + current_app.logger.debug('invalid client authentication at token endpoint', exc_info=True) + error_resp = TokenErrorResponse(error='invalid_client', error_description=str(e)) + response = make_response(error_resp.to_json(), 401) + response.headers['Content-Type'] = 'application/json' + response.headers['WWW-Authenticate'] = 'Basic' + return response + except OAuthError as e: + current_app.logger.debug('invalid request: %s', str(e), exc_info=True) + error_resp = TokenErrorResponse(error=e.oauth_error, error_description=str(e)) + response = make_response(error_resp.to_json(), 400) + response.headers['Content-Type'] = 'application/json' + return response + + +@oidc_provider_views.route('/userinfo', methods=['GET', 'POST']) +def userinfo_endpoint(): + try: + response = current_app.provider.handle_userinfo_request(flask.request.get_data().decode('utf-8'), + flask.request.headers) + return jsonify(response.to_dict()) + except (BearerTokenError, InvalidAccessToken) as e: + error_resp = UserInfoErrorResponse(error='invalid_token', error_description=str(e)) + response = make_response(error_resp.to_json(), 401) + response.headers['WWW-Authenticate'] = AccessToken.BEARER_TOKEN_TYPE + response.headers['Content-Type'] = 'application/json' + return response + + +def do_logout(end_session_request): + try: + current_app.provider.logout_user(end_session_request=end_session_request) + except InvalidSubjectIdentifier as e: + return make_response('Logout unsuccessful!', 400) + + redirect_url = current_app.provider.do_post_logout_redirect(end_session_request) + if redirect_url: + return redirect(redirect_url, 303) + + return make_response('Logout successful!') + + +@oidc_provider_views.route('/logout', methods=['GET', 'POST']) +def end_session_endpoint(): + if flask.request.method == 'GET': + # redirect from RP + end_session_request = EndSessionRequest().deserialize(urlencode(flask.request.args)) + flask.session['end_session_request'] = end_session_request.to_dict() + return render_template('logout.jinja2') + else: + form = parse_qs(flask.request.get_data().decode('utf-8')) + if 'logout' in form: + return do_logout(EndSessionRequest().from_dict(flask.session['end_session_request'])) + else: + return make_response('You chose not to logout') diff --git a/SAS/TMSS/test/oidc/example/wsgi.py b/SAS/TMSS/test/oidc/example/wsgi.py new file mode 100644 index 00000000000..f98a0a82188 --- /dev/null +++ b/SAS/TMSS/test/oidc/example/wsgi.py @@ -0,0 +1,7 @@ +import logging + +from example.app import oidc_provider_init_app + +name = 'oidc_provider' +app = oidc_provider_init_app(name) +logging.basicConfig(level=logging.DEBUG) diff --git a/SAS/TMSS/test/oidc/realm-export.json b/SAS/TMSS/test/oidc/realm-export.json new file mode 100644 index 00000000000..5fa0d5bae6b --- /dev/null +++ b/SAS/TMSS/test/oidc/realm-export.json @@ -0,0 +1,1808 @@ + + "id": "demo", + "realm": "demo", + "notBefore": 0, + "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, + "accessTokenLifespan": 300, + "accessTokenLifespanForImplicitFlow": 900, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "offlineSessionIdleTimeout": 2592000, + "offlineSessionMaxLifespanEnabled": false, + "offlineSessionMaxLifespan": 5184000, + "accessCodeLifespan": 60, + "accessCodeLifespanUserAction": 300, + "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, + "enabled": true, + "sslRequired": "external", + "registrationAllowed": false, + "registrationEmailAsUsername": false, + "rememberMe": false, + "verifyEmail": false, + "loginWithEmailAllowed": true, + "duplicateEmailsAllowed": false, + "resetPasswordAllowed": false, + "editUsernameAllowed": false, + "bruteForceProtected": false, + "permanentLockout": false, + "maxFailureWaitSeconds": 900, + "minimumQuickLoginWaitSeconds": 60, + "waitIncrementSeconds": 60, + "quickLoginCheckMilliSeconds": 1000, + "maxDeltaTimeSeconds": 43200, + "failureFactor": 30, + "roles": { + "realm": [ + { + "id": "9cdbfeb1-7dea-442b-a798-0845a15b3fef", + "name": "uma_authorization", + "description": "${role_uma_authorization}", + "composite": false, + "clientRole": false, + "containerId": "demo", + "attributes": {} + }, + { + "id": "5c42617f-2d8c-422d-8d15-b7630067990e", + "name": "demo-administrator", + "composite": false, + "clientRole": false, + "containerId": "demo", + "attributes": {} + }, + { + "id": "46b3080a-2957-4bd6-9d06-da15dac503e4", + "name": "promoter", + "composite": false, + "clientRole": false, + "containerId": "demo", + "attributes": {} + }, + { + "id": "16a657ca-7a97-4d27-b1d1-8a65087a1f19", + "name": "offline_access", + "description": "${role_offline-access}", + "composite": false, + "clientRole": false, + "containerId": "demo", + "attributes": {} + }, + { + "id": "cecacd7e-1775-4ac1-ba99-93d9020ead83", + "name": "monitoring", + "composite": false, + "clientRole": false, + "containerId": "demo", + "attributes": {} + } + ], + "client": { + "realm-management": [ + { + "id": "e441b81d-6ae3-4cf7-bfbf-ed4215eb2f47", + "name": "create-client", + "description": "${role_create-client}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "8c7cd27d-dfc5-4f83-80bf-373255b888d2", + "name": "manage-realm", + "description": "${role_manage-realm}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "ed027a01-9172-4e2c-a3c5-959de3d24c22", + "name": "view-users", + "description": "${role_view-users}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-users", + "query-groups" + ] + } + }, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "bf27552e-da67-4780-8d14-c795bc9f3407", + "name": "query-clients", + "description": "${role_query-clients}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "d6beb376-5920-411d-93fc-b90c091d3d2f", + "name": "manage-events", + "description": "${role_manage-events}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "3c5e7a53-7ead-4726-940f-d4190b0ec5c7", + "name": "manage-users", + "description": "${role_manage-users}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "031098a6-8e77-4e01-912b-e50a1f9e7749", + "name": "manage-authorization", + "description": "${role_manage-authorization}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "9fdf5253-30a4-4b3d-8ca7-2044396d9ccb", + "name": "query-groups", + "description": "${role_query-groups}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "d43dc9bd-5d06-4eae-9708-95f7e835fbfd", + "name": "view-clients", + "description": "${role_view-clients}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-clients" + ] + } + }, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "693555e2-14e1-461e-98a1-c8cab8137f8f", + "name": "view-realm", + "description": "${role_view-realm}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "6b90a2d2-f366-457d-9469-c5da38f990a6", + "name": "query-realms", + "description": "${role_query-realms}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "c073af53-414a-41f0-b093-0b68c0f1ecba", + "name": "impersonation", + "description": "${role_impersonation}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "1283a4ff-5217-449c-8c85-ddff72ed73fd", + "name": "query-users", + "description": "${role_query-users}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "57a640d0-f017-46f8-a23e-d3fc7f8e7de8", + "name": "realm-admin", + "description": "${role_realm-admin}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "manage-realm", + "create-client", + "view-users", + "query-clients", + "manage-events", + "manage-authorization", + "manage-users", + "query-groups", + "view-realm", + "view-clients", + "query-realms", + "impersonation", + "query-users", + "manage-clients", + "view-authorization", + "view-events", + "view-identity-providers", + "manage-identity-providers" + ] + } + }, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "5d4108b8-c2bc-44f2-9038-ea18bf3164ef", + "name": "manage-clients", + "description": "${role_manage-clients}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "7ee7d0f4-d61f-4e01-ac37-86a7d42e30a0", + "name": "view-authorization", + "description": "${role_view-authorization}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "9d6dd55e-2d70-4b35-9ae7-43b59ff84cd5", + "name": "view-events", + "description": "${role_view-events}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "e2b85d94-2efb-458f-ae69-84e04d0975e4", + "name": "view-identity-providers", + "description": "${role_view-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + }, + { + "id": "466294e7-feb8-4d2f-ae45-6807160553ae", + "name": "manage-identity-providers", + "description": "${role_manage-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "0c80e92e-024a-4324-b516-cf814f7e09df", + "attributes": {} + } + ], + "demo-frontend": [], + "security-admin-console": [], + "admin-cli": [], + "demo-api": [], + "broker": [ + { + "id": "b375956d-b283-45b7-aa0b-76e19d3c9b2f", + "name": "read-token", + "description": "${role_read-token}", + "composite": false, + "clientRole": true, + "containerId": "d165281c-4c36-4185-bfbd-589c8a52945f", + "attributes": {} + } + ], + "account": [ + { + "id": "aada5867-9268-4e37-b206-491041cd3360", + "name": "view-profile", + "description": "${role_view-profile}", + "composite": false, + "clientRole": true, + "containerId": "f5c24837-4fc7-4994-9c1e-bd70f2cbeed6", + "attributes": {} + }, + { + "id": "39893eb7-65a6-4d5e-9704-f59952deaeab", + "name": "manage-account", + "description": "${role_manage-account}", + "composite": true, + "composites": { + "client": { + "account": [ + "manage-account-links" + ] + } + }, + "clientRole": true, + "containerId": "f5c24837-4fc7-4994-9c1e-bd70f2cbeed6", + "attributes": {} + }, + { + "id": "193f4d1a-4c4a-4029-9092-1aa44df23b42", + "name": "manage-account-links", + "description": "${role_manage-account-links}", + "composite": false, + "clientRole": true, + "containerId": "f5c24837-4fc7-4994-9c1e-bd70f2cbeed6", + "attributes": {} + } + ] + } + }, + "groups": [ + { + "id": "62909b3a-eb39-4916-a640-f401d0592a47", + "name": "administrator", + "path": "/administrator", + "attributes": {}, + "realmRoles": [ + "demo-administrator" + ], + "clientRoles": {}, + "subGroups": [] + }, + { + "id": "3e007c9c-297e-4403-8ad0-1888e05211ad", + "name": "monitoring", + "path": "/monitoring", + "attributes": {}, + "realmRoles": [ + "monitoring" + ], + "clientRoles": {}, + "subGroups": [] + }, + { + "id": "9ca100d3-c97c-495e-9e28-828bfe7e2405", + "name": "promoter", + "path": "/promoter", + "attributes": {}, + "realmRoles": [ + "promoter" + ], + "clientRoles": {}, + "subGroups": [] + } + ], + "requiredCredentials": [ + "password" + ], + "otpPolicyType": "totp", + "otpPolicyAlgorithm": "HmacSHA1", + "otpPolicyInitialCounter": 0, + "otpPolicyDigits": 6, + "otpPolicyLookAheadWindow": 1, + "otpPolicyPeriod": 30, + "otpSupportedApplications": [ + "FreeOTP", + "Google Authenticator" + ], + "clients": [ + { + "id": "1f279ab9-a6b9-4d19-b9f3-f881ff2257eb", + "clientId": "admin-cli", + "name": "${client_admin-cli}", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "role_list", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access" + ] + }, + { + "id": "f5c24837-4fc7-4994-9c1e-bd70f2cbeed6", + "clientId": "account", + "name": "${client_account}", + "baseUrl": "/auth/realms/demo/account", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [ + "/auth/realms/demo/account/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "role_list", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access" + ] + }, + { + "id": "0c80e92e-024a-4324-b516-cf814f7e09df", + "clientId": "realm-management", + "name": "${client_realm-management}", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "role_list", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access" + ] + }, + { + "id": "3bcece73-8800-42d4-82fe-7c0012be3780", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "baseUrl": "/auth/admin/demo/console/index.html", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [ + "/auth/admin/demo/console/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "e70c7d3c-dd18-4084-81c8-c57a31a31cb9", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "role_list", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access" + ] + }, + { + "id": "2e0fa909-b029-4d69-ac0e-ff3e593d57e6", + "clientId": "demo-frontend", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [ + "http://localhost:9002/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "exclude.session.state.from.auth.response": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "defaultClientScopes": [ + "web-origins", + "role_list", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access" + ] + }, + { + "id": "d165281c-4c36-4185-bfbd-589c8a52945f", + "clientId": "broker", + "name": "${client_broker}", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "role_list", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access" + ] + }, + { + "id": "79e1f43b-283a-40d9-a953-c60e9686d329", + "clientId": "demo-api", + "surrogateAuthRequired": false, + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "exclude.session.state.from.auth.response": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "defaultClientScopes": [ + "web-origins", + "role_list", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access" + ] + } + ], + "clientScopes": [ + { + "id": "90b602f0-d9a0-4781-9e9b-2dd5f7d28665", + "name": "address", + "description": "OpenID Connect built-in scope: address", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${addressScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "45f8b45d-72bb-47dc-ab28-2a5c83b81cf8", + "name": "address", + "protocol": "openid-connect", + "protocolMapper": "oidc-address-mapper", + "consentRequired": false, + "config": { + "user.attribute.formatted": "formatted", + "user.attribute.country": "country", + "user.attribute.postal_code": "postal_code", + "userinfo.token.claim": "true", + "user.attribute.street": "street", + "id.token.claim": "true", + "user.attribute.region": "region", + "access.token.claim": "true", + "user.attribute.locality": "locality" + } + } + ] + }, + { + "id": "10c965ec-c1af-4f24-9945-9d94fb7ee037", + "name": "email", + "description": "OpenID Connect built-in scope: email", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${emailScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "c31c85b3-9641-4656-b19a-eb399567522e", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "33354d4c-bb3b-4410-9238-f5e8448dc955", + "name": "email verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "emailVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email_verified", + "jsonType.label": "boolean" + } + } + ] + }, + { + "id": "1338f8cd-1cc1-4446-9f54-4e7db3e319d1", + "name": "offline_access", + "description": "OpenID Connect built-in scope: offline_access", + "protocol": "openid-connect", + "attributes": { + "consent.screen.text": "${offlineAccessScopeConsentText}", + "display.on.consent.screen": "true" + } + }, + { + "id": "0c36241e-ca1f-415d-b218-4da0ef9fc57b", + "name": "phone", + "description": "OpenID Connect built-in scope: phone", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${phoneScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "9b8380cc-5aaf-4bf7-89b4-f29c7dba6a0c", + "name": "phone number", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "phoneNumber", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number", + "jsonType.label": "String" + } + }, + { + "id": "d2bdd3f1-3293-4c59-92c5-a64967a49ec7", + "name": "phone number verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "phoneNumberVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number_verified", + "jsonType.label": "boolean" + } + } + ] + }, + { + "id": "9ba88b22-dfd9-4544-966e-ab2e07e02283", + "name": "profile", + "description": "OpenID Connect built-in scope: profile", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${profileScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "abc6a671-5996-48ec-aac3-5d970b85e9a6", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "7a6e6867-8767-4782-8400-e8cba29588e2", + "name": "updated at", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "updatedAt", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "updated_at", + "jsonType.label": "String" + } + }, + { + "id": "a45c0185-4e57-4d73-a55c-de4e30886c84", + "name": "picture", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "picture", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "picture", + "jsonType.label": "String" + } + }, + { + "id": "8786b25f-17e7-4187-8d7d-d2aa61c6dcd8", + "name": "profile", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "profile", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "profile", + "jsonType.label": "String" + } + }, + { + "id": "95ece622-b3cc-49f5-b848-a9b8a5407ef4", + "name": "birthdate", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "birthdate", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "birthdate", + "jsonType.label": "String" + } + }, + { + "id": "59189670-aa93-4933-a796-53dab6a23e45", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + }, + { + "id": "addccb2b-468f-404c-9e80-de9d344f6b94", + "name": "nickname", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "nickname", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "nickname", + "jsonType.label": "String" + } + }, + { + "id": "cd2fe8d9-f253-477f-94fd-29942d56849c", + "name": "website", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "website", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "website", + "jsonType.label": "String" + } + }, + { + "id": "450e97fc-e780-4262-8f26-0cf8ac903aa3", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "4b40a0f9-44a1-4a01-b0c5-bfb8be5bccb6", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": false, + "config": { + "id.token.claim": "true", + "access.token.claim": "true", + "userinfo.token.claim": "true" + } + }, + { + "id": "07343c50-155a-430c-8ebb-c68a931a0c80", + "name": "gender", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "gender", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "gender", + "jsonType.label": "String" + } + }, + { + "id": "8076d3ce-1d9f-4779-93c3-9b6a06e8bdac", + "name": "middle name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "middleName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "middle_name", + "jsonType.label": "String" + } + }, + { + "id": "d26abee7-b8a7-4ca5-9755-38e18cc539d6", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + }, + { + "id": "83344728-39e4-4600-9c5b-b9d69da3c4f0", + "name": "zoneinfo", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "zoneinfo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "zoneinfo", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "289f7853-fa6e-4f17-a01d-6c409bddc25a", + "name": "role_list", + "description": "SAML role list", + "protocol": "saml", + "attributes": { + "consent.screen.text": "${samlRoleListScopeConsentText}", + "display.on.consent.screen": "true" + }, + "protocolMappers": [ + { + "id": "c0d2acb4-d20f-48de-94c7-ec6ac1c964e1", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + } + ] + }, + { + "id": "6820c5fc-b7db-4a1d-b71a-8dbd0c7cf98c", + "name": "roles", + "description": "OpenID Connect scope for add user roles to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "true", + "consent.screen.text": "${rolesScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "1cb77c0d-6397-4b3d-acef-8ae1d4089944", + "name": "client roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": false, + "config": { + "multivalued": "true", + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "resource_access.${client_id}.roles", + "jsonType.label": "String" + } + }, + { + "id": "0cf6603d-891d-4f42-8da0-d187f0816a6d", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + }, + { + "id": "9e8111be-4598-4145-96da-a9a0fcda8169", + "name": "realm roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "multivalued": "true", + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "realm_access.roles", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "ba84e265-6519-45db-88fc-f86ec057f28c", + "name": "web-origins", + "description": "OpenID Connect scope for add allowed web origins to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false", + "consent.screen.text": "" + }, + "protocolMappers": [ + { + "id": "3d010883-cafc-4e4a-9246-3669d767f409", + "name": "allowed web origins", + "protocol": "openid-connect", + "protocolMapper": "oidc-allowed-origins-mapper", + "consentRequired": false, + "config": {} + } + ] + } + ], + "defaultDefaultClientScopes": [ + "role_list", + "profile", + "email", + "roles", + "web-origins" + ], + "defaultOptionalClientScopes": [ + "offline_access", + "address", + "phone" + ], + "browserSecurityHeaders": { + "contentSecurityPolicyReportOnly": "", + "xContentTypeOptions": "nosniff", + "xRobotsTag": "none", + "xFrameOptions": "SAMEORIGIN", + "xXSSProtection": "1; mode=block", + "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "strictTransportSecurity": "max-age=31536000; includeSubDomains" + }, + "smtpServer": {}, + "eventsEnabled": false, + "eventsListeners": [ + "jboss-logging" + ], + "enabledEventTypes": [], + "adminEventsEnabled": false, + "adminEventsDetailsEnabled": false, + "components": { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ + { + "id": "5d3fa6d3-b34b-4996-b19c-4b57c49968c0", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "eee392b9-35d5-4166-90b3-87b8e7fe7102", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "5d4439dc-fae2-41ff-b1a9-36f70dc0ca79", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", + "subType": "anonymous", + "subComponents": {}, + "config": { + "host-sending-registration-request-must-match": [ + "true" + ], + "client-uris-must-match": [ + "true" + ] + } + }, + { + "id": "c1ba9983-f538-417e-8c7c-a4569946ac98", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "oidc-full-name-mapper", + "oidc-usermodel-attribute-mapper", + "oidc-usermodel-property-mapper", + "oidc-address-mapper", + "saml-user-attribute-mapper", + "saml-user-property-mapper", + "oidc-sha256-pairwise-sub-mapper", + "saml-role-list-mapper" + ] + } + }, + { + "id": "506d7fe8-a747-4ad2-89be-6c467cd9820d", + "name": "Max Clients Limit", + "providerId": "max-clients", + "subType": "anonymous", + "subComponents": {}, + "config": { + "max-clients": [ + "200" + ] + } + }, + { + "id": "bdb7e39e-b1dd-4d19-826f-dcf0b1e8b505", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "saml-user-attribute-mapper", + "oidc-full-name-mapper", + "saml-role-list-mapper", + "saml-user-property-mapper", + "oidc-usermodel-attribute-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-usermodel-property-mapper", + "oidc-address-mapper" + ] + } + }, + { + "id": "4d541fe3-f769-4457-817d-5ca7af5705a0", + "name": "Full Scope Disabled", + "providerId": "scope", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "d1b29f0d-4c6b-4c03-95bf-e27c23ef3a2c", + "name": "Consent Required", + "providerId": "consent-required", + "subType": "anonymous", + "subComponents": {}, + "config": {} + } + ], + "org.keycloak.keys.KeyProvider": [ + { + "id": "5ca0e66f-c953-4088-842a-f65f1cfce006", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "004fea62-f268-4580-aafd-0b59b82740f2", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "b9531509-0e75-48dd-8860-7dbec1431d09", + "name": "hmac-generated", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "HS256" + ] + } + } + ] + }, + "internationalizationEnabled": false, + "supportedLocales": [], + "authenticationFlows": [ + { + "id": "e18853d2-04f1-4abd-a397-6d204a640c0d", + "alias": "Handle Existing Account", + "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-confirm-link", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "idp-email-verification", + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "Verify Existing Account by Re-authentication", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "1fea2aeb-619c-41fc-b8cc-d5b4529a500d", + "alias": "Verify Existing Account by Re-authentication", + "description": "Reauthentication of existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-username-password-form", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "requirement": "OPTIONAL", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "382ebfeb-0fd2-4612-890b-6351a44fe1c1", + "alias": "browser", + "description": "browser based authentication", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-cookie", + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "requirement": "DISABLED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "identity-provider-redirector", + "requirement": "ALTERNATIVE", + "priority": 25, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "forms", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "34a5ff88-ffd5-4f60-9d65-99ddc6d9c41a", + "alias": "clients", + "description": "Base authentication for clients", + "providerId": "client-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "client-secret", + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-jwt", + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-secret-jwt", + "requirement": "ALTERNATIVE", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-x509", + "requirement": "ALTERNATIVE", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "3d8c95b8-49a5-416b-823b-5533e089e1a7", + "alias": "direct grant", + "description": "OpenID Connect Resource Owner Grant", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "direct-grant-validate-username", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-password", + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-otp", + "requirement": "OPTIONAL", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "0ae57c67-dfd8-4264-b6ce-6731f71c3237", + "alias": "docker auth", + "description": "Used by Docker clients to authenticate against the IDP", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "docker-http-basic-authenticator", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "272cb097-3372-45c6-b0cc-d920a1cc6bd6", + "alias": "first broker login", + "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "review profile config", + "authenticator": "idp-review-profile", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorConfig": "create unique user config", + "authenticator": "idp-create-user-if-unique", + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "Handle Existing Account", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "ab046190-a8d4-4d52-9503-35325498a15f", + "alias": "forms", + "description": "Username, password, otp and other auth forms.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-username-password-form", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "requirement": "OPTIONAL", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "21f7be44-8819-4ba0-95cb-01a336745cd0", + "alias": "http challenge", + "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "no-cookie-redirect", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "basic-auth", + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "basic-auth-otp", + "requirement": "DISABLED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "requirement": "DISABLED", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "e2f99e58-44fb-4776-aaa4-ffc809294c15", + "alias": "registration", + "description": "registration flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-page-form", + "requirement": "REQUIRED", + "priority": 10, + "flowAlias": "registration form", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "6b1f9993-fd6b-4cf5-b218-99914899154b", + "alias": "registration form", + "description": "registration form", + "providerId": "form-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-user-creation", + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-profile-action", + "requirement": "REQUIRED", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-password-action", + "requirement": "REQUIRED", + "priority": 50, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-recaptcha-action", + "requirement": "DISABLED", + "priority": 60, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "2ac061c4-101e-453d-9b00-ecced9adf98a", + "alias": "reset credentials", + "description": "Reset credentials for a user if they forgot their password or something", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "reset-credentials-choose-user", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-credential-email", + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-password", + "requirement": "REQUIRED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-otp", + "requirement": "OPTIONAL", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "d5cb10f4-333b-4b2e-85ef-533e16d25029", + "alias": "saml ecp", + "description": "SAML ECP Profile Authentication Flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "http-basic-authenticator", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + } + ], + "authenticatorConfig": [ + { + "id": "9181f4be-676d-4639-8883-e8b3bd99dc9c", + "alias": "create unique user config", + "config": { + "require.password.update.after.registration": "false" + } + }, + { + "id": "580e9d0d-3439-44cb-8be7-852cdf9de45a", + "alias": "review profile config", + "config": { + "update.profile.on.first.login": "missing" + } + } + ], + "requiredActions": [ + { + "alias": "CONFIGURE_TOTP", + "name": "Configure OTP", + "providerId": "CONFIGURE_TOTP", + "enabled": true, + "defaultAction": false, + "priority": 10, + "config": {} + }, + { + "alias": "terms_and_conditions", + "name": "Terms and Conditions", + "providerId": "terms_and_conditions", + "enabled": false, + "defaultAction": false, + "priority": 20, + "config": {} + }, + { + "alias": "UPDATE_PASSWORD", + "name": "Update Password", + "providerId": "UPDATE_PASSWORD", + "enabled": true, + "defaultAction": false, + "priority": 30, + "config": {} + }, + { + "alias": "UPDATE_PROFILE", + "name": "Update Profile", + "providerId": "UPDATE_PROFILE", + "enabled": true, + "defaultAction": false, + "priority": 40, + "config": {} + }, + { + "alias": "VERIFY_EMAIL", + "name": "Verify Email", + "providerId": "VERIFY_EMAIL", + "enabled": true, + "defaultAction": false, + "priority": 50, + "config": {} + } + ], + "browserFlow": "browser", + "registrationFlow": "registration", + "directGrantFlow": "direct grant", + "resetCredentialsFlow": "reset credentials", + "clientAuthenticationFlow": "clients", + "dockerAuthenticationFlow": "docker auth", + "attributes": { + "_browser_header.xXSSProtection": "1; mode=block", + "_browser_header.xFrameOptions": "SAMEORIGIN", + "_browser_header.strictTransportSecurity": "max-age=31536000; includeSubDomains", + "permanentLockout": "false", + "quickLoginCheckMilliSeconds": "1000", + "_browser_header.xRobotsTag": "none", + "maxFailureWaitSeconds": "900", + "minimumQuickLoginWaitSeconds": "60", + "failureFactor": "30", + "actionTokenGeneratedByUserLifespan": "300", + "maxDeltaTimeSeconds": "43200", + "_browser_header.xContentTypeOptions": "nosniff", + "offlineSessionMaxLifespan": "5184000", + "actionTokenGeneratedByAdminLifespan": "43200", + "_browser_header.contentSecurityPolicyReportOnly": "", + "bruteForceProtected": "false", + "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "waitIncrementSeconds": "60", + "offlineSessionMaxLifespanEnabled": "false" + }, + "keycloakVersion": "4.6.0.Final", + "userManagedAccessAllowed": false +} diff --git a/SAS/TMSS/test/oidc/tmss_keycloak_Dockerfile b/SAS/TMSS/test/oidc/tmss_keycloak_Dockerfile new file mode 100644 index 00000000000..40af052fa68 --- /dev/null +++ b/SAS/TMSS/test/oidc/tmss_keycloak_Dockerfile @@ -0,0 +1,10 @@ +FROM jboss/keycloak:4.6.0.Final + +ENV KEYCLOAK_USER=admin +ENV KEYCLOAK_PASSWORD=admin +ENV KEYCLOAK_IMPORT=/tmp/realm-export.json + +ADD realm-export.json /tmp/realm-export.json +ADD create-keycloak-user.sh /opt/jboss/create-keycloak-user.sh + + -- GitLab