noi-techpark / it.bz.noi.community

NOI Community App for the Web
GNU General Public License v3.0
0 stars 1 forks source link

As a NOI community App user I want to use my Open Data Hub credentials to access the NOI Community App. #18

Closed sseppi closed 2 years ago

sseppi commented 2 years ago

In order to integrate Keycloak in the NOI Community App we need to:

Piiit commented 2 years ago

@macteo @matax87 @sseppi

Hi all, I will start the discussion here to provide you all needed information about oauth to login.

Found this repository: https://github.com/thomasdarimont/android-openid-connect/tree/feature/keycloak-oidc-demo

Maybe this is the way to go? It seems that we could create a "NOI Account" inside the system's account manager and just provide that to the application later on. Would that work?

On the other hand, I could just create the normal authentication flow that would redirect to a specific URL you give me with a valid access token if logged in correctly. I do not have experience how that would work with native apps...

In the meantime I create a client on keycloak and send you everything via mail...

Cheers, Peter

Piiit commented 2 years ago

@sseppi Should we tick "Implement a new template for the webview to be integrated in the app"? The main issue has been closed...

matax87 commented 2 years ago

@macteo @matax87 @sseppi

Hi all, I will start the discussion here to provide you all needed information about oauth to login.

Found this repository: https://github.com/thomasdarimont/android-openid-connect/tree/feature/keycloak-oidc-demo

Maybe this is the way to go? It seems that we could create a "NOI Account" inside the system's account manager and just provide that to the application later on. Would that work?

On the other hand, I could just create the normal authentication flow that would redirect to a specific URL you give me with a valid access token if logged in correctly. I do not have experience how that would work with native apps...

In the meantime I create a client on keycloak and send you everything via mail...

Cheers, Peter

@Piiit I can confirm that we are able to perform an OAuth authentication(iOS) with the provided client configuration.

image

Moreover we were able to call the userInfo endpoint using the obtained access token:

{
    "sub": "2ea1c57c-276f-4331-8cf8-08676bfaa6e5",
    "email_verified": true,
    "name": "Authentication Example User",
    "preferred_username": "authtestuser1",
    "given_name": "Authentication Example User",
    "locale": "de",
    "family_name": "",
    "email": "no-reply@opendatahub.bz.it"
}
chiaraDimension commented 2 years ago

@Piiit we used a demo app to try OAuth authentication on android and it works. We can't perform sign out because I think two parameters are missing: end_session_redirect_uri and end_session_endpoint. Do you manage them?

demo-appauth

demo-appauth2

Piiit commented 2 years ago

@chiaraDimension Please try the following:

https://auth.opendatahub.testingmachine.eu/auth/realms/noi/protocol/openid-connect/logout?redirect_uri=https://noi.bz.it

The redirect_uri should be url encoded though... this is just a test, but just tell me which uri would be best

It could be that your lib does these things alone, maybe you need to split the URL above in end_session_redirect_uri and end_session_endpoint

Piiit commented 2 years ago

Could it be in a native app, that you have a redirect similar to noi-community://oauth2redirect/login-callback, that shows then the login form of the app?

chiaraDimension commented 2 years ago

@Piiit end_session_endpoint = https://auth.opendatahub.testingmachine.eu/auth/realms/noi/protocol/openid-connect/logout is ok, but we need another end_session_redirect_uri. The documentation says:

end_session_redirect_uri (required): The redirect URI to use for receiving the end session response. This should be a custom scheme URI (com.example.app:/oauth2redirect/example-provider). Consult the documentation for your authorization server. The value specified here should match the value specified for appAuthRedirectScheme in the build.gradle (Module: app), so that the demo app can capture the response. NOTE: Scheme of the URI should be the same as redirect_uri but callback should be different.

Can you configure end_session_redirect_uri = noi-community://oauth2redirect/end_session-callback on keycloak?

Maybe it could be useful if you also attach some screenshots of your configuration page, is it possible?

Piiit commented 2 years ago

Hi @chiaraDimension

Can you configure end_session_redirect_uri = noi-community://oauth2redirect/end_session-callback on keycloak?

Done

Maybe it could be useful if you also attach some screenshots of your configuration page, is it possible?

image

Hope this helps!

Piiit commented 2 years ago

All other settings have been kept with default values

chiaraDimension commented 2 years ago

Hi @Piiit, could you provide us this data?

  1. configuration for the production environment
  2. some users for the production environment
Piiit commented 2 years ago

@chiaraDimension I created the same configuration on our production keycloak now as it is on the testing environment, the base url is as follows: https://auth.opendatahub.bz.it... you can register your own users, as the registration form is open and can be used by everyone --> accounts.opendatahub.bz.it + sign in

However, I wonder why we are not testing with the test environment I provided to you?

