Git Product home page Git Product logo

angular-oauth2-oidc's Introduction

angular-oauth2-oidc

Support for OAuth 2 and OpenId Connect (OIDC) in Angular. Already prepared for the upcoming OAuth 2.1.

OIDC Certified Logo

Credits

Resources

Tested Environment

Successfully tested with Angular 4.3 to Angular 16 and its Router, PathLocationStrategy as well as HashLocationStrategy and CommonJS-Bundling via webpack.

At server side we've used IdentityServer (.NET / .NET Core), Redhat's Keycloak (Java), and Auth0 (Auth0 is officially supported since version 10 of this lib). For Auth0, please have a look into the respective documentation page here.

For using this library with Azure Active Directory (Azure AD), we recommend an additional look to this blog post and the example linked at the end of this blog post.

Also, the Okta community created some guidelines on how to use this lib with Okta. See the links at the end of this page for more information.

Angular 17: Use 17.x versions of this library (should also work with older Angular versions!).

Angular 16: Use 16.x versions of this library (should also work with older Angular versions!).

Angular 15: Use 15.x versions of this library (should also work with older Angular versions!).

Angular 14: Use 14.x versions of this library (should also work with older Angular versions!).

Angular 13: Use 13.x versions of this library (should also work with older Angular versions!).

Angular 12: Use 12.x versions of this library (should also work with older Angular versions!).

Angular 11: Use 10.x versions of this library (should also work with older Angular versions!).

Angular 10: Use 10.x versions of this library (should also work with older Angular versions!).

Angular 9: Use 9.x versions of this library (should also work with older Angular versions!).

Angular 8: Use 8.x versions of this library.

Angular 7: Use 7.x versions of this library.

Angular 6: Use Version 4.x of this library. Version 4.x was tested with Angular 6. You can also try the newer version 5.x of this library which has a much smaller bundle size.

Angular 5.x or 4.3: If you need support for Angular < 6 (4.3 to 5.x) you can download the former version 3.1.4 (npm i angular-oauth2-oidc@^3 --save).

Release Cycle

  • We plan one major release for each Angular version
    • Will contain new features
    • Will contain bug fixes and PRs
  • Critical bugfixes on demand

Contributions

  • Feel free to file pull requests

  • The issues contain some ideas for PRs and enhancements (see labels)

  • If you want to contribute to the docs, you can do so in the docs-src folder. Make sure you update summary.json as well. Then generate the docs with the following commands:

    npm install -g @compodoc/compodoc
    npm run docs

Features

  • Logging in via Code Flow + PKCE
    • Hence, you are safe for the upcoming OAuth 2.1
  • Logging in via Implicit Flow (where a user is redirected to Identity Provider)
  • "Logging in" via Password Flow (where a user enters their password into the client)
  • Token Refresh for all supported flows
  • Automatically refreshing a token when/some time before it expires
  • Querying Userinfo Endpoint
  • Querying Discovery Document to ease configuration
  • Validating claims of the id_token regarding the specs
  • Hook for further custom validations
  • Single-Sign-Out by redirecting to the auth-server's logout-endpoint
  • Tested with all modern browsers and IE
  • Token Revocation according to RFC 7009

Sample-Auth-Server

You can use the OIDC-Sample-Server used in our examples. It assumes, that your Web-App runs on http://localhost:4200

Username/Password:

  • max/geheim
  • bob/bob
  • alice/alice

clientIds:

  • spa (Code Flow + PKCE)
  • implicit (implicit flow)

redirectUris:

  • localhost:[4200-4202]
  • localhost:[4200-4202]/index.html
  • localhost:[4200-4202]/silent-refresh.html

Installing

npm i angular-oauth2-oidc --save

Option 1: Standalone APIs

If you use Standalone Components introduced with Angular 14, you can use our standalone API (call to provideOAuthClient) in your main.ts to setup the OAuthClient:

// main.ts -- Angular 15+ version
import { bootstrapApplication } from '@angular/platform-browser';

import { provideHttpClient } from '@angular/common/http';

import { AppComponent } from './app/app.component';
import { provideOAuthClient } from 'angular-oauth2-oidc';

bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient(),
    provideOAuthClient()
  ]
});

As Angular 14 does have Standalone Components but no Standalone API for its HttpClient, you need to go with the traditional HttpClientModule in this version:

// main.ts -- Angular 14 version
import { bootstrapApplication } from '@angular/platform-browser';

import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app/app.component';
import { provideOAuthClient } from 'angular-oauth2-oidc';
import { importProvidersFrom } from '@angular/core';

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(HttpClientModule),
    provideOAuthClient()
  ]
});

The provideOAuthClient function takes the same parameters as the forRoot function of the OAuthModule that is still in place for the sake of compatibility with existing code bases.

Option 2: Using NgModules

import { HttpClientModule } from '@angular/common/http';
import { OAuthModule } from 'angular-oauth2-oidc';
// etc.

