flutter_appauth icon indicating copy to clipboard operation
flutter_appauth copied to clipboard

sample keycloak integration

Open kstan79 opened this issue 1 year ago • 8 comments

i think the provided example very bad for keycloak user, so I contribute some example of setting for others people to refer, I hope you guys can prepare better sample for community.

final String _clientId = 'keycloak-client-id';
  final String _redirectUrl = 'com.domain.appname:/oauthredirect';
  final String _issuer = 'https://login.your.url/realms/yourrealm';  // you may put `auth` behind hostname if your keycloak very old
  final String _discoveryUrl =
      'https://login.your.url/realms/yourrelam/.well-known/openid-configuration';
  final String _postLogoutRedirectUrl = 'com.domain.yourapp:/';

...
authorizationEndpoint:
        'https://login.your.url/realms/yourrealm/protocol/openid-connect/auth',
    tokenEndpoint:
        'https://login.your.url/realms/yourrealm/protocol/openid-connect/token',
    endSessionEndpoint:
        'https://login.your.url/realms/yourrealm/protocol/openid-connect/logout',
.....


final AuthorizationTokenResponse? result =
          await _appAuth.authorizeAndExchangeCode(
        AuthorizationTokenRequest(
          _clientId, _redirectUrl,
          serviceConfiguration: _serviceConfiguration,
          scopes: _scopes,
          preferEphemeralSession: preferEphemeralSession,
          clientSecret: '_your_client_secret_obtain_from_somewhere'  //original example not include this properties cause authorization never success
        ),
      );

kstan79 avatar Jun 22 '24 14:06 kstan79

Hello, I'm encountering an issue with Keycloak where I cannot log out. Could you please help guide me through this? Flutter endSession code: final String _postLogoutRedirectUrl = 'com.domain.yourapp:/' Keycloak client config: Valid post logout redirect URIs:com.domain.yourapp:/ But when call endSession ,show: Invalid redirect uri

zynzszyn521 avatar Jul 19 '24 04:07 zynzszyn521

hi, after long research. I notice that the proper implementation of keycloak in flutter is:

  1. create loginform.dart in flutter
  2. perform server side authentication (no store client secret in flutter app) at backend
  3. store refresh token and access token at client side.
  4. before any api request, verify refresh token expiry, if near expire then obtain new access token with refresh token via backend
  5. both token and expried time can store in flutter using securestorage library.

For security reason, we dont want store client secret in mobile app thats why:

  1. flutter side no perform any api with keycloak, it authenticate via backend server
  2. backend will handle all keycloak manners.

kstan79 avatar Jul 19 '24 05:07 kstan79

Thank you for your reply。 My Fluttter app login no issue ,but when i click logout button and goto auth web page ,it show errr。

await appAuth.endSession(EndSessionRequest(
          idTokenHint: '<idToken>',
          postLogoutRedirectUrl: '<postLogoutRedirectUrl>',
          serviceConfiguration: AuthorizationServiceConfiguration(authorizationEndpoint: '<authorization_endpoint>',  tokenEndpooint: '<token_endpoint>', endSessionEndpoint: '<end_session_endpoint>'));

I confirm the authorization_endpoint\token_endpoint\end_session_endpoint config is correct ,but I am not sure postLogoutRedirectUrl how to set , i give _postLogoutRedirectUrl = 'com.domain.yourapp:/' and keycloak client setting page is " Valid post logout redirect URIs:com.domain.yourapp:/ " ,

image

cec7922d674f1fc765aa547e60fb0ba

zynzszyn521 avatar Jul 19 '24 05:07 zynzszyn521

As I mentioned, no matter login, refresh, or logout all shall implement at server side cause keep secret in mobile app is bad. When you need to revoke your secret you will have to republish your app and request all user update app. At the time your app malfunction and will be your nightmare.

Anyhow, you can simply delete your token without run logout isn't it?

kstan79 avatar Jul 19 '24 08:07 kstan79

Sorry, I need to ask one more question. I use nginx for keycloak server ,For security reasons, I have set up CSP add_header Content-Security-Policy "form-action 'self' https://fuse.XXX.com;"; However, when I log in, it shows an error. auth:1 Refused to send form data to 'https://fuse.XXX.com/auth/realms/master/login-actions/authenticate?session_code=eElrml7zOz7QJFTqkhpVaO9l3IIYVVxsLQrefutzHVU&execution=a5833fb9-308a-4f1b-a12b-12b84594547d&client_id=fuse.mobile.client&tab_id=S-011gIiFqI' because it violates the following Content Security Policy directive: "form-action 'self' https://fuse.XXX.com". From the error message, the accessed address and the CSP-configured address are the same. Why is there still an error?

zynzszyn521 avatar Aug 06 '24 05:08 zynzszyn521

i not so sure what cause that, maybe 'com.domain.yourapp:/'?

kstan79 avatar Aug 06 '24 06:08 kstan79

you means add 'com.domain.yourapp:/' to CSP config?

zynzszyn521 avatar Aug 06 '24 07:08 zynzszyn521

Can someone provide a simple but complete example for login and sign-in from a mobile app to keycloack? Thanks in advance!

akoyl avatar Sep 11 '24 16:09 akoyl

Closing this as the purpose of the example app was to demonstrate usage of the plugin in general and should be adaptable to various identity providers provided they implement OAuth 2 and the devs have the knowledge about both OAuth and the identity provider. The other and main reason for closing is the OP (@kstan79 ) mentions how the lack of passing a client secret is what caused issues but specifying a client secret in the code and was backtracked later on too as mentioned in https://github.com/MaikuB/flutter_appauth/issues/506#issuecomment-2238190315. Note that specifying a client secret is bad practice in client apps and should only be for backend applications

MaikuB avatar Dec 10 '24 10:12 MaikuB