nokia / kong-oidc

OIDC plugin for Kong
Apache License 2.0
454 stars 320 forks source link

Guidance on implementing Authorization (ACL and or RBAC) #135

Closed lyndon160 closed 3 years ago

lyndon160 commented 4 years ago

Ideally, this plugin could be used to provide authorization, allowing certain OIDC clients to access certain resources. Currently a new ingress has to be created to support this.

This could implemented via a simple ACL or RBAC with OAuth https://auth0.com/docs/authorization/concepts/rbac

As far as I understand, this plugin only focuses on Authentication and does not support authorization.

What is the recomended way of providing authorization? Edit this plugin to support Authorization? Or use it with in conjuntion with another plugin?

mssaisandeep commented 4 years ago

It's better to have another plugin. That way, later if this plugin version got updated You can cleanly update on your end.

BTW, we already implemented RBAC plugin with Keycloak (IDP). Actually, it's pretty easy and doable.
Fell free to ask questions, I can help you out.

lyndon160 commented 4 years ago

@mssaiandeep, thanks for your response and eagerness to help!

I'm particularly looking at providing authorisation to services behind Kong rather than the Kong API.

For a simple example: without modifying the code of each service, i'd like to have two tokens, one with scope A, and another with scope B. Scope A should be able to reach to serivce Y and Scope B should be able to reach service X but not the otherway around.

From the ACL, RBAC, and JWT plugins i've seen for Kong it's not clear that they quite fit this criteria.

Can you talk somemore about the plugin you've used, and whether/how it supports the flow i've described above? I assume you're just using Kong's default RBAC plugin?

ahmednawazkhan commented 4 years ago

Hi @mssaisandeep. I just came across the ACL problem now. after using oidc plugin i need to authorize people with keycloak. can you please give an overview guide on how to create this plugin (RBAC plugin with Keycloak (IDP)). It will be very helpful. many thanks

sandeepmachiraju commented 4 years ago

We at ioTium built our own plugin. Basically we use keycloak for Authorization.

Keycloak has a concept called Permissions, Policies and Resources. So we have a plugin which will get all info from keycloak and make decisions whether to allow request or not.

In keycloak there is also a policy validator where you can send id_token and ResourceID to keycloak and it will provide the result whether user has access or not. Based on that you can make decisions.

Instead of decisions per every request we use Ngx cache for quick access.

sandeepmachiraju commented 4 years ago

Soon we are going to open-source that plugin for community usage.

lyndon160 commented 4 years ago

@sandeepmachiraju great! Link it here when it's available.

ahmednawazkhan commented 4 years ago

That is great. please share the link here when you publish. can u please share the endpoint and parameters it requires for policy validator or share a link that explains it. many thanks

affanshahid commented 4 years ago

@sandeepmachiraju awesome, please share when available.

canattofilipe commented 4 years ago

I have found an interesting kong plugin that perform RBAC authentication (see keycloak-rbac). It does not solve all my problems but give me an ideia of how to implement my own.

xoancosmed commented 4 years ago

Hi!

Any news about this? In my case I just want to require a certain role (defined in KeyCloak) to access a certain service (for example, to access "service1", the role "admin" or "role1" would be needed, and for the service "service2", the role "admin" or "role" would be needed).

I've been taking a loock to keycloak-rbac, but I wasn't able to get it working.

Thanks, Xoán

canattofilipe commented 4 years ago

Hi!

Any news about this? In my case I just want to require a certain role (defined in KeyCloak) to access a certain service (for example, to access "service1", the role "admin" or "role1" would be needed, and for the service "service2", the role "admin" or "role" would be needed).

I've been taking a loock to keycloak-rbac, but I wasn't able to get it working.

Thanks, Xoán

@xoancosmed, Have you tried kong-plugin-jwt-keycloak, this one is very well documented and can work together nokia-oidc as explained here https://github.com/gbbirkisson/kong-plugin-jwt-keycloak/issues/7

