Giter Club home page Giter Club logo

oidc-client-ts's Introduction

oidc-client-ts

Stable Release CI Codecov

Library to provide OpenID Connect (OIDC) and OAuth2 protocol support for client-side, browser-based JavaScript client applications. Also included is support for user session and access token management.

This project is a fork of IdentityModel/oidc-client-js which halted its development in June 2021. It has since been ported to TypeScript here with a similar API for the initial 2.0 release. Going forward, this library will focus only on protocols that continue to have support in OAuth 2.1. As such, the implicit grant is not supported by this client. Additional migration notes from oidc-client are available here.

Contributions and help are greatly appreciated!

Implements the following OAuth 2.0 protocols and supports OpenID Connect Core 1.0:

Table of Contents

Installation

Using npm

$ npm install oidc-client-ts --save

Building the Source

$ git clone https://github.com/authts/oidc-client-ts.git
$ cd oidc-client-ts
$ npm install
$ npm run build

Running the Sample

Parcel project

$ cd samples/Parcel
$ npm install
$ npm run start

and then browse to http://localhost:1234.

Angular app

can be found here.

Running the Tests

$ npm test

Contributing

We appreciate feedback and contribution to this repo!

License

This project is licensed under the Apache-2.0 license. See the LICENSE file for more info.

oidc-client-ts's People

Contributors

alexanderbh avatar asleire avatar badisi avatar brockallen avatar coolhome avatar dependabot[bot] avatar donalfenwick avatar henrikwm avatar hmtylmz avatar ker-nicolaib avatar kherock avatar kwojtasinski-repo avatar longsleep avatar m-mohr avatar markphillips100 avatar maxmantz avatar merijndejonge avatar pamapa avatar pascalluginbuehl avatar paulmowat avatar philjones88 avatar piwysocki avatar pmoleri avatar prithvirajbilla avatar robbaman avatar rstaib avatar rvdkooy avatar ulrichb avatar vincentlanglet avatar volkc-basf avatar

Stargazers

 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  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  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  avatar  avatar  avatar  avatar  avatar  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

oidc-client-ts's Issues

Angular 'CommonJS or AMD dependencies can cause optimization bailouts' warnings

When trying to compile an Angular 13 application with oidc-client-ts version 2.0.0-rc.2, the following compilation warnings occur:

Warning: C:\Dev\sample-angular-oidc-client-ts\node_modules\oidc-client-ts\dist\esm\oidc-client-ts.js depends on 'crypto-js/enc-base64.js'. CommonJS or AMD dependencies can cause optimization bailouts.

3 of these warnings occur:

  • crypto-js/enc-base64.js
  • crypto-js/enc-utf8.js
  • crypto-js/sha256.js

These warnings do not occur if version 2.0.0-beta.3 is used.

I have tested this with 'sample-angular-oidc-client-ts'.

angular/angular-cli#18025 indicates that these warnings can be removed by using the allowedCommonJsDependencies option in angular.json. However I have not yet figured out what crypto-js entry points I should use.

Any help would be appreciated.

TokenRevocationClient can be merged into TokenClient

and for most part of _revoke:

const headers: HeadersInit = {
   "Content-Type": "application/x-www-form-urlencoded",
};
...
response = await fetch(url, { method: "POST", headers, body });
...
if (response.status !== 200) {
  throw new Error(response.statusText + " (" + response.status.toString() + ")");
}

this._jsonService.postForm can be used.
-> less duplicated code + less code to maintain

improve response_mode handling

  • now that implicit flow is gone response_mode fragment is no longer needed
  • no need for response_mode in settings
  • set response_mode to "query" in OidcClientSettingsStore if undefined
  • simplifies code at multiple places

signoutRedirect does not work

to reproduce, use Parcel "UserManager Sample with code flow"

[JsonService] getJson, url: https://demo.identityserver.io/.well-known/openid-configuration
Log.ts:107 [JsonService] getJson: HTTP response received, status 200
Log.ts:107 [MetadataService] getMetadata: json received
Log.ts:107 [MetadataService] getMetadataProperty: metadata received
Log.ts:107 [TokenClient] revoke: Received revocation endpoint, revoking access_token
Log.ts:107 [JsonService] postForm, url: https://demo.identityserver.io/connect/revocation
Log.ts:107 [JsonService] postForm: HTTP response received, status 200
Log.ts:115 [JsonService] postForm: Error parsing JSON response SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at JsonService.postForm (JsonService.ts:110)
    at async TokenClient.revoke (TokenClient.ts:192)
    at async UserManager._revokeInternal (UserManager.ts:643)
    at async UserManager._signoutStart (UserManager.ts:574)
    at async UserManager.signoutRedirect (UserManager.ts:504)

The responseText is empty, which ok for signout

Revoking access token fails

Migrating from oidc-client-js.
In oidc-client-ts revoking no longer works.

It is my understanding that when revoking an access token, it's the refresh token that should be sent to the revoke endpoint.
See the Cognito documentation:

The refresh token that the client wants to revoke. All access tokens issued from this refresh token are also revoked.

