GithubHelp home page GithubHelp logo

auth-clients's Introduction

iTwin.js Authorization clients

Copyright © Bentley Systems, Incorporated. All rights reserved. See LICENSE.md for license terms and full copyright notice.

iTwin.js is an open source platform for creating, querying, modifying, and displaying Infrastructure Digital Twins.

If you have questions, or wish to contribute to iTwin.js, see our Contributing guide.

About this Repository

This repository contains a few OAuth 2.0 client libraries to assist in authenticating with the iTwin Platform in TypeScript/JavaScript.

There are 3 clients in the repository, each of them corresponding to one of the application types supported by the iTwin Platform. See the authorization documentation for more details on the Authorization workflows supported.

In addition, the OIDC Signin Tool is a test helper package to automate the sign-in workflow to aid in writing integration tests.

There is also an authorization client for command-line developer tools.

Prerequisites

Build Instructions

  1. Clone repository (first time) with git clone or pull updates to the repository (subsequent times) with git pull
  2. Install dependencies: pnpm update or pnpm install
  3. Build source: pnpm build
  4. Run tests: pnpm cover

Note: Sometimes lage's cache will become stale and it may refuse to build projects you've changed. If this or other odd behavior occurs on build, add the --reset-cache flag to the pnpm build command.

Extract Documentation

pnpm run docs

auth-clients's People

Contributors

andrewdinunzio avatar anduong249 avatar anmolshres98 avatar aruniverse avatar arvindsvenkat avatar ben-polinsky avatar calebmshafer avatar evelynpreslar-bentley avatar gintv avatar gytiscepk avatar hl662 avatar imodeljs-admin avatar jake-screen avatar johnnyd710 avatar jsnaras avatar juliusarmalis avatar karolis-zukauskas avatar kckst8 avatar khanaffan avatar mgooding avatar michaelbelousov avatar mindaugasbutkus avatar nick4598 avatar paulius-valiunas avatar pbell97 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

auth-clients's Issues

Release `auth-clients` packages as 1.0

Package Releases

Tasks

  1. bug good first issue
    evelynpreslar-bentley mattbjordan
  2. ben-polinsky
  3. breaking change
    ben-polinsky
  4. browser need reproduction
    ben-polinsky
  5. breaking change
    GytisCepk
  6. breaking change electron
    GytisCepk
  7. ben-polinsky
  8. ben-polinsky
  9. breaking change electron
    karolis-zukauskas
  10. bug electron
    MichaelBelousov ben-polinsky
  11. security
    ben-polinsky
  12. paulius-valiunas

Consolidate loopback servers

Both node cli and electron start servers to receive a callback and finalize the authentication process. They are very similar. The code can be consolidated in a common folder to ensure consistency between the two moving forward.

Add token refresh to the Service Auth client

The current service authorization client gets a new token and stores the expires_at but does not properly handle refreshing the cache token if it's expired.

I'd propose we update the getAccessToken() method to check the expires time and refreshes the token if needed. This will make it so that getAccessToken is now always returning a valid token.

browser: Should default to session storage

Investigation has previously been done on defaulting to using the session store for user state, but encountered a blocker from our Identity Provider. We should double back and see if this is now possible.

Unable to import ElectronRendererAuthorization after recent subpaths change

I am unable to import ElectronRendererAuthorization on @itwin/electron-authorization v0.16.0 . I think it is related with #195 . I tried importing it in all sorts of ways and paths, but webpack fails to find it. Trying to import it using the @itwin/electron-authorization/Renderer path, I am getting this message from webpack

image

It is funny that it mentions exports field since I am importing based on that export field. I am using Bentley fork of react-scripts to build frontend.

Setup repository to use Rush

The current PNPM workspace workflow is awesome (!) but is lacking an easy way to manage and bump versions.

There are other options out there besides Rush but it's the one we're using everywhere else so lets go with that one.

The changes that will need to be made;

  • Update build/release pipeline to use Rush version bumping and release
    • Requires updating the shared internal deployment script
  • Setup Rush projects to use independent versioning.

Misleading comment about silent redirect url

Comment tells that if silent redirect url is not configured, then the primary redirect url is reused and automatic silent renew will work:

/** The redirect URL used for silent sign in and renew. If not provided, will default to redirectUri. */

In reality however usermanager expects silentRedirectUri to be provided:

silent_redirect_uri: basicSettings.silentRedirectUri

without that access token obtained via interactive sign-in will get you 1 hour of work and then will fail abruptly.

Configuration of userManager allows 2 different redirect urls (interactive vs silent) for a reason. In case of silent signin, handling of response is done in a hidden iframe, where you want to load a minimal amount of code just to do processing. Official oidc-client sample even suggests to use a static html page for that:

