Authenticate flutter app with keycloak and openid_client
Asked Answered
R

1

7

I'm trying to authenticate my flutter app to keycloak through openid_client

following the repo example, I've wrote an authentication function like this

authenticate() async {

  // parameters here just for the sake of the question
  var uri = Uri.parse('https://keycloak-url/auth/realms/myrealm');
  var clientId = 'my_client_id';
  var scopes = List<String>.of(['openid', 'profile']);
  var port = 4200;
  var redirectUri = Uri.parse('http://localhost:4200');

  var issuer = await Issuer.discover(uri);
  var client = new Client(issuer, clientId);

  urlLauncher(String url) async {
    if (await canLaunch(url)) {
      await launch(url, forceWebView: true);
    } else {
      throw 'Could not launch $url';
    }
  }

  var authenticator = new Authenticator(client,
      scopes: scopes,
      port: port,
      urlLancher: urlLauncher,
      redirectUri: redirectUri);

  var c = await authenticator.authorize();
  closeWebView();

  var token= await c.getTokenResponse();
  print(token);
  return token;
}

when I call the function, a webview popup appears and I can login through keycloak, but when the popup closes I get this error at the c.getTokenResponse():

Exception has occurred. NoSuchMethodError (NoSuchMethodError: The getter 'length' was called on null. Receiver: null Tried calling: length)

inspecting the Credential c, I can see that the TokenResponse has only "state", "session_state" and "code" fields

what am I missing?

Roderich answered 23/3, 2020 at 13:20 Comment(1)
For anyone interested to implement authorisation flow on the web. It appears this is a sample for android/ios. Currently the Authenticator that openid_client provides for the browser supports only the implicit flow as far as I can see from the source code. I'm trying to figure out if I can write my own Authenticator that can support authorisation flow on the web. I was hopping to find this as part of the library. No clear docs/reason are provided as to why implicit flow is used on the web as long as it is currently deprecated and advised against.Aliunde
R
6

I've been answered on github (link), so I'll copy the solution here:


On mobile devices you should use the PKCE flow. This is automatically selected when you omit the redirect uri in the Authenticator constructor.

So, it should be:

var authenticator = new Authenticator(client,
      scopes: scopes,
      port: port,
      urlLancher: urlLauncher,);

Make sure you add the uri http://localhost:4200/ (including the trailing slash) to Valid Redirect URIs in keycloak.

image

Make sure you add the uri http://localhost:4200/ (including the trailing slash) to Valid Redirect URIs in keycloak.

Roderich answered 24/3, 2020 at 13:25 Comment(4)
Do you have to open browser window for this?Walrath
openid_client plugin opens a webview when you call await authenticator.authorize();Roderich
Is there any other way?Walrath
You can use the resource owner password flow, but thats OAuth2 not OpenID and is not recommended due to security reasons. And you loose SSO and federation providers.Moshemoshell

© 2022 - 2024 — McMap. All rights reserved.