Piiit commented 2 years ago

@chiaraDimension I also added a role with name ACCESS_GRANTED to the login, please check for that and allow only access if it is present... let me know if you need further information

matax87 commented 2 years ago

@chiaraDimension I created the same configuration on our production keycloak now as it is on the testing environment, the base url is as follows: https://auth.opendatahub.bz.it... you can register your own users, as the registration form is open and can be used by everyone --> accounts.opendatahub.bz.it + sign in

However, I wonder why we are not testing with the test environment I provided to you?

@Piiit the sign in page is also available via a direct URL? Because the UI has both a login and signup button.

image
matax87 commented 2 years ago

@chiaraDimension I created the same configuration on our production keycloak now as it is on the testing environment, the base url is as follows: https://auth.opendatahub.bz.it... you can register your own users, as the registration form is open and can be used by everyone --> accounts.opendatahub.bz.it + sign in

However, I wonder why we are not testing with the test environment I provided to you?

@Piiit for testing purposes we may use the sandbox oauth environment, but the app must be tested and will be released with the production oauth environment

Piiit commented 2 years ago

@Piiit for testing purposes we may use the sandbox oauth environment, but the app must be tested and will be released with the production oauth environment

Fine for me, but the Community API does currently not exist on the production environment and therefore it is not connected to the production keycloak server... so the testing needs to be done through the testingmachine.eu endpoint until we release it

However, the login itself can be tested also with the production endpoint of keycloak, just the API calls cannot

matax87 commented 2 years ago

ACCESS_GRANTED

@Piiit what we are suppose to do with it? Do we need to configure the OAuth flow in a specific way in order to check it or what?

Piiit commented 2 years ago

When you login you get a token, and the payload of that token contains roles and scopes (and other things), you just check if the role ACCESS_GRANTED exists for the client it.bz.noi.community, that's all... Keycloak just gives you that token and checks if the login is correct, but the authorization must be done by your logic, because we allow everyone freely to register. So we cannot allow everyone to access the app.

Piiit commented 2 years ago

@Piiit the sign in page is also available via a direct URL? Because the UI has both a login and signup button.

I will forward this request and come back to you when I have a solution

Piiit commented 2 years ago

@matax87 The two urls are as follows:

https://auth.opendatahub.bz.it/auth/realms/noi/protocol/openid-connect/auth?client_id=it.bz.noi.community&redirect_uri=https://noi.bz.it&response_type=code&scope=openid

https://auth.opendatahub.bz.it/auth/realms/noi/protocol/openid-connect/registrations?client_id=it.bz.noi.community&redirect_uri=https://noi.bz.it&response_type=code&scope=openid

Change the base to https://auth.opendatahub.testingmachine.eu if you need the test environment, and adapt the redirect_uri for your needs

Thx @RudiThoeni

Piiit commented 2 years ago

@matax87 Please make them configurable, so we can easily switch during build

matax87 commented 2 years ago

When you login you get a token, and the payload of that token contains roles and scopes (and other things), you just check if the role ACCESS_GRANTED exists for the client it.bz.noi.community, that's all... Keycloak just gives you that token and checks if the login is correct, but the authorization must be done by your logic, because we allow everyone freely to register. So we cannot allow everyone to access the app.

@Piiit the payload doesn't contain any role. Do you have a working example?

{
    "access_token": "eyJhbGciOiJ.g21w0w",
    "expires_in": 300,
    "refresh_expires_in": 3600,
    "refresh_token": "eyJhbGci...xkIBx44",
    "token_type": "Bearer",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIg...BxX5FcNw",
    "not-before-policy": 1606215656,
    "session_state": "b71918ec-4fe1-4ab7-ab28-ec83aa3e878d",
    "scope": "openid email profile"
}
macteo commented 2 years ago

but the authorization must be done by your logic

@Piiit this is pretty uncommon and a security risk as the client cannot be trusted. We can proceed anyway, but it must be acknowledged by NOI.

Also if you can help @matax87 solve the issue above as we are not able to see any role expressed in the payload. Thanks

Piiit commented 2 years ago

When you login you get a token, and the payload of that token contains roles and scopes (and other things), you just check if the role ACCESS_GRANTED exists for the client it.bz.noi.community, that's all... Keycloak just gives you that token and checks if the login is correct, but the authorization must be done by your logic, because we allow everyone freely to register. So we cannot allow everyone to access the app.

@Piiit the payload doesn't contain any role. Do you have a working example?

{
  "access_token": "eyJhbGciOiJ.g21w0w",
  "expires_in": 300,
  "refresh_expires_in": 3600,
  "refresh_token": "eyJhbGci...xkIBx44",
  "token_type": "Bearer",
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIg...BxX5FcNw",
  "not-before-policy": 1606215656,
  "session_state": "b71918ec-4fe1-4ab7-ab28-ec83aa3e878d",
  "scope": "openid email profile"
}