https://github.com/authts/oidc-client-ts/blob/main/samples/Parcel/src/user-manager/sample-silent.html

If you reuse primary redirect uri also for silent signin, then it will load your complete app in the iframe. In case of itwin-viewer based app this is megabytes of javascript, which will hurt your RAM usage.

However if you don't configure silentRedirectUri, there is no way to know your configuration is not valid.
The underlying oidc-client needs it strictly:

https://github.com/authts/oidc-client-ts/blob/73c4ba86b13fa34d0ac33204a0dad998334e8a20/src/UserManager.ts#LL271C34-L271C34

But auth-client wrapper swallows the error:

Add Prettier to auto-enforce lint rules / Review Lint Rules

We should enforce consistency in code and make it easier for developers to adhere to our lint rules. Prettier and a VSCode extension will help us do this as we write rather than catching in PR.

Let's also review the lint rules in the first place

Odd behavior with username package in testing

When attempting to import a module which imports the username package in a playwright test, the default import is undefined resulting in: TypeError: OperatingSystemUserName is not a function

The latest version of the package defines a better API, but it only exports ESM, so we'll have to see how that would work.

Replace Rush

Rush is starting to cause more issues than it is worth:

  • Need to break up publishing flow into versioning and publishing, but:

  • Cannot customize tag names used when publishing.

Let's look into Beachball

Switch to jest/vitest for unit tests

Jest has support for JSDOM/browser environments which would help in a few places. It also has built in promise support and generally seems like a more maintained library.

Remove dependency on `[email protected]`

This version of the package doesn't work well with ES Modules and will potentially have security vulnerabilities as it's not actively maintained. There are two potential solutions:

  • Update to version 5, which switched from got to node:http and removed retry support - we would have to add our own retry logic and nodejs documentation is not helpful at all for understanding the kind of errors we should handle
  • Remove the dependency altogether and just send http request using whatever library we want. I'm almost inclined to do this rather than the above option because there's only a couple requests we would have to construct - we don't use most of the features of that package.

extract integration tests into separate package in monorepo

