In web2py put this in your db.py:
# Define oauth application id and secret.
Kcloak_CLIENT_ID='XXXX'
Kcloak_CLIENT_SECRET="XXXXX"
## import required modules
try:
import json
except ImportError:
from gluon.contrib import simplejson as json
from gluon.contrib.login_methods.oauth20_account import OAuthAccount
## extend the OAUthAccount class
class KCloakAccount(OAuthAccount):
# """OAuth impl for KeyCloak"""
AUTH_URL="http(s)://KEYCLOAKIPANDPORT/auth/realms/master/protocol/openid-connect/auth"
TOKEN_URL="http(s)://KEYCLOAKIPANDPORT/auth/realms/master/protocol/openid-connect/token"
def __init__(self):
OAuthAccount.__init__(self, None, Kcloak_CLIENT_ID, Kcloak_CLIENT_SECRET,
self.AUTH_URL, self.TOKEN_URL,
scope='openid profile email',
state="klcoak",
display='popup')
def get_user(self):
if not self.accessToken():
return None
#global token
token= None
token=self.accessToken()
print (token)
#from okta_jwt.jwt import validate_token
issuer="http(s)://KEYCLOAKIPANDPORT/auth/realms/master"
audience="http(s)://YOURWEB2PYPAGEURL"
import jwt
profile=jwt.decode(token,verify=False)
if profile['sub']:
username = profile['email']
email = profile['email']
first_name = profile['given_name']
last_name = profile['family_name']
return dict(username = username, first_name=first_name,last_name=last_name,email = '%s' %(email))
else:
self.session.token = None
and put this in your
gluon/contrib/login_methods/oauth20_account.py
replace whatever you have under the logout function with:
del current.session.token
del current.session.auth
current.session.token = None
current.session.auth = None
redirect('http(s)://KEYCLOAKIPPORT/auth/realms/master/protocol/openid-connect/logout?redirect_uri=*ENCODEDURLTOREDIRECTAFTERLOGOUT" ')
End Web2py part.
For py4web:
Create oauth2keycloak.py file in py4web/utils/auth_plugins/ and put in this:
from . import OAuth2
class OAuth2Keycloak(OAuth2):
name = "oauth2keycloak"
login_url = "http(s)://KEYCLOAKIPPORT/auth/realms/master/protocol/openid-connect/auth"
token_url = "http(s)://KEYCLOAKIPPORT/auth/realms/master/protocol/openid-connect/token"
userinfo_url = "http(s)://KEYCLOAKIPPORT/auth/realms/master/protocol/openid-connect/userinfo"
revoke_url = "http(s)://KEYCLOAKIPPORT/auth/realms/master/protocol/openid-connect/logout"
default_scope = "openid profile"
maps = {
"username": "email",
"email":"email",
"sso_id": "email",
"first_name": "given_name",
"last_name": "family_name",
}
In your app (probably based on scaffold) go to your static/components/auth.html and add a button for KeyCloak:
<a v-if="plugins.indexOf('oauth2keycloak')>=0"
class="button is-link"
v-bind:href="'../auth/plugin/oauth2keycloak/login?next='+next">Login with KeyCloak</a>
Also in your scaffoled app add the plugin to the auth.html file under templates:
<div class="column is-half is-offset-one-quarter" style="border : 1px solid #e1e1e1; border-radius: 10px">
<auth plugins="local,oauth2keycloak"></auth>
Finally for single logout add this line to your logout function in py4web/utils/auth.py
526 elif path == "logout":
527 self.session.clear()
528 redirect ('http(s)://KEYCLOAKIPPORT/auth/realms/master/protocol/openid-connect/logout?redirect_uri=*ENCODEDREDIRECTURIAFTERLOGOUT*
Of course you need to install keycloak and create 2 openid clients with secrets.
Thats it in a nutshell.