Code Monkey home page Code Monkey logo

sample-angular-oauth2-oidc-with-auth-guards's Introduction

Example angular-oauth2-oidc with AuthGuard

This repository shows a basic Angular CLI application with the angular-oauth2-oidc library and Angular AuthGuards.

Lint-Build-Test

⚠ Third-party Cookies

TLDR 👉 See my "SPA Necromancy" blogpost for all options and workarounds known to me.

Browser vendors are implementing increasingly strict rules around cookies. This is increasingly problematic for SPA's with their Identity Server on a third-party domain. Most notably problems occur if the "silent refresh via an iframe" technique is used.

This repository uses that technique currently, starting with a silentRefresh(). This will fire up an iframe to load an IDS page with noprompt, hoping cookies get sent along to so the IDS can see if a user is logged in.

Safari will block cookies from being sent, prompting a leading OAuth/OpenID community member to write "SPAs are dead!?". In fact, if you fire up this sample repository on localhost, which talks to demo.duendesoftware.com (another domain!), and use it in Safari: you will notice that the silent refresh technique already fails!

For reference, see issue #40, or my blogpost that explains workarounds and solutions.

Features

⚠ To see the Implicit Flow refer to the implicit-flow branch (which might be getting outdated, since Code Flow is now the recommended flow).

This demonstrates:

  • Use of the Code+PKCE Flow (so no JWKS validation)
  • Async but mandatory bootstrapping (via an APP_INITIALIZER) before the rest of the app can run
  • Modules (core, shared, and two feature modules)
  • An auth guard that forces you to login when navigating to protected routes
  • An auth guard that just prevents you from navigating to protected routes
  • Asynchronous loading of login information (and thus async auth guards)
  • Using localStorage for storing tokens (use at your own risk!)
  • Loading IDS details from its discovery document
  • Trying refresh on app startup before potientially starting a login flow
  • OpenID's external logout features

Most interesting features can be found in the core module.

Implicit Flow

If you need an example of the Implicit Flow check out the last commit with that flow or even earlier versions. For new applications Code+PKCE flow is recommended for JavaScript clients, and this example repository now demonstrates this as the main use case.

Usage

This repository has been scaffolded with the Angular 5 CLI, then later upgraded to newer versions of the Angular CLI. To use the repository:

  1. Clone this repository
  2. Run npm ci to get the exact locked dependencies
  3. Run npm run start (or start-with-ssl) to get it running on http://localhost:4200 (or https://localhost:4200)

This connects to the demo Duende IdentityServer instance also used in the library's examples. The credentials and ways of logging in are disclosed on the login page itself (as it's only a demo server).

You could also connect to your own IdentityServer by changing auth-config.ts. Note that your server must whitelist both http://localhost:4200/index.html and http://localhost:4200/silent-refresh.html for this to work.

You can run the end-to-end tests using:

  1. Run npx playwright install to grab the Playwright browsers
  2. Run npm run test to run the specs

Differences between Identity Server options

This repository demonstrates features using https://demo.duendesoftware.com (Duende IdentityServer). There are various other server side solutions available, each with their own intricacies. This codebase does not keep track itself of the specifics for each other server side solution. Instead, we recommend you look for specific guidance for other solutions elsewhere. Here are some potential starting points you could consider:

Feel free to open an issue and PR if you want to add additional pieces of guidance to this section.

Example

The application is supposed to look somewhat like this:

Application Screenshot

sample-angular-oauth2-oidc-with-auth-guards's People

Contributors

1304654 avatar dannyvdsluijs avatar dennisameling avatar dependabot[bot] avatar gagandeepp avatar janv8000 avatar jeroenheijmans avatar jwoyame avatar maxisam avatar valburyakov 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

sample-angular-oauth2-oidc-with-auth-guards's Issues

Refresh token and silent refresh

I have a question regarding to refresh token and silent refresh (maybe because I am pretty new to OAuth2 and OIDC).

The module documentation regarding to silent refresh using Code Flow does not mention any use of this.oauthService.silentRefresh() but instead the use of this.oauthService.refreshToken().

I am getting inspiration from you repo which is a great inspiration for getting starting with OAuth2 and OIDC within Angular and I am wondering why you use this.oauthService.silentRefresh() (auth.service.ts:109) and if you have seen this note in the module documentation ?
Also, you have not added offline_access in the scope as advised in the documentation. Is it on purpose ?