Our integration tests (they're really e2e) currently directly import the code they are testing (in addition to cluttering the package code). We can move them out into their own package, then import the code under test as a user would -- as an external dependency (albeit via rush).

In addition, any test helpers or common configuration should be combined.

Create tests for `@itwin/browser-authorization`

The @itwin/browser-authorization package doesn't have any tests that test authorization, so create some.

At the very least, create tests for the main functionality of the package, i.e., that signing in and signing out works.

Probably can code the tests similar to the the tests in oidc-signin-tool.

@itwin/browser-authorization does not return any error codes

/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
import {
  BrowserAuthorizationClient,
  BrowserAuthorizationClientConfiguration,
} from '@itwin/browser-authorization';

import { appConfig } from './AppConfigService';

class AuthorizationService {
  private _authorizationClient: BrowserAuthorizationClient | undefined;

  private async createAuthorizationClient(): Promise<
    BrowserAuthorizationClient
  > {
    const authorizationClientConfiguration: BrowserAuthorizationClientConfiguration = {
      authority: appConfig.auth.authority,
      clientId: appConfig.auth.clientId,
      redirectUri: appConfig.auth.redirectUrl,
      postSignoutRedirectUri: undefined,
      scope: appConfig.auth.scopes,
      responseType: 'code',
    };

    const client = new BrowserAuthorizationClient(
      authorizationClientConfiguration,
    );

    return client;
  }

  public async getAccessToken(): Promise<string> {
    if (!this._authorizationClient) {
      this._authorizationClient = await this.createAuthorizationClient();

      try {
        await this._authorizationClient.signIn();
      } catch (err) {
        throw {
          message: err,
        };
      }
    }

    return this._authorizationClient.getAccessToken();
  }
}

export const authorizationService = new AuthorizationService();

Hi All,

I'm trying to find out why the authorization client does not return anything when the signIn method is called, but i get the following response that is difficult to understand:

{"message":"failed to retrieve issues","error":{"message":{}}}

As you can see, it does not seem to return any error message. Any ideas how I can find out the cause of the error and how to resolve it?

Consolidate `BrowserAuthorizationCallbackHandler` into `BrowserAuthorizationClient`

Get rid of BrowserAuthorizationCallbackHandler and have everything be handled by BrowserAuthorizationClient.

The BrowserAuthorizationCallbackHandler and BrowserAuthorizationClient now share many of the same options (or will once #88 is merged), so their functionality makes more sense to be combined now.

Notes from @evelynpreslar-bentley in #88 (comment)

The main incentive I had for splitting these into 2 classes was to make the config as simple as possible. Before oidc-client-ts made the client-id and authority required for handling callbacks, this made more sense, because all you needed was a redirect-uri. Unless we make the effort to preserve that simplicity, though, I agree that merging the two classes into one starts to make more sense.

Keeping them separate does make it easier for apps to handle callbacks as early as possible, since less configuration is required. Previously, I saw many SPA apps using the same client used for signin also being used to handle callbacks. This meant that half the app would load before handling redirects, because certain config variables were needed, but I don’t think that’s a good enough reason on its own to advocate keeping them separate. Apps should have a special route for redirects anyway.

electron-auth signout does not fully sign user out

Bug: After logout session does not expire and still we can login.

App name:
https://autoupdatecdn.bentley.com/itwinexporterdatasmith/iTwinDatasmithExporterSetup.exe

Steps:
1.Login to iTwinDatasmithExporterSetup.exe app.
2.Click on Signout.
3.You will be redirected to the sign-in page,Click on sign in.
4.Click on allow.

See you are able to login without entering username and password.

Impact: Victim thinks that he is signed out from the account but still the attacker can login to his account without entering username and password.

Poc:
https://drive.google.com/file/d/15eDVa055jRoKAsJPAZAjt4Xi1BK0aJe4/view

Separate context bridge for electron-auth

We have an electron preload script, that exposes some ipc message handling for itwinjs channels on the window, namely core-electron and electron-auth.

Luckily for us, its the same api rn in both and theres no collision, but if there ever arises a time when there is a difference in the apis, it might cause an issue for us. It also really bothers me that we have pretty much the exact same file duplicated across both pkgs. Wondering if we need to consolidate, have an electron-common pkg or some shim. Also wondering if maybe core-electron takes a dep on electron-auth or vice versa. Just food for thought, something Id like to discuss further with our electron experts

[electron client] Breaking changes before stable release

I would like to introduce some breaking changes before we release a stable version (1.0.0) of @itwin/electron-authorization.

  • Use dynamic channel names when setting up IPC (e.g. based on clientId).
    • Currently constructing a second instance of ElectronMainAuthorization will cause an error due to duplicate handlers (ipcMain.handle(...)).
  • Make ElectronMainAuthorization dependency on ipcMain optional (e.g. accept an optional IpcSocket implementation to use for the IPC calls)
    • In iTwin Studio we found that hosting backend-core in Electron "main" process causes UI issues, instead we are hosting it in Electron "utility" process (which doesn't have access to ipcMain).
  • Remove unconditional inclusion of offline_access scope
    • General change - I don't think this package should make assumptions about client scope needs.
  • By default use prompt=login instead of prompt=consent extra URL parameter.
    • prompt=consent parameter causes the consent page to be always shown, even if the OIDC Client has it disabled. In most cases, consent page for Bentley applications (i.e. 1st party applications) doesn't make sense. prompt=login will only show a login page (enter credentials) and skip the consent page (if Client has it setup).
  • Remove access_type=offline extra URL parameter
    • This doesn't seem to be part of OIDC protocol (perhaps IMS specific?) and doesn't seem to have an effect on authorization (at least I didn't notice that). Laurynas R. suggested that this is most likely a copy paste from some other implementation and should not belong in our code.
  • Use string[] instead of string for redirectUri in ElectronMainAuthorizationConfiguration
    • This is based on recent discussion on redirect URI guidelines with AppSec team. Official guidelines are coming soon, but in short desktop/native apps should stick to using http loopback and should have multiple redirect URIs to avoid port collisions. I would like to explicitly break the API here so that consumers (hopefully) update their OIDC configurations to include multiple redirect URIs based on upcoming guidelines.

@aruniverse, @calebmshafer, @kckst8, @ben-polinsky , @GytisCepk - Let me know what you think about proposed changes.

Multiple packages depend on vulnerable version of `openid-client`

Npm audit fails if you reference @itwin/service-authorization (newest version 0.7.0), or @itwin/oidc-signin-tool (latest version 3.6.1).

Steps to reproduce:

  1. npm init
  2. npm i @itwin/service-authorization - reports 4 high severity vulnerabilities
  3. npm audit produces this output:
npm audit report

cacheable-request  <10.2.7
Severity: high
cacheable-request depends on http-cache-semantics, which is vulnerable to Regular Expression Denial of Service - https://github.com/advisories/GHSA-8x6c-cv3v-vp6g
No fix available
node_modules/cacheable-request
  got  8.0.0 - 12.4.1
  Depends on vulnerable versions of cacheable-request
  node_modules/got
    openid-client  1.18.0 - 4.9.1
    Depends on vulnerable versions of got
    node_modules/openid-client
      @itwin/service-authorization  *
      Depends on vulnerable versions of openid-client
      node_modules/@itwin/service-authorization

4 high severity vulnerabilities

Some issues need review, and may require choosing
a different dependency.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.