eclipse-hawkbit / hawkbit

Eclipse hawkBit™
https://projects.eclipse.org/projects/iot.hawkbit
Eclipse Public License 2.0
466 stars 189 forks source link

OIDC Support (OIDC vs OAuth2) #1132

Open dennis-kuypers-gcx opened 3 years ago

dennis-kuypers-gcx commented 3 years ago

I'm currently setting up hawkbit Management UI SSO using Azure AD via OIDC.

I noticed that in OidcUserManagementAutoConfiguration the access token is parsed and validated. This fails for us with an invalid signature.

Here's what I think what is going on. I might be wrong here, so please correct me:

In OIDC the access token is used by the client to access the userinfo endpoint. The client is not supposed to look at the contents of the access token - it's (usually) an opaque value as it is in OAuth2. The primary "subject" here is the id_token which is used for authentication.

So to me it looks like that hawkbit is using the returned access token for 2 different purposes 1) access userinfo endpoint (ok - authN) 2) parsing ("authorities"/claims) (not ok? - authZ)

Considering that OIDC is about authentication but hawkbit seemingly wants to externalize authorization I'm not sure how to set this up correctly.

aktivk commented 3 years ago

Hi @dennis-kuypers-gcx Hawkbit uses the authorities/claims from token to check the permissions to access the respective resources. I am afraid that you might need to adjust the code according to your needs. Have a look at this issue. Let me know if this helps

dennis-kuypers-gcx commented 3 years ago

Hello @aktivk Thank you for your response. I'm still a bit confused to be honest.

I believe what would help me understand if you could tell me, in OAuth2 parlance, who assumes what role here? Who are the resource owner, resource server, client and authorization server?

aktivk commented 3 years ago

Hi @dennis-kuypers-gcx In regards of Hawkbit and according to the OAuth concept: Resource Owner is an end user, Resource server is the Hawkbit resource API, Client is the Hawkbit UI and authorization server is the OAuth access token provider (in your case it's AZURE AD). You need certain ROLES in your access token claims to access the Hawkbit UI and API. These Roles are

[
        "READ_TARGETS",
        "UPDATE_TARGETS",
        "CREATE_TARGETS",
        "DELETE_TARGETS",
        "READ_REPOSITORY",
        "UPDATE_REPOSITORY",
        "CREATE_REPOSITORY",
        "DELETE_REPOSITORY",
        "READ_TARGET_SECURITY_TOKEN",
        "DOWNLOAD_REPOSITORY_ARTIFACT",
        "TENANT_CONFIGURATION",
        "READ_ROLLOUT",
        "UPDATE_ROLLOUT",
        "CREATE_ROLLOUT",
        "DELETE_ROLLOUT",
        "HANDLE_ROLLOUT",
        "APPROVE_ROLLOUT"
]

You can add these roles in your access token if there are any such options to do it like an example would be in Keycloak. Or you can modify the Hawkbit code (Fork it) according to your need in the class - org/eclipse/hawkbit/autoconfigure/security/OidcUserManagementAutoConfiguration.java:276

dennis-kuypers-gcx commented 3 years ago

If hawkbit is the resource server then why does hawkbit use the access token to read from azure? Wouldn't that make azure = resource server and hawkbit = client?

It looks like there are two OAuth access tokens thrown together (one against the hawkbit api and one against userinfo/OIDC). This seems to be the reason why hawkbit doesn't work with Azure, Auth0 (and maybe other OIDC providers).

Am I drawing the correct conclusions here?

aktivk commented 3 years ago

Hi @dennis-kuypers-gcx , You are partially right here - "It looks like there are two OAuth access tokens thrown together (one against the hawkbit api and one against userinfo/OIDC)."

Hawkbit UI uses userinfo/OIDC to authenticate and authorize the resources internally. Currently, Hawkbit does not support resource API access with the OAuth2 access token. At the moment, Hawkbit management API is only accessible by basic Auth

dennis-kuypers-gcx commented 3 years ago

Hello @aktivk,

I'm only talking about the Management UI here. When I said "hawkbit api" I actually meant the Management UI, sorry.

Actually Hawkbit uses the access token to authorize the user because it gets permissions/authorities/roles/assignments from the access token, see https://github.com/eclipse/hawkbit/blob/732e8cc746d1df167641ca704e1626fc6101c359/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/OidcUserManagementAutoConfiguration.java#L158

OIDC would be authentication only: hawkbit would only get identity via OIDC and then manage assigments of roles internally.

I believe the intended way with OIDC is to only communicate something like group membership and then assign permissions to those groups within the application (so hawkbit in this case). Since hawkbit outsources this assignment by expecting assignments in the access token it's actually not doing (only) OIDC - it's a mix.

One possible solution to enable more people to use Hawkbit with OIDC providers (!= KeyCloak) would be to also check the id_token for assignments. I believe that would be a reasonable workaround. That would probably need one additional setting to allow flexibility when naming the claims.

Do you think that would be a solution to the issue that I'm facing?

aktivk commented 3 years ago

Yes, It is a mix of Authentication and Authorization. Checking id_token can provide more flexibility for validating claims and yes, this could also be one way to solve your issue.

dennis-kuypers-gcx commented 3 years ago

Hello @aktivk

I would try to get this implemented in a backward compatible fashion. Do you think we could get this solution merged back with the project? Can you think of other factors to consider when implementing this?

aktivk commented 3 years ago

Hi @dennis-kuypers-gcx Feel free to propose the solution. We will review and also verify about the other additional factors if needed.