Thank you for your answer 😃

Enable and document running with TLS

It would be nice if this sample was even more exemplary and allowed serving with https locally. To fix this issue, I'm not 100% sure what needs to be done, but in the end:

  1. The README.md should be updated with a small section or note on how to use TLS
  2. The package.json scripts should be updated to support running both with http and with https
  3. It should work on both Windows and *nix OSes

I'm not sure what to do about the e2e tests though, and open to suggestions. It might be nice if they run with https as well, then again they should also reflect what you'd get after clone-and-run (which might remain http?). Open to suggestions from whomever picks up this issue.

PS. There's a sample-angular-oauth2-oidc-with-auth-guards channel in the contributing.today Discord where I'll be if anyone has hacktoberfest-related questions!

Signing you in component instead of Fallback

When being redirected from the identity server back to the app, the FallbackComponent is briefly displayed during the signin process:
fallback-component

Usually in apps, the FallbackComponent contains text like: “404 – Could not find the requested page” which you don’t want to display during the signin is processing.

What do you think about having a specific route for path index.html#id_token=… to a SigninInprogressComponent that will display “Signing you in… Please wait.”?

Login always fails

Hi,
I cloned this repo, installed and launched. Every time I click the login button I get

image

I think that some time ago I cloned this repo and ran the demo and it worked. Has something changed or maybe I'm doing something wrong? Thanks.

Invalid issuer in discovery

Hi !
I'v been trying for a couple of days to authenticate via Azure ADB2C, in different ways.
MSAL works, but OpenId Connect is not working for me.

I've created a new Identity provider under Azure ADB2C, and tried different configuration and code samples.

Metadata url response is ok (bellow).

From my console:
GET https://rcib2c.b2clogin.com/rcib2c.onmicrosoft.com/b2c_1_susi/v2.0/.well-known/openid-configuration (200 Ok)

Error message:
invalid issuer in discovery document expected: https://rcib2c.b2clogin.com/rcib2c.onmicrosoft.com/b2c_1_susi/v2.0/ current: https://rcib2c.b2clogin.com/4e35db53-xxxx-xxxx-xxxx-72283835fxxx/v2.0/

I don't understand what I'm doing wrong.

This is part of my auth config (using master branch):

    issuer: 'https://rcib2c.b2clogin.com/rcib2c.onmicrosoft.com/B2C_1_susi/v2.0/',
    redirectUri: 'https://localhost:4200',
    clientId: '8e8565e5-xxxx-xxxx-xxxx-42d8abd6e0xx',
    responseType: 'code',    
    scope: ' openid',
    strictDiscoveryDocumentValidation: false,
    showDebugInformation: true,
    clearHashAfterLogin: true,
    skipIssuerCheck: true,
    oidc: true,
    timeoutFactor: 0.01

Would really appreciate any help. Cheers!

Consider switching sample repo to 'Authorization Code with PKCE' flow

The relevant working groups have updated the advice for single page applications (such as this one, which uses Angular) around the recommended flow. Latest recommendation seems to be that SPA's should switch from "Implicit Flow" to the "Authorization Code with PKCE" flow.

After several different feature requests it was recently released in version 8.

I'm not sure how exactly yet, but I would like my sample repository to somehow support showcasing Code+PKCE flow. However, many people will still want to be using Implicit flow, and it seems awkward to support both.

Some ideas how this repo could support both:

  1. Have both options in master and provide a way to toggle between the two.
  2. Have Code+PKCE as the 'primary' option in master, and refer to an older commit if folks want to see Implicit Flow in action.
  3. Have a branch for Code+PKCE for now, and leave master at Implicit (perhaps with a readme update pointing to the branch). Then later switch them around (effectively going back to option 2).

I think option 3 will have to do for the moment, as we'll need a place to start anyways.

Can't redirect to identity provider in a private window

Hi there,
I use this sample as it is and i have problems.
When i use a private window in chrome to browse the angular client app, no redirection occurs. I got 'AADSTS50058+A+silent+sign-in+request+was+sent....'.
The problem is different on normal chrome window. I got AADSTS50196: The server terminated an operation because it encountered a loop while processing a request.
Any help please.
Adam

Silent refresh problem

Great sample app, thanks!

