authts / oidc-client-ts Goto Github PK
View Code? Open in Web Editor NEWOpenID Connect (OIDC) and OAuth2 protocol support for browser-based JavaScript applications
Home Page: https://authts.github.io/oidc-client-ts/
License: Apache License 2.0
OpenID Connect (OIDC) and OAuth2 protocol support for browser-based JavaScript applications
Home Page: https://authts.github.io/oidc-client-ts/
License: Apache License 2.0
this can be used as starting point:
https://github.com/IdentityModel/oidc-client-js/pull/1335/files
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?
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.
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.
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
IdentityModel/oidc-client-js#1225
Lost opener of popup, that it is no longer able to close it. Probably Cross Origin issue
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.
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?
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
#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).
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
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
Code could be a lot simpler. Would fix a lot of ts and linting errors
settings should be good enough and this will simplify the code quite a bit
see IdentityModel/oidc-client-js#123
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
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:
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.
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.
url = window.location.href
in signinRedirectCallback(url = window.location.href)
and signoutRedirectCallback(url = window.location.href)
with url?: string
currently there is a property called useReplaceToNavigate
in RedirectNavigator
This feature was added in: IdentityModel/oidc-client-js#896
We suggest adding this property to settings. Under the name redirectMethod
.
Available Properties:redirectMethod?: 'replace' | 'assign' = 'assing'
Remove the implicit flow and keep the library lightweight and best practice.
Also see #151
Remove implicit flow in:
JsonService.postForm is currently untested, not good for maintenance and we had a bug #213, which is fixed now
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.
fragment
is no longer neededoidc-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.
enables easier testing of full integration
by using e.g. typedoc or https://docusaurus.io
initial docu can be taken from old wiki:
https://github.com/IdentityModel/oidc-client-js/wiki
this can be used as starting point:
IdentityModel/oidc-client-js#771
see oidc-client-js issue: IdentityModel/oidc-client-js#622
The authorization code grand with PKCE for public clients and follow the guide for browser based (SPA) applications should be used:
https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-03
proposal:
response_type: "code",
scope: "openid",
monitorSession: false,
automaticSilentRenew: true,
validateSubOnSilentRenew: true,
includeIdTokenInSilentRenew: false,
User object doesn't get the refresh_token from the connect/token
request payload.
Here's a truncated example using https://demo.identityserver.io/:
{
"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
ResponseValidator.ts
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 createdpopupWindowFeatures
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....
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.