openid/AppAuth-JS

Angular ionic sample

layinka opened this issue · 31 comments

Hi,
Do you have an example of how i can use this in a mobile android app for Ionic

What are you trying to accomplish ? On Mobile Android you could use the Google APIs (Google Sign In) which is native, and gives you the functionality you need. If you want to support a non GMS device, you could also consider using AppAuth-Android.

Sorry about the delay in replying. For an ionic app, you will have to implement the hooks for launching a custom tab, and handling the redirect either via a Universal URL or an Intent on Android.
I can offer guidance, and the goal of the library has always been to make this very simple.

The key is to implement another AuthorizationRequestHandler like the one here:
https://github.com/openid/AppAuth-JS/blob/master/src/node_support/node_request_handler.ts#L30

@layinka if you have more questions please feel free to re-open this issue.

@layinka any progress?

@BenjaminKauer I wrote an article that shows how to do Ionic authentication with OAuth, maybe you'll find it useful. It doesn't use AppAuth-JS, but it'll get the job done.

I also integrated something similar in the Ionic Module for JHipster, but ended up using angular-oauth2-oidc so it'd work with Okta and Keycloak. You can read about how it works in this blog post. Someone recently contributed a way to make it even better by recognizing existing authenticated sessions.

@mraible Thank you very much. We don't want to use a third-party service as Okta, though. Furthermore we need to implement the Hybrid Flow. It's interesting, that I can't find anyone who has done this before: OIDC Hybrid Flow in Ionic/Angular, using their own IdentityServer.

@BenjaminKauer I've been at the exact same task the last couple of hours. Currently considering doing the implementation myself with the InApp browser

@Belicosus that's the way I'll do it.

But I spent a little time with our backend people to discuss whether we could use another flow. We'll probably stick to the Authorization Code Flow and we'll probably use AppAuth-JS instead of angular-oauth2-oidc. Since I can't get hapi to work, which is needed for the callback (clientRedirectURI), I'm about to implement a (less sophisticated) server with express.

Edit: We're using the Authorization Code Flow with PKCE and Silent Refresh.

@mraible Actually I reviewed your guide and I have a question: The access token gets expired. How do you you refresh it in an hybrid(Ionic) Android application using angular-oauth2-oidc ? I have the same issue like @layinka and I am thinking to try AppAuth-JS

@mraible I think you cannot use the silent refresh feature in Ionic (Android or iOS) application app. You cannot setup the silent refresh process for many reasons. It opens a hidden iframe and follows the implicit login process I think. For example you cannot use iframes that required by the silent refresh process (thats why an in-app browser is used). If you have implemented it you can share it. It will be a great help for many developers.

@kioannou Good point. I don't have a solution at this time.

I've started work on a Ionic wrapper for AuthApp. The implementation is very much inspired by @mraible and his article pointing to the use of InAppBrowser to sign in with Facebook.
I expect to finish this tomorrow or wednesday, I'll upload the solution.

@Belicosus if you're going to spend the time doing the work, I would kindly suggest looking into using a custom URL scheme, rather than using the InAppBrowser. Google's no longer supports authentication using the InAppBrowser and it's not longer the recommended approach for several reasons.

Jacques has an an old (but nonetheless relevant) article on medium that's a pretty nice read.

@Belicosus You might look at react-native-app-auth for inspiration. That uses the custom URL scheme that @lostdev recommends. I wrote an article about it for scotch.io recently.

Thanks for all the ideas. I've got an almost working solution for the Authorization Code Flow with PKCE and silent refresh. As soon as I'm done I'll probably write an article.

FYI: I needed to implement a custom AuthorizationRequestHandler and a TokenRequestHandler. The latter is using a custom URL scheme and the system browser.

Once you have an article, could you please link your article and the source code? That will help others who want to do something similar (implement their own AuthorizationRequestHandler. I will also link it from the README so others can discover it.

Of course I will :)

Hi all, are there any news about this issue?
We want to add OAuth2 authentication in an Ionic app (Identity Server 3 as OAuth2 provider).
Currently we have implemented implicit flow authentication with https://github.com/IdentityModel/oidc-client-js but we would enhance our security adding PKCE.

Thanks...