I'm trying to integrate the same logic in my app but something with silent-refresh doesn't work as expected. Basically, I've copy-pasted the auth-service, config, and initialized it in my app. I've also created a new component for the silent-refresh using ng generate component silent-refresh and replaced the silent-refresh.component.html with your silent-refresh.html. So everything seems to work until the token invocation is triggered by the silent-refresh - there I get 400 and afterwards error that the redirect_uri is wrong although it's configured properly in Okta.

Request

curl 'https://dev-522845.oktapreview.com/oauth2/v1/token' \
  -H 'referer: http://localhost:4200/' \
  --data-raw 'grant_type=authorization_code&code=xxx&redirect_uri=http://localhost:4200/ui&code_verifier=xxx&client_id=xxx' \

Error

{"error":"invalid_grant","error_description":"The 'redirect_uri' does not match the redirection URI used in the authorization request."}

image

I know it's very vague but maybe you have an idea what I might be doing wrong?

Login when user opens the page

Hi,

I am trying to change this code to login automatically when user browse the home page. I updated the app menu component file to call the login method in the constructor but its keep looping. Could you please help me to figure out the issue? Thanks

Provide examples for connecting to Azure clients

Users in Microsoft environments can create clients at https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade.

Configuring this example to work with this client is somewhat complicated and an example would help many users.

The issuer URL would be: issuer: 'https://login.microsoftonline.com/{tenant_id}/v2.0'