@NgModule({
  imports: [
    // etc.
    HttpClientModule,
    OAuthModule.forRoot()
  ],
  declarations: [
    AppComponent,
    HomeComponent,
    // etc.
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule {
}

Logging in

Since Version 8, this library supports code flow and PKCE to align with the current draft of the OAuth 2.0 Security Best Current Practice document. This is also the foundation of the upcoming OAuth 2.1.

To configure your solution for code flow + PKCE you have to set the responseType to code:

  import { AuthConfig } from 'angular-oauth2-oidc';

  export const authCodeFlowConfig: AuthConfig = {
    // Url of the Identity Provider
    issuer: 'https://idsvr4.azurewebsites.net',

    // URL of the SPA to redirect the user to after login
    redirectUri: window.location.origin + '/index.html',

    // The SPA's id. The SPA is registerd with this id at the auth-server
    // clientId: 'server.code',
    clientId: 'spa',

    // Just needed if your auth server demands a secret. In general, this
    // is a sign that the auth server is not configured with SPAs in mind
    // and it might not enforce further best practices vital for security
    // such applications.
    // dummyClientSecret: 'secret',

    responseType: 'code',

    // set the scope for the permissions the client should request
    // The first four are defined by OIDC.
    // Important: Request offline_access to get a refresh token
    // The api scope is a usecase specific one
    scope: 'openid profile email offline_access api',

    showDebugInformation: true,
  };

After this, you can initialize the code flow using:

this.oauthService.initCodeFlow();

There is also a convenience method initLoginFlow which initializes either the code flow or the implicit flow depending on your configuration.

this.oauthService.initLoginFlow();

Also -- as shown in the readme -- you have to execute the following code when bootstrapping to make the library to fetch the token:

this.oauthService.configure(authCodeFlowConfig);
this.oauthService.loadDiscoveryDocumentAndTryLogin();

Logging out

The logOut method clears the used token store (by default sessionStorage) and forwards the user to the auth servers logout endpoint if one was configured (manually or via the discovery document).

this.oauthService.logOut();

If you want to revoke the existing access token and the existing refresh token before logging out, use the following method:

this.oauthService.revokeTokenAndLogout();

Skipping the Login Form

If you don't want to display a login form that tells the user that they are redirected to the identity server, you can use the convenience function this.oauthService.loadDiscoveryDocumentAndLogin(); instead of this.oauthService.loadDiscoveryDocumentAndTryLogin(); when setting up the library.

This directly redirects the user to the identity server if there are no valid tokens. Ensure you have your issuer set to your discovery document endpoint!

Calling a Web API with an Access Token

You can automate this task by switching sendAccessToken on and by setting allowedUrls to an array with prefixes for the respective URLs. Use lower case for the prefixes.

OAuthModule.forRoot({
    resourceServer: {
        allowedUrls: ['http://www.angular.at/api'],
        sendAccessToken: true
    }
})

If you need more versatility, you can look in the documentation how to setup a custom interceptor.

Token Refresh

See docs: https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/refreshing-a-token.html

Routing

If you use the PathLocationStrategy (which is on by default) and have a general catch-all-route (path: '**') you should be fine. Otherwise look up the section Routing with the HashStrategy in the documentation.

Implicit Flow

Nowadays, using code flow + PKCE -- as shown above -- is the recommended OAuth 2/OIDC flow for SPAs. To use the older implicit flow, lookup this docs: https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/using-implicit-flow.html

More Documentation (!)

See the documentation for more information about this library.

Breaking Change in Version 9

With regards to tree shaking, beginning with version 9, the JwksValidationHandler has been moved to a library of its own. If you need it for implementing implicit flow, please install it using npm:

npm i angular-oauth2-oidc-jwks --save

After that, you can import it into your application by using this:

import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks';

instead of that:

import { JwksValidationHandler } from 'angular-oauth2-oidc';

Please note, that this dependency is not needed for the code flow, which is nowadays the recommended flow for single page applications. This also results in smaller bundle sizes.

Breaking change in 9.1.0

The use of encodeURIComponent on the argument passed to initImplicitFlow and its Code Flow counterparts was mandatory before this version.

Since that was considered a bug, the need to do so was removed. Now the reverse is true if you're upgrading from before 9.0.0: you need to remove any call to encode URI components in your own application, as the library will now do it for you.

Tutorials

Thanks to all Contributors

alexandisanbiniyaranoordendeArsProgrammanihanth007

bobvandevijverBobCui20BottswanaErazerBrechtChris3773

ChristianMurphyd-moosenterprisebugcraniodevFabianGosebrink

FabienDehopreFRosnerMisterJamesJessePreinerjesusbotella

JojofoulkkristofdegravesaxiceklukasmattaMaximaximum

mpbalmeidamhyfritzmdaehnertmcserranhumblot

l1b3roleersoyOskarsPakershellerbardepaweldyminski

bechhansenpeterneavepmccloghrylaingakehirRubenVermeulen

ryanmwrightscttcperabshoffSpazzMarticussrenatus

sven-codecultureRocket18CetearethvadjsVarada-Schneider

Gimlyakkaradejcoyoteecddarbiofilipvh

kyubisationluciimonmike-riveradrobert-bfmroblabat

wdunn001adrianbenjuyaAndreas-Hjortlandademattecgatian

dirkbolteenricodeleoGregordyjeroenhinfilinjie997

jfynekevincathcart-casmartin1cernymarvinosswaldnick1699

paulyoderreda-alaouiremiburtingingterskranich

StefanoChiodinotpeter1985dennisamelingdependabot[bot]jdgeier

mraibleajpiersonartnimfmalcherFlofie

mabdelaal86nhanceRazzeeemaxisamismcagdas

ToxicableManuelRaubervdveerjeroenheijmansmanfredsteyer

angular-oauth2-oidc's People

Contributors

adematte avatar adrianbenjuya avatar ajpierson avatar andreas-hjortland avatar busycat avatar debojitk avatar dennisameling avatar dependabot[bot] avatar dirkbolte avatar enricodeleo avatar flofie avatar fmalcher avatar gingters avatar ismcagdas avatar jdgeier avatar jeroenheijmans avatar kranich avatar mabdelaal86 avatar manfredsteyer avatar manuelrauber avatar maxisam avatar michaelfaith avatar nhance avatar paulyoder avatar razzeee avatar reda-alaoui avatar remiburtin avatar stefanochiodino avatar tpeter1985 avatar vdveer 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  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

angular-oauth2-oidc's Issues

Can't authenticate with tokens signed using xx384 or xx512 algorithms when at_hash is included

According to http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken, the at_hash claim contains "the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the access_token value, where the hash algorithm used is the hash algorithm used in the alg Header Parameter of the ID Token's JOSE Header". The current implementation only uses SHA-256 and fails to process tokens signed with algorithms such as RS384 and ES512 since they use correspondingly larger hash algorithms for at_hash.

Remove core-js reference from oauth-service.d.ts

In short: the reference is not needed and causes conflicts with lib-es6.d.ts

Scenario:

  • Follow the Angular2 Webpack sample to create an Angular2 app that builds with Webpack
  • Add the angular-oauth2-oidc package and use it to protect the AppComponent
  • Attempting to build the application fails because oauth-service.d.ts references core-js, which wasn't installed -- so install core-js via npm install @types/core-js --save-dev
  • Attempting to build the application fails because core-js conflicts with lib-es6.d.ts (duplicate identifier 'PropertyKey')
  • Uninstall core-js via npm uninstall @types/core-js --save-dev
  • Open oauth-service.d.ts and delete the line /// <reference types="core-js" />
  • Building the application now succeeds

localStorage not defined

Hello everyone,

Iยดm trying to build an Angular2 project with IdentityServer4 following this post: [https://www.softwarearchitekt.at/post/2016/07/03/authentication-in-angular-2-with-oauth2-oidc-and-guards-for-the-newest-new-router-english-version.aspx].

The fact is that I canยดt run the application because i receive the following error once I load it:
localStorage is not defined at new OAuthService

Thanks and regards

Problem with typings install

Angular doesn't use typings anymore. Now it has dependency on @types, eg.
"devDependencies": { "@types/node": "^6.0.45", "@types/jasmine": "^2.5.35" }

When imported to project with no typings it throws an error:
npm ERR! [email protected] postinstall: typings install
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] postinstall script 'typings install'.
npm ERR! Make sure you have the latest version of node.js and npm installed.

It's propably due to use of typings, and specifying it only in devDependancies.

OAuthModule.forRoot() giving me an error.

ERROR in Error encountered resolving symbol values statically. Calling function 'OAuthModule', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol AppModule in directory/oAuth/src/app/app.module.ts, resolving symbol AppModule in directory/oAuth/src/app/app.module.ts

OAuthService.logOut(true) doesn't log the user out from the identity server

In short: OAuthService.logOut(true) clears the identity token from the client application but does not log the user out of the identity server itself.

Angular2 application signs in to Identity Server via OIDC and is redirected back to the angular2 app. The angular2 app has a "logout" button which corresponds to OAuthService.logOut(). The parameter to logOut() is "noRedirectToLogoutUrl?: boolean" which, if true, clears the identity token from the angular2 application but not from the identity server, i.e. if the user tries to log in from the angular2 app, they are automatically signed in by the identity server and redirected back to the angular2 app. To me this is unexpected behavior: I want the user signed out of both the angular2 app AND the identity server.

If instead I call OAuthService.logOut(false) then the behavior is as expected except now the user needs to manually navigate back to the angular2 app (which I want to avoid).

?p=policy not supported (ad b2c)

Hi @manfredsteyer, first of all: great for sharing this, works great with ng 4! however i have a small issue with AD B2C and it's policies.

if i have a discovery url like :

https://login.microsoftonline.com/doomsdayb2c.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_signin

that will resolve in a login url :

https://login.microsoftonline.com/doomsdayb2c.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_signin

then the login will not work because the appended querystring (in createLoginUrl) starts with a ? too, that's one too much. do you accept a PR as a fix?

Is it possible to subscribe to authentication so navigation isn't needed on logout?

First of all, thanks for this great library! I've been using it to show how to interact with Okta's OIDC and OAuth support.

I'm trying to use it in an Ionic app and I've run into an issue navigating on logout. I posted this question to the Ionic forums to see about how to workaround a logout issue. As you can see, I received a reply that I should simply subscribe to an event to do my navigation. For example:

authService.notifier.subscribe((authed) => {
  if (authed) {
    this.rootPage = TabsPage;
  } else {
    this.rootPage = LoginPage;
  }
});

Does this library provide that feature?

canActivate Route

When I try to use canActivate on a route it always returns false. I am doing an implicit flow and when it redirects back it seems like it does not wait for the service to be aware of the login and it always redirects back to the login page.

`@Injectable()
export class AuthGuardService implements CanActivate {

constructor (
    private _oauthService: OAuthService,
    private _router: Router
) {

}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.loggedIn) {
        return true;
    }

    //Redirect the user before denying them access to this route
    this._router.navigate(['/welcome']);
    return false;
}

get loggedIn() {
    return this._oauthService.hasValidAccessToken();
}

}`

Userinfo Endpoint undefined

I'm trying to setup the OAuthService to use a user info endpoint and I have defined this as follows:
this.oauthService.userinfoEndpoint = "https://login.microsoftonline.com/common/openid/userinfo";
However, when I look at the directory of the service, it says that userinfoEndpoint: undefined. Because of this, I'm not able to get the user details.

Documentation describing password flow is wrong

It seems that the documentation describing the password flow without discovery document is incorrect. The code snippet ends with a line that loads the discovery document (copy/paste issue?).

The snippet should IMO end with something like:

    this.oauthService.tokenEndpoint = 'https://steyer-identity-server.azurewebsites.net/identity/connect/token';
    this.oauthService.fetchTokenUsingPasswordFlow('max', 'geheim').then(() => {
      // ...
    });

Support for Deep Linking

I'd like to support the following scenario:

  1. user bookmarks a view (or sends a link to collegue)
  2. the user session expires
  3. user clicks the link
  4. the user is prompted for login if necessary
  5. the desired view is displayed

At first, this sounds trivial, simply add the proper redirect URI:

oauthService.redirectUri = window.location.href;

until one meets an OpenID Connect provider that does not support wildcards in authorized redirect urls (yes Google, I am looking at you ...)

I guess I could specify a redirect URI like "redirect.html?target=the_deep_link" and hook into the router to intercept this URL, parse the query param, and redirect to the actual target once the token has been verified. This has the advantage that asynchronous token verification (due to asynchronous loading of the discovery document) would be invisible to the actual application route, i.e. a component constructor could issue backend requests without needing to wait for a login promise.

Do you see a better solution? If not, would you accept a PR implementing this?

Support for Angular Universal (localStorage dependency)

First off, I wanted to thank you for making this project--I've found it super useful, and it's very generous of you to contribute it!

I've been trying to adapt it to an app that uses Angular Universal using this starter template. The rub with Angular Universal in general is that global objects such as window or localStorage are not available when the page gets rendered on the server in the context of node (see list of gotchas here).

The approach I was trying out was to create a "mock" storage service to be injected into the OAuthService when it runs on the server. I could then write this service to take auth tokens from the http header of the client request, and pass them along to the OAuthService through my mock's implementation of the getItem method.

The issue I'm hitting is with this line - which causes the OAuthService class to (try to) be created with window.LocalStorage even before I've had a chance to override it with my mock storage service through the setStorage method. This causes the app to fail to render completely on the server side.

I've found that by modifying that line to instead simply not create a default value (e.g. private _storage: Storage; instead of private _storage: Storage = localStorage;, I can get things working. Obviously, making that change could break other people who had relied on the default behavior in a non-universal context.

One suggestion that might work for everyone would be to initialize the _storage variable in the constructor, but only if localStorage actually exists (which is true on the Browser, but not on the Server. This should keep things the same for anyone rendering in the browser, but also enable the server-render scenario as long as you call the setStorage method to your mock Storage object soon after initializing OAuthService. Something like this:

private _storage: Storage;
constructor(private http: Http) {
    if (typeof localStorage != undefined) {
        this._storage = localStorage;
    }
//Rest of the constructor
}

Do you like the idea of trying to support Angular Universal? If yes, what do you think of this general approach? I'm happy to submit a pull request, but I wanted to check with you first.

Facebook/Google login

Hello,

Thank you for this excellent tool. I was wondering if you can provide an example using Facebook or Google login.
I tried but I faced CORS issues.

Thanks for your help !

Authorization Code Flow support

When are you planning to add support for the Authorization Code Flow?

Should be reasonably easy given that you already implemented all logic for identity, access, and refresh tokens, including refreshing the access token with the refresh token - or am I missing something?

Response Type

Hi, I'm implementing an OAuth 2.0 client for the first time, so I may be doing something incorrectly, but I believe I need to be able to customize the responseType parameter. The server I'm working with expects a response_type of code for requesting an authorization code. Here is a section of the OAuth 2.0 spec:

response_type
REQUIRED. The value MUST be one of "code" for requesting an authorization code as described by Section 4.1.1, "token" for requesting an access token (implicit grant) as described by Section 4.2.1, or a registered extension value as described by Section 8.4.
-- https://tools.ietf.org/html/rfc6749#page-19

Currently, the responseType can't be set manually, and can only be set to token or id_token+token (if OIDC is being used).

Question about scenario

so if I opt for manual clicks for logon/logoff, I can get this working no problem with my implicit provider. I'd like to basically say spa as a whole is blocked without authentication.

I've basically put something in place that loads the discovery doc, then tries to login. After that oauthservice .hasIdToken(), I initiate the implicitflow().

No combination of router guards and those checks will end up breaking before we present any user interface, and was wondering how people are achieving this effect. There is no user interface for unauthenticated users. I could just enforce the index.html doesnt get served it not authenticated... but seems like I should be able to achieve this here as well.

My router guard experiments resulted in weird looping between my oidc server and the opening component.

getting unauthorized_client 400 error when logging in

Hi I need help,

anyone getting 400 error with unauthorized client error on submit request, anyone had issue?

click handler

public login() {

        console.log('email: ' + this.model.email, 'password: ' + this.model.password);
        
        if(this.model.email && this.model.password != null) {
            this.loading = true;
            this.oauthService.fetchTokenUsingPasswordFlow(this.model.email, this.model.password).then(
                result => {
                    this.token = this.oauthService.getAccessToken();
                },
                error => {
                    alert(error);
                    console.log(error);
                    this.token = error;
                    this.loading = false;
            })
        }
    }

fired on login submit

    public configureLogin(){  
        // URL of the SPA to redirect the user to after login
        this.oauthService.redirectUri = window.location.origin;

        // The SPA's id. The SPA is registerd with this id at the auth-server
        this.oauthService.clientId = "testClient";

        // set the scope for the permissions the client should request
        // The first three are defined by OIDC. The 4th is a usecase-specific one
        this.oauthService.scope = "openid profile email TestScope";

        // set to true, to receive also an id_token via OpenId Connect (OIDC) in addition to the
        // OAuth2-based access_token
        this.oauthService.oidc = true;

        this.oauthService.dummyClientSecret = "secret";

        // Use setStorage to use sessionStorage or another implementation of the TS-type Storage
        // instead of localStorage
        this.oauthService.setStorage(sessionStorage);

        // The name of the auth-server that has to be mentioned within the token
        this.oauthService.issuer = "https://phenomenexauthserver.azurewebsites.net/";
        
        // Load Discovery Document and then try to login the user
        this.oauthService.loadDiscoveryDocument().then(() => {

            // This method just tries to parse the token(s) within the url when
            // the auth-server redirects the user back to the web-app
            // It dosn't send the user the the login page
            this.oauthService.tryLogin({});      

        });
    }

handle error when idp returns error login in

if the user does not successfully login in the idp then an error is returned eg:

image

EXCEPTION: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'error'
Error: Cannot match any routes. URL Segment: 'error'
    at ApplyRedirects.noMatchError (http://localhost:4200/vendor.bundle.js:108860:16) [angular]
    at CatchSubscriber.selector (http://localhost:4200/vendor.bundle.js:108829:29) [angular]
    at CatchSubscriber.error (http://localhost:4200/vendor.bundle.js:50636:31) [angular]
    at MapSubscriber.Subscriber._error (http://localhost:4200/vendor.bundle.js:483:26) [angular]
    at MapSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
    at MapSubscriber.Subscriber._error (http://localhost:4200/vendor.bundle.js:483:26) [angular]
    at MapSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
    at MapSubscriber.Subscriber._error (http://localhost:4200/vendor.bundle.js:483:26) [angular]
    at MapSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
    at LastSubscriber.Subscriber._error (http://localhost:4200/vendor.bundle.js:483:26) [angular]
    at LastSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
    at MergeAllSubscriber.OuterSubscriber.notifyError (http://localhost:4200/vendor.bundle.js:632:26) [angular]
    at InnerSubscriber._error (http://localhost:4200/vendor.bundle.js:115288:21) [angular]
    at InnerSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
window.console.error @ VM13634:27
VM13634:27 ORIGINAL STACKTRACE:
window.console.error @ VM13634:27
VM13634:27 Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'error'
Error: Cannot match any routes. URL Segment: 'error'
    at ApplyRedirects.noMatchError (apply_redirects.js:149) [angular]
    at CatchSubscriber.selector (apply_redirects.js:118) [angular]
    at CatchSubscriber.error (catch.js:104) [angular]
    at MapSubscriber.Subscriber._error (Subscriber.js:128) [angular]
    at MapSubscriber.Subscriber.error (Subscriber.js:102) [angular]
    at MapSubscriber.Subscriber._error (Subscriber.js:128) [angular]
    at MapSubscriber.Subscriber.error (Subscriber.js:102) [angular]
    at MapSubscriber.Subscriber._error (Subscriber.js:128) [angular]
    at MapSubscriber.Subscriber.error (Subscriber.js:102) [angular]
    at LastSubscriber.Subscriber._error (Subscriber.js:128) [angular]
    at LastSubscriber.Subscriber.error (Subscriber.js:102) [angular]
    at MergeAllSubscriber.OuterSubscriber.notifyError (OuterSubscriber.js:22) [angular]
    at InnerSubscriber._error (InnerSubscriber.js:26) [angular]
    at InnerSubscriber.Subscriber.error (Subscriber.js:102) [angular]
    at resolvePromise (zone.js:643) [angular]
    at resolvePromise (zone.js:619) [angular]
    at :4200/vendor.bundle.js:131681:17 [angular]
    at Object.onInvokeTask (ng_zone.js:264) [angular]
    at ZoneDelegate.invokeTask (zone.js:362) [angular]
    at Zone.runTask (zone.js:166) [<root> => angular]
    at drainMicroTaskQueue (zone.js:529) [<root>]
window.console.error @ VM13634:27
VM13634:27 Unhandled Promise rejection: Cannot match any routes. URL Segment: 'error' ; Zone: angular ; Task: Promise.then ; Value: ZoneAwareError Error: Cannot match any routes. URL Segment: 'error'
    at ApplyRedirects.noMatchError (http://localhost:4200/vendor.bundle.js:108860:16) [angular]
    at CatchSubscriber.selector (http://localhost:4200/vendor.bundle.js:108829:29) [angular]
    at CatchSubscriber.error (http://localhost:4200/vendor.bundle.js:50636:31) [angular]
    at MapSubscriber.Subscriber._error (http://localhost:4200/vendor.bundle.js:483:26) [angular]
    at MapSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
    at MapSubscriber.Subscriber._error (http://localhost:4200/vendor.bundle.js:483:26) [angular]
    at MapSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
    at MapSubscriber.Subscriber._error (http://localhost:4200/vendor.bundle.js:483:26) [angular]
    at MapSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
    at LastSubscriber.Subscriber._error (http://localhost:4200/vendor.bundle.js:483:26) [angular]
    at LastSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
    at MergeAllSubscriber.OuterSubscriber.notifyError (http://localhost:4200/vendor.bundle.js:632:26) [angular]
    at InnerSubscriber._error (http://localhost:4200/vendor.bundle.js:115288:21) [angular]
    at InnerSubscriber.Subscriber.error (http://localhost:4200/vendor.bundle.js:457:18) [angular]
window.console.error @ VM13634:27
VM13634:27 ZoneAwareError

Extra state causes token parse to fail

Hi,

There is a bug in the tryLogin function. When you have additional state, the state is sent to the IDP as a string, seperated with ;. This is URL encoded due to it being passed around by the IDP, and then when the code tries to split the string later on, it cannot split the string on the delimiter ; and so the nonce checking fails.

https://github.com/manfredsteyer/angular-oauth2-oidc/blob/master/src/oauth-service.ts#L282-L294

A fix would be to URL decode the string before splitting the state by ;.

Cheers

"expires_in" does not work

Hi,

the key for "expires_in" in line 286 of oauth-service.ts seems to be incorrect. Regarding openId Spec

Instead of
this.storeAccessTokenResponse(accessToken, null, parts['expiresIn']);
it should be
this.storeAccessTokenResponse(accessToken, null, parts['expires_in']);
if i'm correct.

The old version of this library had it correct.

Thanks in advance

Not working with Slack

This is my configuration:

constructor(private oAuthService: OAuthService) {
    this.oAuthService.loginUrl = 'https://slack.com/oauth/authorize';
    this.oAuthService.redirectUri = '<redirect_uri>';
    this.oAuthService.clientId = '<client_id>';
    this.oAuthService.scope = 'commands users:read.email chat:write:bot channels:write channels:read users:read';
    this.oAuthService.tryLogin({
      onTokenReceived: context => {
        console.debug("logged in");
        console.debug(context);
      }
    });
}

Slack redirects to <redirect_uri> passing the parameters code and state.

http://<domain>/?code=<code>&state=<state>

Looking at the oauth page from slack (https://api.slack.com/docs/oauth), these are the following steps:

  1. Authorization (https://slack.com/oauth/authorize)
  2. Token Issuing (https://slack.com/api/oauth.access)

How can I make it work with Slack?

Does not work for GitHub

I tried multiple approaches for logging in with GitHub, but it does not log me in. I can approve the app and it returns the code and state in the url, but it does not do the second step and gets the token.

Uncaught SyntaxError: Unexpected token import

Hello,

  1. I added "angular-oauth2-oidc" dependency

  2. angular-cli.json
    "scripts": [
    "../node_modules/angular-oauth2-oidc/index.ts"
    ],

  3. getting this following error
    Uncaught SyntaxError: Unexpected token import
    at eval ()
    at webpackJsonp.../../../../script-loader/addScript.js.module.exports (addScript.js:9)
    at Object.../../../../script-loader/index.js!../../../../angular-oauth2-oidc/index.ts (index.ts?3cee:1)
    at webpack_require (bootstrap 59ce402โ€ฆ:54)
    at Object.2 (scripts.bundle.js:37)
    at webpack_require (bootstrap 59ce402โ€ฆ:54)
    at webpackJsonpCallback (bootstrap 59ce402โ€ฆ:25)
    at scripts.bundle.js:1

login implicitflow method keeps looping redirecting hp, doesn't go to loginurl

I created an authservice with all parameters filled in

constructor(private oauthService: OAuthService) {

      // Login-Url
      this.oauthService.loginUrl = "https://login.microsoftonline.com/TENANT_ID_GUID/oauth2/authorize";

      // URL of the SPA to redirect the user to after login
      this.oauthService.redirectUri = window.location.origin + "/";

      // The SPA's id. Register SPA with this id at the auth-server
      this.oauthService.clientId = '';

      // set the scope for the permissions the client should request
      this.oauthService.scope = "openid profile";

      // set to true, to receive also an id_token via OpenId Connect (OIDC) in addition to the
      // OAuth2-based access_token
      this.oauthService.oidc = true;

      //resourceAppId from manifest; required because requesting id_token AND token.  Would not be requied for just id_token...
      this.oauthService.resource = '';

      // Use setStorage to use sessionStorage or another implementation of the TS-type Storage
      // instead of localStorage
      this.oauthService.setStorage(sessionStorage);

      // To also enable single-sign-out set the url for your auth-server's logout-endpoint here
      this.oauthService.logoutUrl = "https://login.microsoftonline.com/TENANT_ID_GUID/oauth2/logout?id_token={{id_token}}";

      this.oauthService.issuer = "https://sts.windows.net/TENANT_ID_GUID/";

      // This method just tries to parse the token(s) within the url when
      // the auth-server redirects the user back to the web-app
      // It dosn't send the user the the login page
      this.oauthService.tryLogin({
          onTokenReceived: context => {
              var claims = context.idClaims;
              var currentUser = {
                  name: claims.name,
                  id: claims.unique_name,
                  roles: claims.roles
              };
              sessionStorage.setItem('currentUser', JSON.stringify(currentUser));
           }
       });
    }

Then a authguard on homepage for homepage

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private oauthService: OAuthService, private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    if (this.oauthService.hasValidIdToken()) {
      return true;
    }

    this.oauthService.initImplicitFlow();
    return false;
  }
}

the this.oauthService.initImplicitFlow(); just keeps looping and refreshing homepage, there is stuff in the url but that's it. It doesn't go to login url, any ideas? here is repo https://github.com/premiumwd/a

Add postLogoutRedirectUri as a separate property to OAuthService

It would be nice to have a separate property on OAuthService for the postLogoutRedirectUri, so that the service can be configured all at once, rather than having to set the redirectUri before calling logout.

...
        public redirectUri = "";
        public postLogoutRedirectUri = "";
...

For backward compatibility, the service should fall back on the redirectUri:

...
        let logoutUrl: string;
        
        // For backward compatibility
        if (this.logoutUrl.indexOf('{{') > -1) {
            logoutUrl = this.logoutUrl.replace(/\{\{id_token\}\}/, id_token);
        }
        else {
            logoutUrl = this.logoutUrl + "?id_token_hint=" 
                                + encodeURIComponent(id_token)
                                + "&post_logout_redirect_uri="
                                + encodeURIComponent(this.postLogoutRedirectUri || this.redirectUri);
        }
        location.href = logoutUrl;
...

Is it possible to save the token?

Is it possible to save the token for use later and then verify if the token is valid before requesting a new one?

Edit: Use case would be allowing a user to book mark a certain "page" within the app and then navigate back to it using the saved token instead of requesting a new one and then being redirected back to the landing page.

I know you can change the storage to "localStorage" but the module doesn't seem to utilize the stored key.

logOut() does not end session on ID provider

I have the following configured in my AppComponent:

export class AppComponent {

    constructor(private router: Router,
        private oauthService: OAuthService) {

        // Login-Url
        this.oauthService.loginUrl = "https://login.microsoftonline.com/TENANT_ID_GUID/oauth2/authorize";

        // URL of the SPA to redirect the user to after login
        this.oauthService.redirectUri = window.location.origin + "/";

        // The SPA's id. Register SPA with this id at the auth-server
        this.oauthService.clientId = CLIENT_ID_GUID;

        // set the scope for the permissions the client should request
        this.oauthService.scope = "openid profile";

        // set to true, to receive also an id_token via OpenId Connect (OIDC) in addition to the
        // OAuth2-based access_token
        this.oauthService.oidc = true;

        //resourceAppId from manifest; required because requesting id_token AND token.  Would not be requied for just id_token...
        this.oauthService.resource = RESOURCE_ID_GUID;

        // Use setStorage to use sessionStorage or another implementation of the TS-type Storage
        // instead of localStorage
        this.oauthService.setStorage(sessionStorage);

        // To also enable single-sign-out set the url for your auth-server's logout-endpoint here
        this.oauthService.logoutUrl = "https://login.microsoftonline.com/TENANT_ID_GUID/oauth2/logout?id_token={{id_token}}";

        this.oauthService.issuer = "https://sts.windows.net/TENANT_ID_GUID/";

        // This method just tries to parse the token(s) within the url when
        // the auth-server redirects the user back to the web-app
        // It dosn't send the user the the login page
        this.oauthService.tryLogin({
            onTokenReceived: context => {
                var claims = context.idClaims;
                var currentUser = {
                    name: claims.name,
                    id: claims.unique_name,
                    roles: claims.roles
                };
                sessionStorage.setItem('currentUser', JSON.stringify(currentUser));
            }
        });
}

When I call oauthService.logOut(), it does not end the session on the ID provider server (Azure AD). If I call oauthService.getAccessToken() it returns null and oauthService.hasValidAccessToken() returns false, but if I navigate to my ID provider login page (https://login.microsoftonline.com), my session is still active.

FWIW, I'm using v1.0.20.

Error

I have this error

Failed to load resource: the server responded with a status of 404 (Not Found)
localhost/:51 (SystemJS) XHR error (404 Not Found) loading http://localhost:5555/node_modules/angular-oauth2-oidc.js
Error: XHR error (404 Not Found) loading http://localhost:5555/node_modules/angular-oauth2-oidc.js
at XMLHttpRequest.wrapFn [as _onreadystatechange] (http://localhost:5555/node_modules/zone.js/dist/zone.js?1486029206310:1039:29) []
at Zone.runTask (http://localhost:5555/node_modules/zone.js/dist/zone.js?1486029206310:151:47) [ => ]
at XMLHttpRequest.ZoneTask.invoke (http://localhost:5555/node_modules/zone.js/dist/zone.js?1486029206310:345:33) []
Error loading http://localhost:5555/node_modules/angular-oauth2-oidc.js as "angular-oauth2-oidc" from http://localhost:5555/app/app.module.js Not expecting this error? Report it at https://github.com/mgechev/angular-seed/issues
(anonymous) @ (index):51
http://localhost:5555/node_modules/angular-oauth2-oidc.js Failed to load resource: the server responded with a status of 404 (Not Found)

Error after upgrading angular-cli

I get the following error after upgrading angular-cli:

ERROR in Error encountered resolving symbol values statically. Calling function 'OAuthModule', function calls are not supported. Consider replacing the function or lambda with a refer
ence to an exported function, resolving symbol AppModule in ...

It looks like there is an error in the angular part, but for the moment i can't use your package and i'm not sure if the angular team will change anything. I've compared your package with working code from FexLayoutModule or MaterialModule, but i don't get the difference... :-(

Here is the issue depending to this:
angular/angular#13931

Perhaps you know a solution for that, or gues whether the problem is in your, mine or the angular part :-)

Not working without Document Discovery

Maybe I'm misunderstanding how this is supposed to be working. But I'm attempting to use it for OAuth with a provider that doesn't have a publicly accessible discovery document for their OpenID Configuration. I've tried for hours to get this working but it never actually navigates to the providers login/consent page. If I take the login url that is generated out of the library and paste that in my browser it takes me to their consent screen just as expected. In order to test the theory, I have been able to get a working example using Google as a provider with Document Discovery. If I take the exact values that are extracted from their openid-configuration and set them manually and remove Document Discovery, it stops working and in fact behaves just like the other provider. Below are the configurations I'm using for Google with and without Document Discovery.

With Discovery:

constructor(private oauthService: OAuthService) {
    this.oauthService.redirectUri = window.location.origin + '/index.html';
    this.oauthService.clientId = '<client-id>';
    this.oauthService.scope = 'openid email profile';
    this.oauthService.oidc = true;
    this.oauthService.setStorage(sessionStorage);
    this.oauthService.issuer = 'https://accounts.google.com'
    this.oauthService.loadDiscoveryDocument().then(() => {
      this.oauthService.tryLogin({
        onTokenReceived: context => {
          console.log('logged in');
          console.log(context);
        }
      });
    });
  }

  public login(): void {
    this.oauthService.initImplicitFlow();
  }

Without Discovery:

this.oauthService.loginUrl = 'https://accounts.google.com/o/oauth2/v2/auth';
    this.oauthService.tokenEndpoint = 'https://www.googleapis.com/oauth2/v4/token';
    this.oauthService.userinfoEndpoint = 'https://www.googleapis.com/oauth2/v3/userinfo';
    this.oauthService.redirectUri = window.location.origin + '/index.html';
    this.oauthService.clientId = '<client-id>';
    this.oauthService.scope = 'openid email profile';
    this.oauthService.oidc = true;
    this.oauthService.setStorage(sessionStorage);
    this.oauthService.issuer = 'https://accounts.google.com';
    this.oauthService.tryLogin({});

Routing Blocked with Additional Api Call - CanActivate Guard

Background/Scenario

In utilizing the library by hitting url 'someurl/1' as the initial page, my app sets the settings for the oauthservice on the app component constructor level. The AuthorizationGuardService then determines you are not authorized by using the oauthservice.hasValidIdToken() the default route configured to the login component kicks in and calls oauthservice.initImplicitFlow() triggering the IDP redirects which ultimately is returned to the same login route it came from. We check that oauthservice.hasValidIdToken() is true then redirect back to the guarded route. which also makes the same oauthService.hasValidIdToken() call and then an additional api call for permissions. This returns an observable boolean. When the observable/api call resolves, the guard should allow the route to pass through. It doesn't it just sits there without any error and never allows the protected route to load. The router seems to be cancelling navigation when tracing is on.

I removed the calls to the oauthService and the same method works fine ultimately resolving the protected route. The general code structure is below. Package version is 1.0.20 on angular 4.1.3.

app.component.ts

import { Component, Inject } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { AppConfig } from './app.config';

@Component({
    selector: 'my-app',
    styleUrls: [ './app.component.scss' ],
    templateUrl: './app.component.html'
})
export class AppComponent {
    constructor(private _config: AppConfig,
                private _oauthService: OAuthService) {
        this._oauthService.loginUrl = _config.settings.loginEndpoint;
        this._oauthService.redirectUri = _config.settings.redirectUri;
        this._oauthService.clientId = _config.settings.clientId;
        this._oauthService.scope = _config.settings.scope;
        this._oauthService.oidc = _config.settings.oidc;
        this._oauthService.tryLogin({});
    }
}

login.component.ts

import { Component, OnInit, Inject } from '@angular/core';
import { Router } from '@angular/router';
import { OAuthService } from 'angular-oauth2-oidc';

@Component({
  template: ''
})
export class LoginComponent implements OnInit {
  constructor(private _oauthService: OAuthService, private _router: Router) {
  }

  ngOnInit(): void {
    let id =1;

    if (this._oauthService.hasValidIdToken()) {
      if (id)
        this._router.navigate(['/someurl', id]);
    }
    else
      this.login();
  }

  login() {
    this._oauthService.initImplicitFlow();
  }
}

authorization.guard.service.ts

import { permissionServiceInterface, IPermissionService } from './../permission/permission.service';
import { OAuthService } from 'angular-oauth2-oidc';
import { Observable } from 'rxjs/Observable';
import { CanActivate, ActivatedRouteSnapshot, Router, RouterStateSnapshot, NavigationExtras } from '@angular/router';
import { Inject, Injectable } from '@angular/core';

@Injectable()
export class AuthorizationGuardService implements CanActivate {
    constructor(private _oauthService: OAuthService,
        private _router: Router,
        @Inject(permissionServiceInterface) private _permissionService: IPermissionService) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
        let id = route.params['id'];

        if (this._oauthService.hasValidIdToken())
            return this.checkRoutePermissions(+id);

        this._router.navigate(['/login']);
        return false;
    }

    private checkRoutePermissions(id: number): Observable<boolean> {
        return this._permissionService.checkAuthority(id);
    }
}

permission.service.ts

import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
import { Http, Response } from '@angular/http';
import { Injectable, OpaqueToken } from '@angular/core';

export let permissionServiceInterface = new OpaqueToken('IPermissionService');

export interface IPermissionService {
    checkAuthority(id: number): Observable<boolean>;
}

@Injectable()
export class PermisisonService implements IPermissionService {
    private _apiUrl: string;

    constructor(private _http: Http, private _config: AppConfig,
                router: Router) {
        super(router);
        this._apiUrl = 'someurl';
    }

    checkAuthority(id: number): Observable<boolean> {
        this._apiUrl = 'someurl/id';

        return this._http.get(this._apiUrl)
                    .map((response) => {
                        return response.json() as boolean;
                    });
    }
}

Return URLs with ? not properly parsed

When the return URL looks like

https://localhost:6001/#/home?id_token=...&access_token=...&token_type=Bearer
&expires_in=3600&scope=...&state=...&session_state=...

then I get the following JSON from getFragment()

{
  "home?id_token": "...",
  "access_token": "...",
  "token_type": "Bearer",
  "expires_in": "3600",
  "scope": "...",
  "state": "...",
  "session_state": "..."
}

obviously, the home? part should not be in this json. Apparently the issue is because the method getFragment, which parses everything after the # sign, instead of everything after the ? sign:

    getFragment() {
        if (window.location.hash.indexOf("#") === 0) {
            return this.parseQueryString(window.location.hash.substr(1));
        } else {
            return {};
        }
    };

it should probably look like:

    getFragment() {
         const questionMarkPosition = window.location.href.indexOf('?');
         if (questionMarkPosition >= 0) {
             var queryString = window.location.href.slice(questionMarkPosition + 1);
             return this.parseQueryString(queryString);
        }

        if (window.location.hash.indexOf("#") === 0) {
            return this.parseQueryString(window.location.hash.substr(1));
        }

        return {};
        }
    };

how to use password pattern without discovery document?

when i use password pattern without discovery document, occur errors.
project can not do the right request to the auth-server.

constructor(private oauthService: OAuthService) {

    // Login-Url
    this.oauthService.loginUrl = 'https://accounts.google.com/o/oauth2/v2/auth'; //Id-Provider?

    // URL of the SPA to redirect the user to after login
    this.oauthService.redirectUri = window.location.origin;

    // The SPA's id. Register SPA with this id at the auth-server
    this.oauthService.clientId = '<client-id>';

    // set the scope for the permissions the client should request
    this.oauthService.scope = 'profile email https://www.googleapis.com/auth/drive';

    // set to true, to receive also an id_token via OpenId Connect (OIDC) in addition to the
    // OAuth2-based access_token
    this.oauthService.oidc = true;

    // Use setStorage to use sessionStorage or another implementation of the TS-type Storage
    // instead of localStorage
    this.oauthService.setStorage(sessionStorage);
    this.oauthService.issuer = 'https://www.googleapis.com';

    // To also enable single-sign-out set the url for your auth-server's logout-endpoint here
    // this.oauthService.logoutUrl = "https://steyer-identity-server.azurewebsites.net/identity/connect/endsession?id_token={{id_token}}";

    // Set a dummy secret
    // Please note that the auth-server used here demand the client to transmit a client secret, although
    // the standard explicitly cites that the password flow can also be used without it. Using a client secret
    // does not make sense for a SPA that runs in the browser. That's why the property is called dummyClientSecret
    // Using such a dummy secreat is as safe as using no secret.
    this.oauthService.dummyClientSecret = '<client-secret>';

    // This method just tries to parse the token(s) within the url when
    // the auth-server redirects the user back to the web-app
    // It dosn't send the user the the login page
    this.oauthService.tryLogin({
      onTokenReceived: (context) => {
        console.log('logged in', context);
      }
    });
    
  }

2017-07-19_100933

Detection of wrong credentials for PasswordFlow

When the users passes credentials, that are not accepted by the identity provider, I would like to detect this and present an error message, pointing the user into the right direction. I cannot seem to get this to work, here is a code snippet:

 this.oauthService
            .fetchTokenUsingPasswordFlowAndLoadUserProfile(this.user.username, this.user.password)
            .then(() => {
                console.debug('successfully logged in');
                let claims = this.oauthService.getIdentityClaims();
                this.loginFailed = false;
            })
            .catch((err) => {
                console.error('error logging in', err);
                this.loginFailed = true;
                this.errorMessage = this.labels.APP_UNAVAILABLE;
            })

The err object is a ProgressEvent and I cannot find anything useful to differentiate the error that happened.
error

Is this currently supported?

No need to import all of rxjs

This statement in oauth-service.ts imports ALL of rxjs which increases the size of app by a large amount. It's unnecessary.

import { Observable, Observer } from 'rxjs';

replacing it by this:

import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';

would dramatically reduce the size of the app.

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.