Closed chintus777 closed 8 months ago
Hello Chintu,
abcdesktop auth works fine with the famous keycloak service. Rules are only supported by Ldap service, in this current release. You ask for a new feature, Add keycloak tag, and match the auth tag to rule. This is a relay good feature, and I like your great idea. I have to check how keycloack tag can be read from the auth provider classes.
Good point, thank you for your comment I add your request as 'New feature or Request'
Alexandre
Hello Alexandre,
Thanks for your reply.
After researching a bit, I was wondering that to apply 2FA through RSA, can something be implemented on the submit button that redirects to an external page where an OTP can be authenticated. After authentication if the login is true, user can access their desktop, otherwise redirected to their login page with an error message. Some options I researched upon were: Duo by Cisco JumpCloud
Also do let me know your view, whether implementing this will be better or making ACL Rules over Keycloak is better.
Thank You Chintu
Hello Chintu,
The abcdesktopio/oc.pyos:3.1 has now a support for acl rule over Keycloak.
The default memberof attribut name is groups
The keycloak IP Addr is a.b.c.d
The keycload external provider is defined in od.config
'keycloak': {
'displayname': 'keycloak',
'enabled': True,
'client_id': 'cc18d356-19b0-11ee-ada5-zzzzzzzzzzz',
'client_secret': 'xxxxxxxxxxxxxxxx',
'userinfo_auth': True,
'scope': [ 'openid', 'email', 'profile', 'roles' ],
'userinfo_url': 'https://a.b.c.d:8080/realms/master/protocol/openid-connect/userinfo',
'redirect_uri_prefix' : 'https://www.abcdesktop.local/API/auth/oauth',
'redirect_uri_querystring': 'manager=external&provider=keycloak',
'authorization_base_url': 'http://a.b.c.d:8080/realms/master/protocol/openid-connect/auth',
'token_url': 'http://a.b.c.d:8080/realms/master/protocol/openid-connect/token',
'revoke_url' : 'https://a.b.c.d:8080/realms/master/protocol/openid-connect/revoke',
'policies': {
'acl' : { 'permit': [ 'all' ] },
'rules' : {
'rule-ship2': {
'conditions' : [ { 'memberOf': 'abcdesktop-role', 'expected' : True } ],
'expected' : True,
'label': 'ship'
}
}
}
},
Then I use the keycloack auth, the user is member of ship
group.
On the keycloack, you have to define groups, in my case the user is member of 'abcdesktop-role' group.
Add rules, and check the Include in token scope
box in the client scope
Look at the log of pyos pod to get the keycloack auth response attribut, if need. I have also defined a role mapping for this user.
See you Alexandre
Hello Alexandre,
Thanks a lot for your reply . I am still facing issues in applying ACL rule and still the label is not available inside abcdesktop.
Following is the od.config snippet-
'external': { 'providers': { 'keycloak': { 'displayname': 'Keycloak', 'enabled': True, 'userinfo_auth': True, 'scope' : [ 'openid','email','profile','roles','abcdesktop-role'], 'client_id': 'demo', 'client_secret': 'd3FyRmJWmjYgta1LlhmAQYmtkgHhzjG5', 'redirect_uri_prefix' : 'https://login.co/API/auth/oauth', 'redirect_uri_querystring': 'manager=external&provider=keycloak', 'authorization_base_url': 'https://keycloak1.co/realms/master/protocol/openid-connect/auth', 'token_url': 'https://keycloak1.co/realms/master/protocol/openid-connect/token', 'userinfo_url': 'https://keycloak1.co/realms/master/protocol/openid-connect/userinfo', 'revoke_url': 'https://keycloak1.co/realms/master/protocol/openid-connect/revoke', 'policies': { 'acl' : { 'permit': [ 'all' ] }, 'rules' : { 'rule-net-home': { 'conditions' : [ { 'memberOf': 'firefox', 'expected' : True } ], 'expected' : True, 'label' : 'firefox' } } } }
The deployment , ingress and service yaml is same as provided in previous comment. I am using quay.io/keycloak/keycloak:latest image for keycloak and abcdesktopio/oc.pyos:3.1 image for pyos. On keycloak Portal I did following steps-
2 Created a group named 'firefox'
3Created a user john and added to group firefox
4 Created a client scope -abcdesktop-role
5 Then added the 'abcdesktop-role' scope in demo client.
6 Then I added a role named 'test-2' for my client demo
7 Then I added role-mapping 'test-2' to the user and group
Still after sign in I cant see label "firefox" inside settings.
Following are the logs of pyos- 2023-10-13 11:37:18 od [INFO ] main.trace_request:anonymous /core/getmessageinfo {} 2023-10-13 11:37:18 od [INFO ] main.trace_response:3476a799-43d7-4bf2-bd3d-eb4ff4369eef /core/getmessageinfo b'{"status": 200, "result": null, "message": "b.Successfully assigned vdi/3476a799-43d7-4bf2-bd3d-eb4ff4369eef-79f97 to prodclient-w3"}' 2023-10-13 11:37:21 od [INFO ] main.trace_request:anonymous /core/getmessageinfo {} 2023-10-13 11:37:21 od [INFO ] main.trace_response:3476a799-43d7-4bf2-bd3d-eb4ff4369eef /core/getmessageinfo b'{"status": 200, "result": null, "message": null}' 2023-10-13 11:37:22 od [INFO ] main.trace_request:anonymous /core/getmessageinfo {} 2023-10-13 11:37:22 od [INFO ] main.trace_response:3476a799-43d7-4bf2-bd3d-eb4ff4369eef /core/getmessageinfo b'{"status": 200, "result": null, "message": "c.Waiting for desktop graphical service 1/42"}' 2023-10-13 11:37:23 od [INFO ] main.trace_request:anonymous /core/getmessageinfo {} 2023-10-13 11:37:23 od [INFO ] main.trace_response:3476a799-43d7-4bf2-bd3d-eb4ff4369eef /core/getmessageinfo b'{"status": 200, "result": null, "message": "stopinfo"}' 2023-10-13 11:37:23 od [INFO ] main.trace_request:anonymous /core/getkeyinfo {'provider': 'zimbra'} 2023-10-13 11:37:23 od [INFO ] main.trace_response:anonymous /core/getkeyinfo b'{"id": null, "callbackurl": null}' 2023-10-13 11:37:24 od [INFO ] main.trace_request:anonymous /healthz 2023-10-13 11:37:25 od [INFO ] main.trace_request:anonymous /store/get {'key': 'backgroundType'} 2023-10-13 11:37:25 store_controller [DEBUG ] controllers.store_controller.StoreController.wrapped_get:3476a799-43d7-4bf2-bd3d-eb4ff4369eef 2023-10-13 11:37:25 datastore [DEBUG ] oc.datastore.ODMongoDatastoreClient.get_document_value_in_collection:3476a799-43d7-4bf2-bd3d-eb4ff4369eef database=profiles collectionname=3476a799-43d7-4bf2-bd3d-eb4ff4369eef key=backgroundType 2023-10-13 11:37:25 datastore [DEBUG ] oc.datastore.ODMongoDatastoreClient.createclient:3476a799-43d7-4bf2-bd3d-eb4ff4369eef databasename=profiles 2023-10-13 11:37:25 datastore [DEBUG ] oc.datastore.ODMongoDatastoreClient.createclient:3476a799-43d7-4bf2-bd3d-eb4ff4369eef createclient MongoClient mongodb://pyos:Az4MeYWUjZDg4Zjhk@mongodb.vdi.svc.cluster.local/profiles?authSource=profiles 2023-10-13 11:37:25 od [INFO ] main.trace_request:anonymous /core/getkeyinfo {'provider': 'webrtc'} 2023-10-13 11:37:25 od [INFO ] main.trace_response:anonymous /core/getkeyinfo b'{"id": false, "callbackurl": null}' 2023-10-13 11:37:25 store_controller [DEBUG ] controllers.store_controller.StoreController.wrapped_get:3476a799-43d7-4bf2-bd3d-eb4ff4369eef wrapped_get result 3476a799-43d7-4bf2-bd3d-eb4ff4369eef:backgroundType->img 2023-10-13 11:37:25 od [INFO ] main.trace_response:3476a799-43d7-4bf2-bd3d-eb4ff4369eef /store/get b'{"status": 200, "result": "img", "message": "ok"}' 2023-10-13 11:37:32 od [INFO ] main.trace_request:anonymous /auth/labels {} 2023-10-13 11:37:32 od [INFO ] main.trace_request:anonymous /store/getcollection {'key': 'loginHistory'} 2023-10-13 11:37:32 auth_controller [DEBUG ] controllers.auth_controller.AuthController.labels:anonymous 2023-10-13 11:37:32 datastore [DEBUG ] oc.datastore.ODMongoDatastoreClient.getcollection:3476a799-43d7-4bf2-bd3d-eb4ff4369eef database=loginHistory collectionname=3476a799-43d7-4bf2-bd3d-eb4ff4369eef 2023-10-13 11:37:32 od [INFO ] main.trace_response:3476a799-43d7-4bf2-bd3d-eb4ff4369eef /auth/labels b'{"status": 200, "result": {}, "message": "ok"}' 2023-10-13 11:37:32 datastore [DEBUG ] oc.datastore.ODMongoDatastoreClient.createclient:3476a799-43d7-4bf2-bd3d-eb4ff4369eef databasename=loginHistory 2023-10-13 11:37:32 datastore [DEBUG ] oc.datastore.ODMongoDatastoreClient.createclient:3476a799-43d7-4bf2-bd3d-eb4ff4369eef createclient MongoClient mongodb://pyos:Az4MeYWUjZDg4Zjhk@mongodb.vdi.svc.cluster.local/loginHistory?authSource=loginHistory 2023-10-13 11:37:32 od [INFO ] main.trace_response:3476a799-43d7-4bf2-bd3d-eb4ff4369eef /store/getcollection b'{"status": 200, "result": [{"_id": "65292bf25627e22f125143d8", "name": "John Doe", "userid": "3476a799-43d7-4bf2-bd3d-eb4ff4369eef", "locale": "en_US", "posix": {"cn": "3476a799-43d7-4bf2-bd3d-eb4ff43", "uid": "3476a799-43d7-4bf2-bd3d-eb4ff43", "gid": "3476a799-43d7-4bf2-bd3d-eb4ff4369eef", "uidNumber": "4096", "gidNumber": "4096", "homeDirectory": "/home/balloon", "loginShell": "/bin/bash", "description": "abcdesktop default account", "groups": null, "gecos": null}, "provider": "oauth", "date": "2023-10-13T11:37:22.786529", "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60", "ipaddr": "192.168.178.202", "node": "prodclient-w3", "type": "desktop"}], "message": "ok"}' 2023-10-13 11:37:34 od [INFO ] main.trace_request:anonymous /healthz
Please let me know what can I do to resolve this issue , Also I am still confused about client-scope , roles, role-mapping as u mentioned in previous comment .
Thanks and Regards Chintu
Hello Alexandre,
These are the logs of keycloak pod -
Updating the configuration and installing your custom providers, if any. Please wait.
2023-10-16 13:11:41,114 INFO [io.quarkus.deployment.QuarkusAugmentor] (main) Quarkus augmentation completed in 9478ms
2023-10-16 13:11:42,412 INFO [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: Base URL: <unset>, Hostname: <request>, Strict HTTPS: false, Path: <request>, Strict BackChannel: false, Admin URL: <unset>, Admin: <request>, Port: -1, Proxied: true
2023-10-16 13:11:44,038 WARN [io.quarkus.agroal.runtime.DataSources] (main) Datasource <default> enables XA but transaction recovery is not enabled. Please enable transaction recovery by setting quarkus.transaction-manager.enable-recovery=true, otherwise data may be lost if the application is terminated abruptly
2023-10-16 13:11:44,634 WARN [org.infinispan.PERSISTENCE] (keycloak-cache-init) ISPN000554: jboss-marshalling is deprecated and planned for removal
2023-10-16 13:11:44,757 WARN [org.infinispan.CONFIG] (keycloak-cache-init) ISPN000569: Unable to persist Infinispan internal caches as no global state enabled
2023-10-16 13:11:44,857 INFO [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000556: Starting user marshaller 'org.infinispan.jboss.marshalling.core.JBossUserMarshaller'
2023-10-16 13:11:45,344 WARN [io.quarkus.vertx.http.runtime.VertxHttpRecorder] (main) The X-Forwarded-* and Forwarded headers will be considered when determining the proxy address. This configuration can cause a security issue as clients can forge requests and send a forwarded header that is not overwritten by the proxy. Please consider use one of these headers just to forward the proxy address in requests.
2023-10-16 13:11:45,375 INFO [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: node_977034, Site name: null
2023-10-16 13:11:45,385 INFO [org.keycloak.broker.provider.AbstractIdentityProviderMapper] (main) Registering class org.keycloak.broker.provider.mappersync.ConfigSyncEventListener
2023-10-16 13:11:46,538 INFO [org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusJpaUpdaterProvider] (main) Initializing database schema. Using changelog META-INF/jpa-changelog-master.xml
2023-10-16 13:11:48,456 INFO [org.keycloak.services] (main) KC-SERVICES0050: Initializing master realm
2023-10-16 13:11:50,263 INFO [io.quarkus] (main) Keycloak 22.0.4 on JVM (powered by Quarkus 3.2.6.Final) started in 9.031s. Listening on: http://0.0.0.0:8080
2023-10-16 13:11:50,264 INFO [io.quarkus] (main) Profile dev activated.
2023-10-16 13:11:50,264 INFO [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-mariadb, jdbc-mssql, jdbc-mysql, jdbc-oracle, jdbc-postgresql, keycloak, logging-gelf, micrometer, narayana-jta, reactive-routes, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-health, vertx]
2023-10-16 13:11:50,423 INFO [org.keycloak.services] (main) KC-SERVICES0009: Added user 'admin' to realm 'master'
2023-10-16 13:11:50,428 WARN [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.
2023-10-16 13:29:06,153 WARN [org.keycloak.protocol.oidc.utils.OAuth2CodeParser] (executor-thread-48) Code '9504d150-aacd-489b-b913-29966498bc2c' already used for userSession '1f435b0b-7bed-4757-a6c9-7f630c97e985' and client '2925dadc-17a1-4340-958f-0bd7edf4b4a0'.
2023-10-16 13:29:06,155 WARN [org.keycloak.events] (executor-thread-48) type=CODE_TO_TOKEN_ERROR, realmId=6e1f0fe4-639d-4cab-9f67-278c564d57ff, clientId=demo, userId=null, ipAddress=192.168.178.202, error=invalid_code, grant_type=authorization_code, code_id=1f435b0b-7bed-4757-a6c9-7f630c97e985, client_auth_method=client-secret
Below is the keycloak ingress , deployment and service yaml -
apiVersion: v1
kind: Service
metadata:
name: keycloak
namespace: vdi
labels:
app: keycloak
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: keycloak
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: vdi
labels:
app: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:latest
args: ["start-dev"]
env:
- name: KEYCLOAK_ADMIN
value: "admin"
- name: KEYCLOAK_ADMIN_PASSWORD
value: "admin"
- name: KC_PROXY
value: "edge"
- name: PROXY_ADDRESS_FORWARDING
value: "true"
- name: KEYCLOAK_HOSTNAME
value: "keycloak1.co"
ports:
- name: http
containerPort: 8080
readinessProbe:
httpGet:
path: /realms/master
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: keycloak-ingress
namespace: vdi
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- keycloak1.co
secretName: keycloak1-tls-secret
rules:
- host: keycloak1.co
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: keycloak
port:
number: 80
I am using keycloak with start-dev cmd and also the hostname is not getting set on deployment but I can access the URL , is that causing the issue ?
Thanks and Regards Chintu
Hello Chintu,
Please read the keycloak jwt response, and check that the groups
is included in token scope.
It seems that in your case groups
is NOT included in token scope.
Without groups
in token scope, the memberOf rule never runs, as you can read in your user settings session screenshot.
Alexandre
Hello Alexandre ,
From where can I get the keycloak-jwt-token ?
Hello Chintus,
I've added this line in authservice.py in abcdesktopio/oc.pyos:3.1
image.
self.logger.debug( f"dump userinfo data={data}" )
This line dumps the json response from keycloak, so you can get read the userinfo values.
For example you can read on pyos stdout or in pyos container file /var/pyos/logs/trace.log
2023-10-17 11:52:38 authservice [DEBUG ] oc.auth.authservice.ODExternalAuthProvider.getuserinfo:anonymous dump userinfo data=
With the dict values
{
"sub": "f6622d20-f91c-40c9-923d-315b7484e89b",
"resource_access": {"account": {"roles": ["manage-account", "manage-account-links", "view-profile"]}},
"email_verified": false,
"realm_access": {"roles": ["default-roles-master", "monrole", "offline_access", "uma_authorization", "abcdesktop-role"]},
"name": "alexandre devely",
"groups": ["default-roles-master", "monrole", "offline_access", "uma_authorization", "abcdesktop-role"],
"preferred_username": "alex",
"given_name": "alexandre",
"family_name": "devely",
"email": "nobody@nowhere.com"
}
You need to pull the image.
I hope this will help you to read the keycloack groups
Alexandre
Hello Alexandre , Thanks a lot for your help . I have successfully applied ACL with keycloak Earlier I didn't include "group" token in client scope.
Hello Alexandre,
I was trying to implement external Auth method using keycloak . Keycloak has various benefits over Openldap as it provides support for MFA and has an interactive UI . I have deployed keycloak and integrated it with abcdesktop. Following are the keycloak yamls -
apiVersion: apps/v1 kind: Deployment metadata: name: keycloak namespace: vdi spec: replicas: 1 selector: matchLabels: app: keycloak template: metadata: labels: app: keycloak spec: containers:
apiVersion: v1 kind: Service metadata: name: keycloak namespace: vdi spec: selector: app: keycloak ports:
protocol: TCP port: 80 targetPort: 8080
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: keycloak-ingress namespace: vdi annotations: cert-manager.io/cluster-issuer: letsencrypt-prod kubernetes.io/ingress.class: "nginx" spec: tls:
Following is the addition in od.config-
authmanagers: { 'external': { 'providers': { 'keycloak': { 'displayname': 'Keycloak', 'enabled': True, 'basic_auth': True, 'userinfo_auth': True, 'scope' : [ 'openid','email','profile' ], 'client_id': 'demo', 'client_secret': 'W', 'redirect_uri_prefix' : 'https://loginvdi.co/API/auth/oauth', 'redirect_uri_querystring': 'manager=external&provider=keycloak', 'authorization_base_url': 'https://keycloak2.co/auth/realms/test/protocol/openid-connect/auth', 'token_url': 'https://keycloak2.co/auth/realms/test/protocol/openid-connect/token', 'userinfo_url': 'https://keycloak2.co/auth/realms/test/protocol/openid-connect/userinfo', 'policies': { 'acl' : { 'permit': [ 'all' ] }, }
This is the page which appears after clicking "connect with keycloak" on login page -
After this it asks for OTP-
The login is successful and apps are visible as well
Authentication is working fine with 2FA as well , Apps are also visible inside abcdesktop. The main issue which I am facing is on defining rules for getting labels which I can apply for app restrcition to users . Like in openldap- we define rule such as -
'rule-sample': { 'conditions': [ { 'memberOf': 'cn=ship_crew,ou=people,dc=planetexpress,dc=com', 'expected' : True } ], 'expected' : True, 'label': 'shipcrewgrp' }
How should I define rule for keycloak , Like LDAP we can create groups in keyclaok as well. I think implementation for 2FA is really crucial for this project as it enhances the security. Please tell me how should I proceed . Waiting eagerly for your reply.
Thanks and Regards Chintu