Skip to content

Commit

Permalink
Merge pull request #153 from authts/remove-implicit-flow
Browse files Browse the repository at this point in the history
feat: #152 remove implicit flow
  • Loading branch information
pamapa authored Oct 26, 2021
2 parents 4414528 + 1e8522d commit 1d5f87a
Show file tree
Hide file tree
Showing 73 changed files with 212 additions and 20,018 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ Library to provide OpenID Connect (OIDC) and OAuth2 protocol support for client-
applications. Also included is support for user session and access token management.

This is a forked version of the [oidc-client-js](https://github.com/IdentityModel/oidc-client-js) library, which has
been archived and is no longer maintained. This version has been refactored from JavaScript to TypeScript. Trying to
keep the API as compatible as possible. However we are aiming to modernize and simplify the library, which will
have an effect on the API.
been archived and is no longer maintained. This version has been refactored from JavaScript to TypeScript. Trying to keep the API as compatible as possible. The support for the outdated implicit flow has been removed.

**Contributions and help is much appreciated!**

Expand Down
8 changes: 3 additions & 5 deletions docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The `UserManager` constructor requires a settings object as a parameter. The set
* authority (string): The URL of the OIDC/OAuth2 provider.
* client_id (string): Your client application's identifier as registered with the OIDC/OAuth2 provider.
* redirect_uri (string): The redirect URI of your client application to receive a response from the OIDC/OAuth2 provider.
* response_type (string, default: `'id_token'`): The type of response desired from the OIDC/OAuth2 provider.
* response_type (string, default: `'code'`): The type of response desired from the OIDC/OAuth2 provider.
* scope (string, default: `'openid'`): The scope being requested from the OIDC/OAuth2 provider.

#### Provider settings if CORS not supported on OIDC/OAuth2 provider metadata endpoint
Expand All @@ -49,7 +49,7 @@ The `authority` URL setting is used to make HTTP requests to discover more infor
* acr_values

#### Other Optional Settings
* clockSkew (number, default: `300`): The window of time (in seconds) to allow the current time to deviate when validating id_token's `iat`, `nbf`, and `exp` values.
* clockSkew (number, default: `300`): The window of time (in seconds) to allow the current time to deviate when validating token's `iat`, `nbf`, and `exp` values.
* loadUserInfo (boolean, default: `true`): Flag to control if additional identity data is loaded from the user info endpoint in order to populate the user's `profile`.
* filterProtocolClaims (boolean, default: `true`): Should OIDC protocol claims be removed from `profile`.
* post_logout_redirect_uri (string): The OIDC/OAuth2 post-logout redirect URI.
Expand All @@ -65,7 +65,6 @@ The `authority` URL setting is used to make HTTP requests to discover more infor
* monitorSession [1.1.0]: (default: `true`): Will raise events for when user has performed a signout at the OP.
* checkSessionInterval: (default: `2000`): Interval, in ms, to check the user's session.
* revokeAccessTokenOnSignout [1.2.1] (default: `false`): Will invoke the revocation endpoint on signout if there is an access token for the user.
* includeIdTokenInSilentRenew [1.4.0] (default: `true`): Flag to control if `id_token` is included as `id_token_hint` in silent renew calls.
* staleStateAge (default: `300`): Number (in seconds) indicating the age of state entries in storage for authorize requests that are considered abandoned and thus can be cleaned up.
* extraQueryParams: (object): An object containing additional query string parameters to be including in the authorization request. E.g, when using Azure AD to obtain an access token an additional resource parameter is required. extraQueryParams: `{resource:"some_identifier"}`
* mergeClaims [1.11.0] (default: `false`): Indicates if objects returned from the user info endpoint as claims (e.g. `address`) are merged into the claims from the id token as a single object. Otherwise, they are added to an array as distinct objects for the claim type.
Expand Down Expand Up @@ -120,8 +119,7 @@ mgr.events.addAccessTokenExpiring(function(){

The `User` type is returned from the `UserManager`'s `getUser` API. It contains these properties:

* id_token: The id_token returned from the OIDC provider.
* profile: The claims represented by a combination of the `id_token` and the user info endpoint.
* profile: The claims represented by a combination of the `token` and the user info endpoint.
* session_state: The session state value returned from the OIDC provider.
* access_token: The access token returned from the OIDC provider.
* scope: The scope returned from the OIDC provider.
Expand Down
7 changes: 4 additions & 3 deletions docs/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ Ported library from JavaScript to TypeScript.
- renamed clockSkew to clockSkewInSeconds
- renamed staleStateAge to staleStateAgeInSeconds
- removed ResponseValidatorCtor and MetadataServiceCtor, if needed OidcClient/UserManager class must be extended
- default of response_type changed from "id_token" to "code"
- changed response_type, only code flow (PKCE) is supported
- removed loadUserInfo

**UserManagerSettings:**
- renamed accessTokenExpiringNotificationTime to accessTokenExpiringNotificationTimeInSeconds
- changed silentRequestTimeout (milliseconds) to silentRequestTimeoutInSeconds
- changed checkSessionInterval (milliseconds) to checkSessionIntervalInSeconds
- default of automaticSilentRenew changed from false to true
- default of validateSubOnSilentRenew changed from false to true
- default of includeIdTokenInSilentRenew changed from true to false
- default of monitorSession changed from true to false
- removed includeIdTokenInSilentRenew

**UserManager:**
- signoutPopupCallback to pass optionaly keepOpen as true, second argument must be used
- signoutPopupCallback to pass optionally keepOpen as true, second argument must be used
21 changes: 6 additions & 15 deletions docs/oidc-client-ts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ export interface CreateSigninRequestArgs {
// (undocumented)
extraTokenParams?: Record<string, any>;
// (undocumented)
id_token_hint?: string;
// (undocumented)
login_hint?: string;
// (undocumented)
max_age?: number;
Expand Down Expand Up @@ -176,11 +174,11 @@ export class OidcClient {
// Warning: (ae-forgotten-export) The symbol "SigninRequest" needs to be exported by the entry point index.d.ts
//
// (undocumented)
createSigninRequest({ response_type, scope, redirect_uri, state, prompt, display, max_age, ui_locales, id_token_hint, login_hint, acr_values, resource, request, request_uri, response_mode, extraQueryParams, extraTokenParams, request_type, skipUserInfo }: CreateSigninRequestArgs): Promise<SigninRequest>;
createSigninRequest({ response_type, scope, redirect_uri, state, prompt, display, max_age, ui_locales, login_hint, acr_values, resource, request, request_uri, response_mode, extraQueryParams, extraTokenParams, request_type, skipUserInfo }: CreateSigninRequestArgs): Promise<SigninRequest>;
// Warning: (ae-forgotten-export) The symbol "SignoutRequest" needs to be exported by the entry point index.d.ts
//
// (undocumented)
createSignoutRequest({ state, id_token_hint, post_logout_redirect_uri, extraQueryParams, request_type }?: CreateSignoutRequestArgs): Promise<SignoutRequest>;
createSignoutRequest({ state, post_logout_redirect_uri, extraQueryParams, request_type }?: CreateSignoutRequestArgs): Promise<SignoutRequest>;
// (undocumented)
readonly metadataService: MetadataService;
// (undocumented)
Expand Down Expand Up @@ -222,7 +220,6 @@ export interface OidcClientSettings {
// (undocumented)
extraTokenParams?: Record<string, any>;
filterProtocolClaims?: boolean;
loadUserInfo?: boolean;
// (undocumented)
max_age?: number;
// (undocumented)
Expand Down Expand Up @@ -321,7 +318,6 @@ export class TokenRevocationClient {
// @public (undocumented)
export class User {
constructor(args: {
id_token?: string;
session_state?: string;
access_token: string;
refresh_token?: string;
Expand All @@ -341,8 +337,6 @@ export class User {
set expires_in(value: number | undefined);
// (undocumented)
static fromStorageString(storageString: string): User;
// (undocumented)
id_token: string | undefined;
// Warning: (ae-forgotten-export) The symbol "UserProfile" needs to be exported by the entry point index.d.ts
//
// (undocumented)
Expand Down Expand Up @@ -470,8 +464,6 @@ export class UserManager {
protected _useRefreshToken(user: User): Promise<User>;
// (undocumented)
protected get _userStoreKey(): string;
// (undocumented)
protected _validateIdTokenFromTokenRefreshToken(profile: UserProfile, id_token: string): Promise<void>;
}

// @public (undocumented)
Expand Down Expand Up @@ -532,7 +524,6 @@ export interface UserManagerSettings extends OidcClientSettings {
accessTokenExpiringNotificationTimeInSeconds?: number;
automaticSilentRenew?: boolean;
checkSessionIntervalInSeconds?: number;
includeIdTokenInSilentRenew?: boolean;
// (undocumented)
monitorAnonymousSession?: boolean;
monitorSession?: boolean;
Expand Down Expand Up @@ -574,10 +565,10 @@ export class WebStorageStateStore implements StateStore {

// Warnings were encountered during analysis:
//
// src/OidcClient.ts:114:88 - (ae-forgotten-export) The symbol "SigninState" needs to be exported by the entry point index.d.ts
// src/OidcClient.ts:114:108 - (ae-forgotten-export) The symbol "SigninResponse" needs to be exported by the entry point index.d.ts
// src/OidcClient.ts:184:89 - (ae-forgotten-export) The symbol "State" needs to be exported by the entry point index.d.ts
// src/OidcClient.ts:184:115 - (ae-forgotten-export) The symbol "SignoutResponse" needs to be exported by the entry point index.d.ts
// src/OidcClient.ts:113:88 - (ae-forgotten-export) The symbol "SigninState" needs to be exported by the entry point index.d.ts
// src/OidcClient.ts:113:108 - (ae-forgotten-export) The symbol "SigninResponse" needs to be exported by the entry point index.d.ts
// src/OidcClient.ts:181:89 - (ae-forgotten-export) The symbol "State" needs to be exported by the entry point index.d.ts
// src/OidcClient.ts:181:115 - (ae-forgotten-export) The symbol "SignoutResponse" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
26 changes: 14 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@
"prepare": "husky install"
},
"dependencies": {
"jsrsasign": "^10.3.0"
"crypto-js": "^4.1.1"
},
"devDependencies": {
"@microsoft/api-extractor": "^7.18.10",
"@testing-library/jest-dom": "^5.5.0",
"@types/crypto-js": "^4.0.2",
"@types/jest": "^27.0.2",
"@types/jsrsasign": "^8.0.13",
"@typescript-eslint/eslint-plugin": "^4.31.1",
"@typescript-eslint/parser": "^4.31.1",
"esbuild": "^0.13.2",
Expand Down
78 changes: 10 additions & 68 deletions samples/Parcel/oidc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ var signingKeysPath = path + "/.well-known/jwks";
var authorizationPath = path + "/connect/authorize";
var userInfoPath = path + "/connect/userinfo";
var endSessionPath = path + "/connect/endsession";
var tokenPath = path + "/connect/token";

var metadata = {
issuer: path,
jwks_uri: signingKeysPath,
authorization_endpoint: authorizationPath,
userinfo_endpoint: userInfoPath,
end_session_endpoint: endSessionPath,
token_endpoint: tokenPath,
};

function prependBaseUrlToMetadata(baseUrl) {
Expand Down Expand Up @@ -46,58 +48,6 @@ var claims = {
"role": ["Admin", "Geek"]
};

function genAccessToken() {
return parseInt(Math.random().toString().replace("0.", "")).toString(16);
}

function hashAccessToken(access_token) {
var hash = jsrsasign.crypto.Util.hashString(access_token, "sha256");
var left = hash.substr(0, hash.length / 2);
var left_b64u = jsrsasign.hextob64u(left);
return left_b64u;
}

function genIdToken(aud, nonce, access_token) {
var now = parseInt(Date.now() / 1000);
var payload = {
aud: aud,
iss: metadata.issuer,
nonce: nonce,
sid: "37889234079034890",
nbf: now,
iat: now,
exp: now + 300,
idp: "some_idp",
amr: ["password"]
};

if (access_token) {
payload.at_hash = hashAccessToken(access_token);
payload.sub = claims.sub;
}
else {
for (var key in claims) {
payload[key] = claims[key];
}
}

return jsrsasign.jws.JWS.sign(null, { alg: "RS256", kid: "1" }, payload, rsaKey.prvKeyObj);
}

function isOidc(response_type) {
var result = response_type.split(/\s+/g).filter(function(item) {
return item === "id_token";
});
return !!(result[0]);
}

function isOAuth(response_type) {
var result = response_type.split(/\s+/g).filter(function(item) {
return item === "token";
});
return !!(result[0]);
}

function addFragment(url, name, value) {
if (url.indexOf("#") < 0) {
url += "#";
Expand Down Expand Up @@ -129,30 +79,17 @@ module.exports = function(baseUrl, app) {
app.get(authorizationPath, function(req, res) {
//res.send("<h1>waiting...</h1>"); return;

var response_type = req.query.response_type;

var url = req.query.redirect_uri;

var state = req.query.state;
if (state) {
url = addFragment(url, "state", state);
if (req.url.indexOf("code_challenge") !== -1) {
url = addFragment(url, "code", "foo");
}
}

//url = addFragment(url, "error", "bad_stuff"); res.redirect(url); return;

if (isOAuth(response_type)) {
var access_token = genAccessToken();
url = addFragment(url, "access_token", access_token);
url = addFragment(url, "token_type", "Bearer");
url = addFragment(url, "expires_in", "70");
url = addFragment(url, "scope", req.query.scope);
}

if (isOidc(response_type)) {
url = addFragment(url, "id_token", genIdToken(req.query.client_id, req.query.nonce, access_token));
url = addFragment(url, "session_state", "123");
}

res.redirect(url);
});

Expand All @@ -173,4 +110,9 @@ module.exports = function(baseUrl, app) {
res.send("logged out");
}
});

app.post(tokenPath, function(req, res) {
res.json({});
});

};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export const settings = {
monitorAnonymousSession : true,

filterProtocolClaims: true,
loadUserInfo: true,
revokeAccessTokenOnSignout : true,

//metadata: {"issuer":"https://demo.identityserver.io","jwks_uri":"https://demo.identityserver.io/.well-known/openid-configuration/jwks","authorization_endpoint":"https://demo.identityserver.io/connect/authorize","token_endpoint":"https://demo.identityserver.io/connect/token","userinfo_endpoint":"https://demo.identityserver.io/connect/userinfo","end_session_endpoint":"https://demo.identityserver.io/connect/endsession","check_session_iframe":"https://demo.identityserver.io/connect/checksession","revocation_endpoint":"https://demo.identityserver.io/connect/revocation","introspection_endpoint":"https://demo.identityserver.io/connect/introspect","device_authorization_endpoint":"https://demo.identityserver.io/connect/deviceauthorization","frontchannel_logout_supported":true,"frontchannel_logout_session_supported":true,"backchannel_logout_supported":true,"backchannel_logout_session_supported":true,"scopes_supported":["openid","profile","email","api","api.scope1","api.scope2","scope2","policyserver.runtime","policyserver.management","offline_access"],"claims_supported":["sub","name","family_name","given_name","middle_name","nickname","preferred_username","profile","picture","website","gender","birthdate","zoneinfo","locale","updated_at","email","email_verified"],"grant_types_supported":["authorization_code","client_credentials","refresh_token","implicit","password","urn:ietf:params:oauth:grant-type:device_code"],"response_types_supported":["code","token","id_token","id_token token","code id_token","code token","code id_token token"],"response_modes_supported":["form_post","query","fragment"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"id_token_signing_alg_values_supported":["RS256"],"subject_types_supported":["public"],"code_challenge_methods_supported":["plain","S256"],"request_parameter_supported":true},
Expand Down

This file was deleted.

23 changes: 0 additions & 23 deletions samples/Parcel/src/implicit-flow-identityserver/sample-callback.js

This file was deleted.

Loading

0 comments on commit 1d5f87a

Please sign in to comment.