@maurotn A project deadline has kept me from creating a usable package for this, but we did indeed implement the AppAuth JS library in our Ionic app.
We are utilizing the AppAuth project, but have implemented/overridden the vital parts like requestor, AuthorizationRequestHandler and RequestHandler.
Our app implements the Open ID Connect Hybrid flow as implemented in IdentityServer 4.
I would like to put this in a npm package, but I haven't had the time. If you're interested I'll try to find the time tomorrow to put the code in a github repo for you to use as an example.

@maurotn

something like this

class CordovaAuthorizationRequestHandler extends AuthorizationRequestHandler { 
 private currentRequest: AuthorizationRequest = null;
  constructor(
    public locationLike: LocationLike = window.location,
    utils = new BasicQueryStringUtils(),
    generateRandom = cryptoGenerateRandom
  ){
    super(utils, generateRandom)
  }
  performAuthorizationRequest(configuration: AuthorizationServiceConfiguration, request: AuthorizationRequest): void {
    let handle = this.generateRandom();
    let url = this.buildRequestUrl(configuration, request);

    this.currentRequest = request;

    log('Making a request to ', request, url);

    SafariViewController.isAvailable(isAvaliable=>{
      if(isAvaliable){
        SafariViewController.show({url});
      }
      else{
        cordova.InAppBrowser.open(url);
      }
    });
  }
  protected completeAuthorizationRequest(): Promise<AuthorizationRequestResponse> {

    return new Promise(resolve => {
      SafariViewController.hide();
      if(!this.currentRequest)
        resolve();
      let currentUri = `${this.locationLike.origin}${this.locationLike.pathname}`;
      let queryParams = this.utils.parse(this.locationLike, true /* use hash */);
      let state: string|undefined = queryParams['state'];
      let code: string|undefined = queryParams['code'];
      let error: string|undefined = queryParams['error'];
      log('Potential authorization request ', currentUri, queryParams, state, code, error);
      let shouldNotify = state ===  this.currentRequest.state;
      let authorizationResponse: AuthorizationResponse|null = null;
      let authorizationError: AuthorizationError|null = null;
      if (shouldNotify) {
        if (error) {
          // get additional optional info.
          let errorUri = queryParams['error_uri'];
          let errorDescription = queryParams['error_description'];
          authorizationError =
              new AuthorizationError(error, errorDescription, errorUri, state);
        } else {
          authorizationResponse = new AuthorizationResponse(code, state!);
        }
        log('Delivering authorization response');
        resolve({ request: this.currentRequest,
                  response: authorizationResponse,
                  error: authorizationError
                } as AuthorizationRequestResponse );
      }else{
        log('Mismatched request (state and request_uri) dont match.');
        return Promise.resolve(null);
      }
    })
  }
}```

Thanks @Belicosus , yes I'm interested. If you had the time to upload it into a repo it would be great!

Thanks @nmocruz

@Belicosus would be grad if you could put that on github and we could maybe pull it up alltogether!

@Belicosus @nmocruz Awesome work.

If you create a GitHub repo, I can link it from this repo so others can discover it.
Thanks for the code snippet which can help folks get started in the meantime.

@BenjaminKauer I am struggling to work AppAuth-Js with Identityserver3 to implement AuthorizationCode with PKCE. I am able to launch Login page but after successful login it is not redirecting but coming back to login page only. If you have completed your ionic example with PKCE can you please share it? There are so many days i have spent but totally stuck..please

Hi guys. @maurotn @twinklekumarp
Finally got around to put the code on Github.

AppAuth-Ionic Github Repo

It still needs some(a lot) polishing if we want to publish it as a npm package, but for now, it should at least get some of you going. Please feel free to post any questions in the issues section.

@tikurahul Do whatever you want with the repo. I don't know if you want to link to it at it's current state. It's up to you 👍

@Belicosus Thank you for the link. I am going to link it off the README so others can discover your approach. Thanks !

I'm sorry I wasn't able to deliver my solution earlier. We've been busy implementing the EU-GDPR stuff.
Thank you @Belicosus, I'll check your approach, maybe I can contribute something to your repo.

@BenjaminKauer Fell free to post any questions of suggestions under Issues, or even submit a PR. will be much appreciated :)