https://docs.aws.amazon.com/cognito/latest/developerguide/revocation-endpoint.html

oidc-client-ts (wrongly?) sends the access token, which results in the following error:

HTTP 400 and error unsupported_token_type is returned if the token sent in the revocation request is not a refresh token

Is it possible to add additional information inside id_token or User object?

I have a website where user can use external IDP to login, below is the id_token returned.

"profile": {
    "s_hash": "<s_hash>",
    "sid": "<sid>",
    "sub": "<sub>",
    "auth_time": <auth_time>,
    "idp": "openidconnect",
    "tenant": "test-TENANT",
    "loginidp": "test-IDP",
    "email": "[email protected]",
    "family_name": "Doe",
    "given_name": "John",
    "name": [
      "John Doe"
    ],
    "amr": [
      "pwd"
    ]
  }

However, I need to add additional information such as Roles inside the profile so I can decide which menu/fields to show to the logged in User based on their role. I can provide which Role is the logged in user based on their email.

Is there any way to do that?

refactor MetaDataService

  • avoid multiple instances of MetaDataService
  • MetaDataService should hold active used metadata + signingKeys instead in settings
  • avoid multiple metadataUrl implementations

improve unit-tests

Instead of the Stub*.ts classes, make use of jest.mock. Simplify internal interface by not needing anymore to inject types are instances in case of testing

  • MetadataService
  • OidcClientSettings
  • ResponseValidator
  • SessionMonitor
  • TokenClient
  • UserInfoService

UserProfile additional claims from IDP

the returned token from our IdP includes some additional claims like client_id and name. the current implementation has a strict UserProfile interface which doesn't allow to access this data.

It would be great to access additional claims. May be we could have a generic way to access them through an extended UserProfile type.

Hello!

Hi all -- I see that you're working here on a successor to oidc-client. That's great!

Often people don't know the protocol well enough and miss nuances that was done in oidc-client, so I'm happy to answer any questions about why something might have been done a certain way.

Thanks.

refresh_token is undefiend when the /token response contains it's value

User object doesn't get the refresh_token from the connect/token request payload.

Here's a truncated example using https://demo.identityserver.io/:

  • User object:
{
  "id_token": "eyJhbGciOiJSUzI1NiIs...",
  "session_state": "lhX9qi1NzjA3fkhbVLc2a...",
  "access_token": "eyJhbGciOiJSUzI1NiIsIm...",
  "token_type": "Bearer",
  "scope": "openid profile email api offline_access",
  "profile": { ... },
  "expires_at": 1635410072
}
  • /connect/token request payload:
{
  "client_id": "interactive.public.short",
  "code": "7CB04BAF331B59FAE2...",
  "redirect_uri": "http://localhost:3000/welcome",
  "code_verifier": "caba71d44b4a4424a...",
  "grant_type": "authorization_code"
}
  • /connect/token response:
{
  "id_token": "eyJhbGciOiJSUzI1NiIsImt...",
  "access_token": "eyJhbGciOiJSUzI1NiI...",
  "expires_in": 75,
  "token_type": "Bearer",
  "refresh_token": "EB821FC4ADEAFC7583...",
  "scope": "openid profile email api offline_access"
}

Modifying a couple of files in the lib to actually use the refresh_token does seem to resolve the issue.
SigninResponse.ts
SigninResponse ts
ResponseValidator.ts
ResponseValidator ts

simlify code by reducing not needed customizability

settings should be good enough and this will simplify the code quite a bit
see IdentityModel/oidc-client-js#123

  • remove args params from UserManager public functions
  • remove behavior injecting via Ctor (e.g. MetaDataServiceCtor, ...)
  • make settings readonly see #23
  • do not allow to create OidcClient and UserManager without settings
  • remove semi used ClockService
  • remove args params from OidcClient public functions

Removal of implicit flow goes too far, also removes loading of user info

#152 removes implicit flow, thats fine and all, but the same PR also removes loading of user info, resulting in the User.profile field to be always empty.

Similarly, the same PR also removes includeIdTokenInSilentRenew which imo also should be brought back as it is useful and not related to implicit flow. I also cannot se a way to get the ID token raw value (only access_token and refresh_token).

heap memory grows over iterations of silent signin

if i repeatedly do silent sign-in, for example un-authenticated (result in login_required) (keep pressing renew button in angular app) ... then the heap grows and the source keeps adding silent-callback.html instances ...

see screen shots

after investigation, it seems that if i make a change to IFrameWindow.navigate to appendChild AFTER set the iframe.src, then the GC can reclaim this heap and the silent-callback.html instances are removed ... however i can not explain why ... looking for help to
understand what is happening here

this heap leak needs to be fixed especially for spa sites

i made a fork with changes jeffschulzusc / oidc-client-ts

Screen Shot 2021-10-15 at 9 03 02 AM

Screen Shot 2021-10-15 at 9 02 44 AM

issue with imports

bug

I keep getting this error on a fresh install.
loading the modules as import { SHA256, EncBase64, EncUtf8 } from 'crypto-js'; seems to fix the issue.