Hi, I will give the two dimension users that privilege now

Piiit commented 2 years ago

but the authorization must be done by your logic

@Piiit this is pretty uncommon and a security risk as the client cannot be trusted. We can proceed anyway, but it must be acknowledged by NOI.

Also if you can help @matax87 solve the issue above as we are not able to see any role expressed in the payload. Thanks

You get a token that you can afterwards use for API calls, that token has been verified by Keycloak and is therefore authenticated. The login is general, where a logged user has different privileges. This is called role-based security on Keycloak, but if you forward then to the inner parts of the app is app specific and must be checked on app side. This is a normal workflow for this. It is not that we just check a flag, but a validated token. Also the ACCESS_GRANTED check is a plus to the regular token validation, and not a replacement...

matax87 commented 2 years ago

When you login you get a token, and the payload of that token contains roles and scopes (and other things), you just check if the role ACCESS_GRANTED exists for the client it.bz.noi.community, that's all... Keycloak just gives you that token and checks if the login is correct, but the authorization must be done by your logic, because we allow everyone freely to register. So we cannot allow everyone to access the app.

@Piiit the payload doesn't contain any role. Do you have a working example?

{
    "access_token": "eyJhbGciOiJ.g21w0w",
    "expires_in": 300,
    "refresh_expires_in": 3600,
    "refresh_token": "eyJhbGci...xkIBx44",
    "token_type": "Bearer",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIg...BxX5FcNw",
    "not-before-policy": 1606215656,
    "session_state": "b71918ec-4fe1-4ab7-ab28-ec83aa3e878d",
    "scope": "openid email profile"
}

Hi, I will give the two dimension users that privilege now

@Piiit which users? We don't know their used id and password. Can you provide us this information via email?

Thank you

Piiit commented 2 years ago

@matax87 You made them, the usernames are your emails... I see two users with @dimension.it emails

matax87 commented 2 years ago

@matax87 You made them, the usernames are your emails... I had two users with @dimension.it emails

@Piiit ok. Those accounts were created in production and I thought you were talking of some account on the testing machine.

Piiit commented 2 years ago

@matax87 I understand, so please create accounts on the testing auth server and ping me afterwards, so I can give you the privileges to access the community app... see the comment above for the URL to do so. Let me know if you need any other information.

matax87 commented 2 years ago

@matax87 I understand, so please create accounts on the testing auth server and ping me afterwards, so I can give you the privileges to access the community app... see the comment above for the URL to do so. Let me know if you need any other information.

I've just created a generic one on DEV at DIMENSION dot IT

Piiit commented 2 years ago

Done, please test

matax87 commented 2 years ago

Done, please test

the payload still doesn't contain any role.

{
    "access_token": "eyJhbGciO...mysXgoXsuXpb8WoA",
    "expires_in": 300,
    "refresh_expires_in": 3600,
    "refresh_token": "eyJhbGciOiJIUzI1...FT910",
    "token_type": "Bearer",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOi...LUBme70Q-Cg",
    "not-before-policy": 1606215656,
    "session_state": "8482ee1c-7252-4cbb-994f-3a733f89a186",
    "scope": "openid email profile"
}

@Piiit could you verify it with your OAuth client and provide me a working examples (i.e. one that include roles)?

Thank you!

Piiit commented 2 years ago

@matax87 The role is not in the response JSON, but in the token itself which is a JWT...this might also explain your concern in other comments. To verify my thoughts, please copy/paste the "access_token" content to https://jwt.io and see if you have there everything you need as JWT payload. Your application needs to decode that JWT as well and get the role from there. That should be an out-of-the-box command if you have a Keycloak or OAuth2 lib...

matax87 commented 2 years ago

@matax87 The role is not in the response JSON, but in the token itself which is a JWT...this might also explain your concern in other comments. To verify my thoughts, please copy/paste the "access_token" content to https://jwt.io and see if you have there everything you need as JWT payload. Your application needs to decode that JWT as well and get the role from there. That should be an out-of-the-box command if you have a Keycloak or OAuth2 lib...

Ok done. It was not clear that we had a jwt token from the oauth 2 flow.

Thank you!

matax87 commented 2 years ago

@Piiit the auth flow is almost finished, but we have some doubts:

  1. regarding the JWT token we also need to verify its signature or just the roles for our client id?
  2. the access token duration is 5 minutes and the refresh token duration is 60 minutes on the testing machine and 120 in the production one. For the testing machine these kind of durations are fine; but we think that on production they must be incremented/refresh token that never expires; otherwise, logged user will be automatically logged out.