xoancosmed commented 4 years ago

@canattofilipe Thanks!

harsh4870 commented 4 years ago

@canattofilipe thanks for suggestion.

Hi! Any news about this? In my case I just want to require a certain role (defined in KeyCloak) to access a certain service (for example, to access "service1", the role "admin" or "role1" would be needed, and for the service "service2", the role "admin" or "role" would be needed). I've been taking a loock to keycloak-rbac, but I wasn't able to get it working. Thanks, Xoán

@xoancosmed, Have you tried kong-plugin-jwt-keycloak, this one is very well documented and can work together nokia-oidc as explained here gbbirkisson/kong-plugin-jwt-keycloak#7

@xoancosmed i am also looking for same solution to creat POC :

In my case I just want to require a certain role (defined in KeyCloak) to access a certain service (for example, to access "service1", the role "admin" or "role1" would be needed, and for the service "service2", the role "admin" or "role" would be needed).

anything update so far ? working for you ?

Voronenko commented 4 years ago

@harsh4870 Not sure, if it suits you, but assuming you can provide granted roles to user in scope of your jwt token claims, you can implement some custom plugin ( as a basic example https://github.com/Voronenko/kong-plugin-sa-jwt-claims-validate ) after the kong jwt plugin, which would do additional access control

harsh4870 commented 4 years ago

@harsh4870 Not sure, if it suits you, but assuming you can provide granted roles to user in scope of your jwt token claims, you can implement some custom plugin ( as a basic example https://github.com/Voronenko/kong-plugin-sa-jwt-claims-validate ) after the kong jwt plugin, which would do additional access control

@harsh4870 Not sure, if it suits you, but assuming you can provide granted roles to user in scope of your jwt token claims, you can implement some custom plugin ( as a basic example https://github.com/Voronenko/kong-plugin-sa-jwt-claims-validate ) after the kong jwt plugin, which would do additional access control

@Voronenko thanks for suggestion, right now i am using this plugin nokid-oidc it's working well, however, now just looking for a way to authenticating requested based on scope.

so now if i try to implement plugin further as per your suggestion: https://github.com/Voronenko/kong-plugin-sa-jwt-claims-validate to compare or check role. i may need to change priority inside kong ? is there anything ?

in your suggested link i didn't found lua rock installation how to add in Dockefile and extend it.

thanks once again for suggestion.

xoancosmed commented 4 years ago

@xoancosmed i am also looking for same solution to creat POC :

In my case I just want to require a certain role (defined in KeyCloak) to access a certain service (for example, to access "service1", the role "admin" or "role1" would be needed, and for the service "service2", the role "admin" or "role" would be needed).

anything update so far ? working for you ?

Hi @harsh4870,

I got it working with the plugin kong-plugin-jwt-keycloak suggested by @canattofilipe. This is how I configured it, but don't trust me at all, I am still working on this:

As you can see, I have to say to the jwt-keycloak plugin that it has to look for the JWT token in the "X-Access-Token" header instead of the traditional "Authorization" header. In this case, "ADMIN" is a role I have defined in the KeyCloak client (which I named "kong"):

imagen

Hope this helps, Xoán Cosmed

harsh4870 commented 4 years ago

@xoancosmed Thanks a ton for the suggestion. i am using a kong with Konga-UI dashboard and Postgres let me try and check it out. thanks once again for the quick response.

Voronenko commented 4 years ago

@harsh4870 In my scenario I had two approaches together in one application : web was using nokia oidc plugin + I have also server side clients, which use machine to machine authorization scheme. In both scenarios I receive JWT token, but in order to add application specific information to token - m2m requires to define hooks, while for application that was using nokia oidc - I had to define rules.

https://medium.com/@V_Voronenko/microservices-integrating-kong-api-gateway-with-auth0-authentication-provider-6b6a9f27a69a

Mentioned above https://github.com/gbbirkisson/kong-plugin-jwt-keycloak is also very promising, as it was developed specifically to use with keycloak, I was dealing with auth0 mostly.

harsh4870 commented 4 years ago

@Voronenko @xoancosmed working like a charm thanks a lot for suggestion and helping me out.

ghost commented 4 years ago

hey im very new in coding and authentification...i want to secure apps with kong and keycloak...the authentication works perfectly but the authorization doesnt. could i do this with these implementation? @xoancosmed where can i find the docker-compose file? @harsh4870 is it working for you? i want to work with konga and postgres too...could you help me to implement the plugin?

Thank you very much !

harsh4870 commented 4 years ago

@Chrenken Yes authorization working for me with nokia-oidc plugin and for authentication have used jwt-keycloak plugin to restrict user based on role.

Plugin links :

Docker file for adding both plugin inside Kong : https://github.com/gbbirkisson/kong-plugin-jwt-keycloak/issues/7#issuecomment-623964792

Other all steps explained in this comment : https://github.com/nokia/kong-oidc/issues/135#issuecomment-647487795

For connecting kong with Postgres, you can use the official helm chart and update it as per requirement.

ghost commented 4 years ago

@harsh4870 thank you! I will test it soon as possible =)

ghost commented 4 years ago

@harsh4870 Oh is the third link correct? I could not find a docker file there...and maybe could you post or send me your docker-compose file? because i dont know where i have to add these JWT_KEYCLOAK_PRIORITY: "900" variable? thanks

harsh4870 commented 4 years ago

@Chrenken i am not using docker-compose file, i have deployed everything on k8s demo cluster and just completed demo of authorization and authentication. also, i have updated third link : https://github.com/gbbirkisson/kong-plugin-jwt-keycloak/issues/7#issuecomment-623964792

however, let me know if you want to see the whole demo with keycloak, kong and plugins before i terminate instances. you can please email me, email available in my profile.

xoancosmed commented 4 years ago

Hi! Sorry for the delay.

@Chrenken you have to add JWT_KEYCLOAK_PRIORITY to your environment variables. In case you are using the "docker run" command, just add -e JWT_KEYCLOAK_PRIORITY=900. If you are using Docker Compose like me, you have to add it to the "environment" section of your YAML; here you have my Docker Compose as reference (I'm using DB-less mode, so it's going to be different your you):

version: '3'

services:
  kong:
    container_name: kong
    build: .
    image: kong-oicd
    volumes:
      - "/home/xcosmed/kong/config:/usr/local/kong/declarative"
    environment:
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: "/usr/local/kong/declarative/kong.yml"
      KONG_PROXY_ACCESS_LOG: "/dev/stdout"
      KONG_ADMIN_ACCESS_LOG: "/dev/stdout"
      KONG_PROXY_ERROR_LOG: "/dev/stderr"
      KONG_ADMIN_ERROR_LOG: "/dev/stderr"
      KONG_ADMIN_LISTEN: "0.0.0.0:8001, 0.0.0.0:8444 ssl"
      KONG_PLUGINS: "oidc,jwt-keycloak,bundled,acme,request-transformer"
#      KONG_LOG_LEVEL: "debug"
      JWT_KEYCLOAK_PRIORITY: "900" # <------------------------------------------- HERE
      KONG_LUA_SSL_TRUSTED_CERTIFICATE: "/etc/ssl/certs/ca-certificates.crt"
    ports:
      - 80:8000
      - 443:8443
      - 8001:8001
      - 8444:8444
    networks:
      - net
    restart: unless-stopped

networks:
  net:
    external: false

If you are using Kuberneted (which I'm going to be using in a near future), add it to the "env" sections of your deployment.

The Dockerfile, as @harsh4870 mentioned and as I wrote in my first answer, it's in this thread: https://github.com/gbbirkisson/kong-plugin-jwt-keycloak/issues/7#issuecomment-623964792.

ghost commented 4 years ago

@xoancosmed thank you very much! The Plugins are working!! But could you give me maybe our Keycloak Configuration? Because i always get these message: {"message":"Token issuer not allowed"}. I create a user and give him the role ADMIN but get these message. So i think the configuration is not correct. Should i create two Clients? Because if the client is public then i cant get the secret.

Thank you for your help!!! Wish you a nice weekend!

xoancosmed commented 4 years ago

@Chrenken If you recieve that message is a good sign, because that means that the plugin is reading the JWT token. You have to be careful about how you define the roles, probably you did it wrong.

Please refer to the screenshot of my comment explaining all the steps (https://github.com/nokia/kong-oidc/issues/135#issuecomment-647487795). In that example, I defined different roles for each KeyCloak client; I created a role "ADMIN" in my client "kong", that's why I wrote "kong:ADMIN" in the plugin config.

  - name: jwt-keycloak
    config:
      allowed_iss:
      - "https://<your_keycloak_url>/realms/master"
      internal_request_headers:
      - "X-Access-Token"
      client_roles:
      - "kong:ADMIN"

If you want to define global roles instead of client roles (as I did in https://github.com/nokia/kong-oidc/issues/135#issuecomment-647487795), you have to change the plugin config to something like this:

  - name: jwt-keycloak
    config:
      allowed_iss:
      - "https://<your_keycloak_url>/realms/master"
      internal_request_headers:
      - "X-Access-Token"
      roles:
      - "ADMIN"

Similarly, if you want to define realm roles instead of client roles (as I did in https://github.com/nokia/kong-oidc/issues/135#issuecomment-647487795), you have to change the plugin config to something like this:

  - name: jwt-keycloak
    config:
      allowed_iss:
      - "https://<your_keycloak_url>/realms/master"
      internal_request_headers:
      - "X-Access-Token"
      realm_roles:
      - "ADMIN"
harsh4870 commented 4 years ago

Can anyone please help.

i am looking for help on how to setup authentication like Github using Keycloak.

i am using Kong API gateway with keycloak along with OIDC plugin with JWT-keycloak.

As in GitHub we have organization repo and each user has different access in an organization repo (read/write) or i can add a specific user to the organization with only one repository access.

i think Github manage this by forming URL

https://github.com/org-name/username/reponame and restricting user at API gateway level if no access there.

can someone please help me with how to achieve it using the same with keyclaok and kong API gateway.

xoancosmed commented 3 years ago

Hi @harsh4870 sorry for the delay. For that purpose I think you should create your own plugin, as this behavior is very specific, or manage this in your services instead of in the api gw. As a base for your plugin you could use an existing one, like the jwt-keycloak, and add your own code for requesting the owners of the resource and check if your user meets the requirements.

xoancosmed commented 3 years ago

I think the problem is that Nokia's kong-idc plugin sets some cookies, and with curl your are not sending those. Probably the 302 response you receive is a redirection to the login endpoint of your keycloak.

harsh4870 commented 3 years ago

no, i just resolved 302 issue by using two clients one is confidential and another public working like charm now. thanks again for your reply.

sharpedavid commented 3 years ago

@harsh4870 wrote:

@Chrenken Yes authorization working for me with nokia-oidc plugin and for authentication have used jwt-keycloak plugin to restrict user based on role.

Plugin links :

Docker file for adding both plugin inside Kong : gbbirkisson/kong-plugin-jwt-keycloak#7 (comment)

Other all steps explained in this comment : #135 (comment)

For connecting kong with Postgres, you can use the official helm chart and update it as per requirement.

Hi @harsh4870 I appreciate you taking the time to share this, but I wanted to warn people to read that "Docker file for adding both plugin inside Kong" closely. It's not using the main nokia-oidc or kong-plugin-jwt-keycloak plugins: it's using forks of both. The nokia-oidc fork bumps the version of a dependency, and the kong-plugin-jwt-keycloak fork fork adds the new internal_request_header option. For my team this is a maintenance concern, so I wanted to highlight it for others following along.