Response type would be: (I don't know, perhaps this?) responseType: 'code id_token token',

What would clientId be?

How do you register the URLs and configure the proper flow?

https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/Authentication/appId/{client_id}/isMSAApp/ has options for configuring implicit grant flow, https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow?WT.mc_id=Portal-Microsoft_AAD_RegisteredApps:

To enable the implicit grant flow, select the tokens you would like to be issued by the authorization endpoint:

  • Access Tokens
  • ID Tokens

What Logout URL should be used?

Additionally, I received the following: "Every url in discovery document has to start with the issuer url.Also see property strictDiscoveryDocumentValidation." after https://login.microsoftonline.com/{token_id}/v2.0/.well-known/openid-configuration was fetched. Is it really invalid? It seems users will have to also set strictDiscoveryDocumentValidation: false,.

Fix broken GitHub Actions because of Chromedriver (v84) versus Chrome (v85) issues

For example this Action run failed:

[00:20:01] I/launcher - Running 1 instances of WebDriver
[00:20:01] I/direct - Using ChromeDriver directly...
[00:20:07] E/launcher - session not created: This version of ChromeDriver only supports Chrome version 85
  (Driver info: chromedriver=85.0.4183.87 (cd6713ebf92fa1cacc0f1a598df280093af0c5d7-refs/branch-heads/4183@{#1689}),platform=Linux 5.3.0-1034-azure x86_64)
[00:20:07] E/launcher - SessionNotCreatedError: session not created: This version of ChromeDriver only supports Chrome version 85
  (Driver info: chromedriver=85.0.4183.87 (cd6713ebf92fa1cacc0f1a598df280093af0c5d7-refs/branch-heads/4183@{#1689}),platform=Linux 5.3.0-1034-azure x86_64)
    at Object.checkLegacyResponse (/home/runner/work/sample-angular-oauth2-oidc-with-auth-guards/sample-angular-oauth2-oidc-with-auth-guards/node_modules/selenium-webdriver/lib/error.js:546:15)
    at parseHttpResponse (/home/runner/work/sample-angular-oauth2-oidc-with-auth-guards/sample-angular-oauth2-oidc-with-auth-guards/node_modules/selenium-webdriver/lib/http.js:509:13)
    at /home/runner/work/sample-angular-oauth2-oidc-with-auth-guards/sample-angular-oauth2-oidc-with-auth-guards/node_modules/selenium-webdriver/lib/http.js:441:30
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Seems to me that Chrome in the image from GitHub is still at version 84, while the webdriver-manager included with Angular tries to get the latest version (85)? Not sure why it would do that though, since it seems the purpose of said package would be to install the right one?

Anyways, the CI setup should be robust against this situation.

Hash fragment not cleared

Hi,

As a background, I'm using this example as my starting point, and have made a few changes. The biggest one (to the flow itself) is this:

  • At step 3, i use login method. Basically, if silentRefresh fails, I want to immidiately redirect to Identity Server. I'm calling the login method, so that I can be redirected to the correct page that user initially navigated to.

// Enable this to ALWAYS force a user to login.
// this.oauthService.initImplicitFlow();

But since I am also using guards, this of course wont work (router.url doesn't have the same url as in address bar, since the guard is blocking navigation).

this.oauthService.initImplicitFlow(encodeURIComponent(targetUrl || this.router.url));

In any case, the problem I have noticed, is that once I get back after logging in, the hash fragment is not actually cleared by the angular-oauth2-oidc (or maybe it is but then is readded, since it does visually blink).

The example here seems to be working (i.e. the hash is not there) only because of the navigation:

this.router.navigateByUrl(this.oauthService.state);

Do you have slightest idea? I know it's a bit vague description, I'm just asking if this is something you have seen.

Using my own identity server causes X-Frame-Options 'sameorigin' errors

I am using your example here and trying to use my own identity server because I have been having several problems getting the angular-oauth2-oidc to work properly with my app. I get the following error when I use your auth-guard-with-forced-login...
Refused to display 'http://cds-identity.rdeadmin.waters.com:50333/identity/connect/authorize?response_type=id_token%20token&client_id=cds&state=BoA4YNjJ9DskkXpnmeyR2XRuqSsE61ccbF2iiryf&redirect_uri=http%3A%2F%2Flocalhost%3A4201%2Fsilent-refresh.html&scope=unifi%20openid%20profile&nonce=BoA4YNjJ9DskkXpnmeyR2XRuqSsE61ccbF2iiryf&prompt=none' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
Is it my identity server or am I forgetting something in your test code?

Thanks in advance.

Set up CI/CD via GitHub Actions

In #11 we added some e2e test coverage. There's also some linting and building. So it makes sense to add some CI/CD to this project, especially to make sure automated (e.g. dependabot) PRs are easy to merge.

Server side rendering

Hi Jeroen,

Thanks for your sample.

Do you have any clue how to get this working with SSR and lazy loading of modules?
When I add the authservice and authguard to my project the page stays blank with initialNavigation: 'enabled' on the routermodule.

Thanks in advance

ps. can you add a License to this sample?

silent_refresh erro on remote identity provider

Folks,

Did you face this problem?

When executing this project, if the angular app and the keycloak are on the same server, the example runs perfectly (local). When changing to a remote keycloak, after log in, the silent_refresh_error occurs.

The only difference is the issuer.

It works:

export const authConfig: AuthConfig = {
issuer: 'http://localhost:8080/auth/realms/myrealm',
clientId: 'spa-sigga-platform', // The "Auth Code + PKCE" client
responseType: 'code',
redirectUri: window.location.origin + '/index.html',
silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
scope: 'openid profile email', // Ask offline_access to support refresh token refreshes
useSilentRefresh: true, // Needed for Code Flow to suggest using iframe-based refreshes
silentRefreshTimeout: 5000, // For faster testing
timeoutFactor: 0.25, // For faster testing
sessionChecksEnabled: true,
showDebugInformation: true, // Also requires enabling "Verbose" level in devtools
clearHashAfterLogin: false, // manfredsteyer/angular-oauth2-oidc#457 (comment),
requireHttps: false
};

It not works:

export const authConfig: AuthConfig = {
issuer: 'http://172.20.0.247:8080/auth/realms/myrealm',
clientId: 'spa-sigga-platform', // The "Auth Code + PKCE" client
responseType: 'code',
redirectUri: window.location.origin + '/index.html',
silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
scope: 'openid profile email', // Ask offline_access to support refresh token refreshes
useSilentRefresh: true, // Needed for Code Flow to suggest using iframe-based refreshes
silentRefreshTimeout: 5000, // For faster testing
timeoutFactor: 0.25, // For faster testing
sessionChecksEnabled: true,
showDebugInformation: true, // Also requires enabling "Verbose" level in devtools
clearHashAfterLogin: false, // manfredsteyer/angular-oauth2-oidc#457 (comment),
//nonceStateSeparator : 'semicolon', // Real semicolon gets mangled by IdentityServer's URI encoding
requireHttps: false
};

Chrome console output:

image

Hacktober-update for all dependencies

Hacktober is a great excuse to once again do some hygiene updates and make sure all dependencies and devDependencies are up to date. I'm always happy to accept PRs that bring the repo up to date, but for hacktober it seems sensible to create an explicit issue for it, especially for those who are looking to get their very first open source PR in! (So feel free to skip this issue if you already know the ropes of PRs....)

Note that you can locally run npm run e2e to see if your update worked, and any PR will also show the results of Actions (automated build).

PS. There's a sample-angular-oauth2-oidc-with-auth-guards channel in the contributing.today Discord where I'll be if anyone has hacktoberfest-related questions!

Update sample to deal with stricter browser vendor rules for third-party cookies

Browser vendors are implementing increasingly strict rules around cookies.
This is increasingly problematic for SPA's with their Identity Server on a third-party domain.
Most notably problems occur if the "silent refresh via an iframe" technique is used.

This repository uses that technique currently, starting with a silentRefresh().
This will fire up an iframe to load an IDS page with noprompt, hoping cookies get sent along to so the IDS can see if a user is logged in.

Safari will block cookies from being sent, prompting a leading OAuth/OpenID community member to write "SPAs are dead!?".
In fact, if you fire up this sample repository on localhost, which talks to demo.identityserver.io (another domain!), and use it in Safari: you will notice that the silent refresh technique already fails!

Edit: starting with Chrome 83, they also have this behavior in Incognito mode.

Several prominent directions for solving this are available, and more too possibly:

  1. Run IDS on a subdomain where your SPA is also running (effectively making cookies first-party)
  2. Don't use "the iframe technique", but instead use refresh tokens with additional mitigations
  3. Switch to a BFF (Backend-for-frontend) setup

I'm not sure yet what route to pick for this sample, if any.

When ssl is enabled, code breaks where cookies are not stored in chrome.

In angular.json, add certs like:

        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "angular-sample:build",
            "ssl": true,
            "sslKey": "ssl/server.key",
            "sslCert": "ssl/server.crt"
          },

After this, the same code which was working before will break and the console shows the message:
A cookie associated with a cross-site resource at http://xxxxxxx.com was set without the SameSite attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

Edge issue: Validating access_token failed, wrong state/nonce

I am running keycloak with 2 users - 1 local to keycloak and 1 from microsoft azure.

In Chrome - everything is working as expected for both users.

In Edge - local keycloak user is able to login and logout fine.

  • microsoft azure - first attempt to login gets invalid_nonce_in_state
    hit the login button a second time, and user is in. Reproduceable everytime.

I have seen similar issues, but no fix yet: manfredsteyer/angular-oauth2-oidc#218

Enable iframe-based silent refresh in Code Flow example

In #24 we're trying to get Code + PKCE flow working. However, I'm very keen on getting iframe-based silent refresh to work before making Code Flow the new master branch example (as per the newest recommendations).

The reason that iframe-based silent refresh is so important in my opinion, is this scenario:

  1. User lands in your application, logged in on the Identity Server, but not yet in your app
  2. The app fires up, has no refresh token (in fact storage is empty for oauth lib)
  3. The app first tries the iframe based silent refresh, as it should work because the user has a session at the IDS
  4. The silent refresh should work, and the user gets logged in without a prompt

This should've been fixed in manfredsteyer/angular-oauth2-oidc#600 with version 9.1.0, so let's try that and merge it into the #24 branch (and later into the master branch).

Integration with wso2 identity server 5.3.0 : silent_refresh_timeout

Hello Jeroen ,

I have tried your application (i need the force authentication auth guard for my own app) by integrating it with WSO2's Identity Server version 5.3.0 IDP. Everyting is working fine except the silent refresh part when not authenticated , i am allways getting OAuthErrorEvent {type: "silent_refresh_timeout", reason: null, params: null}.
Here is a request example sent by the iframe :
GET https://localhost:9443/oauth2/authorize?response_type=id_token%20token&client_id=7ZUexyCcbKA7TomyF5DyahP2zPsa&state=eIJOJLYKYXza0A2muhu1IFitqyiTWIEQ6psLwBBH&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fsilent-refresh.html&scope=read%20write%20openid%20oidc%3Abric&nonce=eIJOJLYKYXza0A2muhu1IFitqyiTWIEQ6psLwBBH&prompt=none

And this is the response from the IDP :
HTTP/1.1 302 Found X-Frame-Options: DENY X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Date: Mon, 04 Mar 2019 12:47:52 GMT Location: http://localhost:4200/silent-refresh.html#error_description=Authentication+required&state=eIJOJLYKYXza0A2muhu1IFitqyiTWIEQ6psLwBBH&error=login_required?sp=accessmanagement&tenantDomain=carbon.super&session_state=aea171cb6b21c631751834db1bba266219cbbd5d03607062283fb5d5d3fd4523.nMmF3yZnQZOtuk27l85CjQ Content-Length: 0 Server: WSO2 Carbon Server

I have no clue why this error event happens and i know it might be more of angular-oauth2-oidc library issue (so i will create an issue there as well) or might as well be a WSO2 Identity Server bug/issue but maybe you could help me understanding what goes wrong here.

Kind regards and thanks in advance,
Laurens

Hash fragments with session_state, sate, id_token etc not getting set in session storage

UrlHelperService.prototype.getHashFragmentParams = 
    function (customHashFragment) {
        /** @type {?} */
        **var hash = customHashFragment || window.location.hash;**
        hash = decodeURIComponent(hash);
        if (hash.indexOf('#') !== 0) {
            return {};
        }
        /** @type {?} */
        var questionMarkPosition = hash.indexOf('?');
        if (questionMarkPosition > -1) {
            hash = hash.substr(questionMarkPosition + 1);
        }
        else {
            hash = hash.substr(1);
        }
        return this.parseQueryString(hash);
    };

I want to set some value to the customHashFragment instead of taking it from window.location.hash. Is there a way to configure this?

Extend example with (lazy loaded) feature modules

In #4 it was asked if the sample could be extended with lazily loaded feature modules. Since that issue was mainly focused (given the title) on Server Side Rendering (Angular Universal), we'll separate feature modules into this story.

Even though I'm not sure if it's worth making this sample all the more complex to show only feature modules....

Silent refresh problem when using Google Chrome

I found some weird behaviour in chrome. But I guess it is a problem with the angular-oauth2-oidc library.
It seems that the session is changed after the login, so the refreshing fails with "silent refresh failed after session changed"

Can you confirm this problem in chrome? In Edge and Firefox it works as expected.

OAuthStorage not inject in DefaultOAuthInterceptor with --prod flag

Hi,

i'm using your module in a angular 7 project and it works fine using dev ng build.

But if I build the angular app with --prod flag I get this.authStorage undefined in default-oauth.interceptor.ts - row 48:

       const sendAccessToken = this.moduleConfig.resourceServer.sendAccessToken;
        if (sendAccessToken && this.authStorage.getItem('access_token')) {   <-- ERROR HERE
            const token = this.authStorage.getItem('access_token');
            const header = 'Bearer ' + token;

            const headers = req.headers.set('Authorization', header);

            req = req.clone({ headers });
        }

The issue disappear if I remove from core.module.ts
{ provide: OAuthStorage, useValue: localStorage }

I'm on Angular 7.0.3.

Thank you,
Alessandro

Upgrade to Angular 7

Angular 7 was recently released, so should upgrade the example some time soon.

Add specs for auth.service

At the start there were no tests involved in this sample. But since many people found the repository useful, and probably use mainly auth.service.ts as a starting point for their application, it seems useful to add a spec for the core thing they can copy/paste along.

I'm tagging this issue hacktoberfest/up-for-grabs, mainly because creating a start for all of this is something that can be picked up when you start out.

I prefer to have multiple PRs to do this in steps:

  1. First PR to re-enable jasmine and test running for this repository, with just 1 it spec for auth.service.ts, that runs as part of the GitHub Actions pipelines (can be a dummy test)
  2. Second PR to properly add a good mock for the OAuthService and then test the runInitialLoginSequence logic branches
  3. Optionally a third PR to add some Jasmine Marbles based testing, to see what happens in various sequences

Let us know in the issue if you want to pick up any of these and at which timing, to prevent getting conflicts if multiple PRs come in.

(If no one feels like it that's also fine! Then I might add it myself, later. For now I commit to actively watching for incoming PRs.)

Create guidance for opening issues

As a reminder, I need to set some guidance for opening issues in this repository, make sure it's clear what the repo is about and what type of issues can be opened here. Probably an issue template is good for this?

Storage events can cause race conditions

In the auth-service there is a storage event listener added. This might cause race conditions. For example:

  1. Tab A and Tab B both have the app open, not logged in yet
  2. Tab A logs in. Internally in auth-service from the library, a function will run that starts with setting the access_token in storage
  3. Tab B starts responding to that change before tab A completes with the function
  4. Tab B's response is to load the user info, and upon response from the server the sub from the response is checked against the Identity Claims in storage, but Tab A never got to save that yet because it's thread on the CPU didn't get prio.
  5. Tab B will now throw an error because the sub from the user info endpoint doesn't match null from storage.

So:

  • Workaround: wrap logic in setTimeout to make it very likely that Tab A handles everything before Tab B
  • Solution: don't respond to storage events, but make tabs propagate OAuthEvents properly to sibling tabs

Can the sample assume the callback url is /callback instead of /index.html?

Thanks for making this. I realize this sample can't be the end all and be all for all users. However, when I was integrating CoreModule into my existing angular app this morning into my app, a big issue was realizing I needed an explicit route for /callback because I don't have a default route like your sample does. The sample worked with my endpoint because of the default route.

I've done Azure AD Oauth a few times, but this is my first rodeo with OAuth that doesn't come with its own library. My junior coworkers who have not were lost.

Anyway, I understand everything is a trade off, but perhaps if the sample got rid of the default route, set an explicit callback (and I guess change the sample IdentityServer to send the callback to /callback and then there was a note "if your callback is / then just move this code to AppComponent"

Let me know what you think and perhaps in early June I could make a PR doing this.

Add a license

TODO: Need to add a license to the repo, as mentioned in #4

Login (by navigating to `/login`) when the user opens the page

Hi I want do something similar to #39 . But for login I want to route the user to /login route to display some message there and call the loginSequence from there. But I'm getting stuck at infinite loop between /login & /callback routes. Can you please help me on this? Thanks.

Upgrade library to version 12.x

The library got a v12.0.0 release. Let's upgrade the sample to the latest version of the library as well as the latest version of Angular.

I've tagged it "up-for-grabs" if someone wants to have a go at it. But if you want to do so let us know in the issue, otherwise I might start on it myself some time later.

Add extra e2e test that exercises some other features

The current basic e2e test just boots up the app. The happy-path-flow e2e test will log the user in and out via the login button. This leaves a few components unused in e2e tests:

  • The auth-guard.service.ts (so being prevented from going to a protected page)
  • The auth-guard-with-forced-login.service.ts (so getting sent off to IDS4 when you go to a protected page)
  • The should-login.component.ts page
  • and maybe a handful of others too

Let's add 1 more e2e test that tests an extra typical "flow" exercising the above parts.

Note that npm run e2e should run the tests, and these are also run for a PR via GitHub Actions (and nightly for master).

Login does not work on Chrome for IOS

STR:

  1. With Chrome for IOS on IPAD or IPhone, go to http://sample-angular-oauth2-oidc-with-auth-guards.s3-website.eu-west-3.amazonaws.com where I have deployed this repository code with minor changes to allow deployment to AWS S3.
  2. Hit "login" button
  3. Enter credentials (bob/bob) and be focused on the behaviour

Results:

  1. IsAuthenticated, HasValidToken, IsDoneLoading and CanActivateProtectedRoutes are true for a couple of seconds then are switched back to false.
  2. IdentityClaims, AccessToken and IdToken are showing up for a couple of seconds then are switched back to null.

Expected results:
I should remain logged in.

Trace: https://gist.github.com/Yanal-Yves/0b7a30e49417d297e0c1276b4210d267
To get this trace, I built Chromium on a Mac book pro (With Xcode 12.0.1 installed) and ran it on an IPhone simulator. To do so I followed this instructions and more precisely I:

  1. Built Chromium for IOS
    1.1 mkdir chromium && cd chromium
    1.2 git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
    1.3 export PATH="$PATH:~/chromium/depot_tools"
    1.4 mkdir chromium && cd chromium
    1.5 fetch --no-history ios
    1.6 cd src
    1.7 ios/build/tools/setup-gn.py
    1.8 autoninja -C out/Debug-iphonesimulator gn_all
    1.9 out/Debug-iphonesimulator/iossim out/Debug-iphonesimulator/Chromium.app
  2. I opened the simulator and the built Chromium for IOS
  3. I followed the STR described above in this issue.

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.