MaikuB / flutter_appauth

A Flutter wrapper for AppAuth iOS and Android SDKs
274 stars 246 forks source link

sample keycloak integration #506

Open kstan79 opened 5 months ago

kstan79 commented 5 months ago

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
        ),
      );
zynzszyn521 commented 4 months ago

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

kstan79 commented 4 months ago

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.
zynzszyn521 commented 4 months ago

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

kstan79 commented 4 months ago

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?

zynzszyn521 commented 3 months ago

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?

kstan79 commented 3 months ago

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

zynzszyn521 commented 3 months ago

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

akoyl commented 2 months ago

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