is this a bug? or is my setup broken?

to clarify; I use es modules to load code

improve esbuild

  • do not bundle externals for esm + node -> allows the users to apply patches for externals (crypto-io+jwt-decode) if needed
  • keep bundling everything for browser builds -> keep them self contained
  • simplify package.json

modernize code

  • replace keyword var with const or let
  • bail out early
  • use "for (let i of list)" loops if possible
  • cleanup constructors to inject types for new (e.g. OidcClientSettingsStore, UserInfoService, ...)
  • remove if (!settings)
  • remove typeof extraQueryParams === 'object'
  • remove all get _X(), which access a private member (e.g. get _stateStore())
  • reduce usage of any type
  • reduce typescript warning/error ignores

make Log more clever

instead of this
Log.error("JoseUtil.validateJwtAttributes: issuer was not provided");
this would need less duplicated strings and be more consistent:
Log.error(this, "validateJwtAttributes: issuer was not provided");

Currently e.g. "JoseUtil.", "UserManager.", ... is used multiple times.

Something like
public static debug(ctx: any, message: string): void
Is there something better than ctx: any, which covers class type?

or
this._logger = Log.getLogger("JoseUtil")
This does not work well with static classes For static classes we can add a static private member....

Possibility of making the jwt signature verification configurable?

By far the largest part of this library right now is `jsrsassign' but I don't think it really needs to be. The problem with jsrsassign is that it doesn't lend itself to treeshaking.

For example, angular oidc client is utilising:

https://www.npmjs.com/package/jsrsasign-reduced

Which contains only the methods needed to actually verify the token. It's still a large 140kb bundle but it's way better than the 200-300kb we have now.

Auth0 went in a slightly different direction with https://www.npmjs.com/package/idtoken-verifier which only supports RS256 tokens however it is 14kb minified + gzipped which is a massive improvement.

I presume you can't really dictate that in this library as it needs to be somewhat generic so my suggestion is to effectively allow the verify method to be implemented by the library consumer and perhaps include the current functionality in a separate entry point so it can be tree-shaken if a user decides not to use it.

Round tripping "state" is missing

The OidcClient is supporting additional state which is round tripped (https://github.com/authts/oidc-client-ts/blob/main/src/OidcClient.ts#L25) but the state cannot be set from any of the typed functions which actually trigger a round trip as the parameter type does not include the exported args type (like https://github.com/authts/oidc-client-ts/blob/main/src/UserManager.ts#L20).

I am trying to port an existing app from oidc-client-js to oidc-client-ts to see if its feasible and this so far the only issue i faced as the existing app for example stores its URL path (before sign in) in the state and once signin in successfull, uses the state information again to redirect to said path (now i can only redirect to the entry page as no state is round tripped).

Please let me know what you think.

Support SSR

There are plenty of code access the window object which make the server build fail. It doesn't happen in oidc-client-js.
For example, window.LocalStorage, even I provide a custom CookieStorage, as the source code default value is using window.LocalStorage, the code would fail.
Also, when I call userManager.getUser(), it init a timer which make use of window.setInterval and window.clearInterval, which make it fail in server side build.
Is it possible to change the source code to check if window object exists before access it?

Waking up from sleep

oidc-client-ts does not seem to handle the computer going to sleep. When the computer wakes up, typically the error that occurs is:

[SilentRenewService] _tokenExpiring: Error from signinSilent: IFrame timed out without a response

and oidc-client-ts stops trying to silently refresh the token.

My main question is, should this be handled in my application or by oidc-client-ts?

If I need to handle in my application, first I would need to detect this condition. My thinking is to use the Page Visibility API. Whenever the page becomes visible, I would check for a timeout problem in oidc-client-ts. If this is detected, I would try to get oidc-client-ts to continue its silent refreshing with UserManager.signinSilent().

It is possible (though unlikely) that the refresh token has timed out if the computer has been asleep for a long time. So if UserManager.signinSilent() fails, I would try again with UserManager.signinRedirect() however that would effectively restart my application.

Any ideas on how this can be handled?
If my application has to handle this, how could it detect that oidc-client-ts has timed out and is no longer doing silent refreshes?

Thanks for your help.

Injecting/Mocking User

For UI tests it would help a lot if we could inject a logged in user to oidc-client-ts. basically allow to inject an access token to skip the authentication flow.

Restore a subset of the args removed from the sign in methods

With oidc-client 1.x, I used a few parameters in the signinRedirect, signinPopup, and signinSilent methods which were removed in #20:

  • extraQueryParams - I need to set this dynamically to tweak the auth server's login page. For example, Keycloak has kc_idp_hint that allows me to create multiple buttons for launching different identity provider login flows. I also might need to be able to suggest a username that's only obtained after the UserManager is created
  • popupWindowFeatures
    • I want to be able to center the popup window in front of the open window rather than the hardcoded offset that's set when constructing the UserManager. These offsets can only be accurately determined the moment the popup is opened.
    • I need to be able to customize the size of the window based on various login pages that can show based on the parameter I mentioned above

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.