Giter VIP home page Giter VIP logo

angular2-keycloak's Introduction

angular2-keycloak

Native Typescript Keycloak library for angular2/4.

Installation

To install this library, run:

$ npm install @ebondu/angular2-keycloak --save

Development

To generate all *.js, *.js.map and *.d.ts files:

$ npm run tsc

To lint all *.ts files:

$ npm run lint

Usage

Declare Keycloak module in angular app :

import { Ng2KeycloakModule } from '@ebondu/angular2-keycloak';
...

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    Ng2KeycloakModule
  ],
  providers: [
    ...
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

To login

import { Keycloak } from '@ebondu/angular2-keycloak';
...

export class MyLoginClass implements OnInit {

  public parsedToken: any;
  public isAuthenticated: boolean;
  public profile: any;

  constructor( private keycloak: Keycloak) {
    Keycloak.authenticatedObs.subscribe(auth => {
      this.isAuthenticated = auth;
      this.parsedToken = Keycloak.tokenParsed;

      console.info('APP: authentication status changed...');
    });
    this.keycloak.init({});
  }

  ngOnInit() {
    // Configure the Keycloak
    Keycloak.config = 'assets/keycloak.json';

    // Initialise the Keycloak
    this.keycloak.init({
      checkLoginIframe: false
    });
  }

  login() {
    Keycloak.login({});
  }

  logout() {
    Keycloak.logout({});
  }

  loadProfile() {
    Keycloak.loadUserProfile().subscribe(profile => {
      this.profile = profile;
    });
  }

  ...
}

Please, use Http interface to get access to Keycloak http proxy (authentication / authorization). Angular will inject the right provider class for you.

import { Http } from '@angular/http';
...

@Injectable()
export class MyClass {
    // Angualar will inject the instance of the KeycloakHttp class
    constructor(private http: Http) {}

    callAPI(): Observable<MyObject> {

      let headers = new Headers({'Accept' :'application/json'});
      let options: RequestOptionsArgs = { headers: headers };
        return this.http.get("http://localhost/myAPI/myMethod",  options)
            .map(res => res.json())
            .catch(err => handleError(err));
     }
     ...
}

Example

See angular2-webpack-product-app

License

Apache2 © ebondu

angular2-keycloak

angular2-keycloak's People

Contributors

akserg avatar ebondu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

angular2-keycloak's Issues

forkAndJoin not working

has anyone gotten forkAndJoin to work? looks like http responses return, but looks like there is an issue with observable...

[Help] Any way to use the adapter with my webapp login form ?

Is there any way to use the wrapper (keep the refresh tokens management to the adapter) and use my webapp login form to initiate the keycloak login ?
The webapp being the entrypoint of all our services, I want to keep the login context in it, but can't find a way to pass my form params to the adapter and let it manage the auth lifecycle.

Example App: Wrong resource url

When running the example app following the "Test with an existing keycloak server running" instructions, the app will fail to run properly due to the fact that all static resource URLs expect the content of the angular2-keycloak/example/angular2-webpack-product-app/src/public/ directory to be found at http://localhost:8080/angular2-product while they are actually hosted at the root http://localhost:8080/.
The main issue is that the keycloak.json configuration file cannot be found.
A workaround is to move all content of the public folder into a new subfolder called angular2-product. You will probably want to create a proper fix though.

How to use environment variables?

In applications that use automated deploy it is necessary to inject the environment variables in the angular application.
It is necessary to have another form of configuration besides the file keycloak.json
What is the best way to include the settings through the environment variables?

Code copied from the keycloak-js library

I noticed that you seem to have copied/rewritten large chunks of code from the keycloak-js library (https://github.com/keycloak/keycloak/tree/master/adapters/oidc/js/src/main/resources). Since that library is maintained and officially supported by the keycloak core team, wouldn't it be better to wrap the library instead of duplicating its code? If this was a conscious decision, could you provide some insight into the reasoning that lead to this approach?

If there is no reason not to wrap keycloak-js, would you consider refactoring this project in a way that it uses the official client instead? Would you accept a pull request if you are not available to put in the work yourself?

Given that your code is much more readable then the current keycloak-js version, have you tried to get in contact with their core team to recontribute your code?

Invalid parameter: redirect_uri (v 0.9 )

I have a problem with client redirection, when i run ng serve, it all works perfectly but when click login
get this error

schermata del 2017-08-25 15-36-06

schermata del 2017-08-25 15-36-50

schermata del 2017-08-25 15-37-07

and this is my keycloak client

schermata del 2017-08-25 15-42-26

the url inside keycloak is:
http://localhost:8080/auth/realms/onkalo/protocol/openid-connect/auth?client_id=onakalo-public&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fonkalo-angular&state=fd07d718-cb27-e8c9-8793-42fbe7bed93c&nonce=b5f2b15c-8e6b-cb44-163e-6b4ad1bc055e&response_mode=fragment&response_type=code&scope=openid

this is keycloak log
15:39:28,229 WARN [org.keycloak.events] (default task-58) type=LOGIN_ERROR, realmId=onkalo, clientId=onakalo-public, userId=null, ipAddress=127.0.0.1, error=invalid_redirect_uri, redirect_uri=http://localhost:4200/onkalo-angular

Maybe I have to build, because the problem is vendor.bundle.js
I also tried to pass the url in the login method but not work:

login() {
    this.keycloak.login({ redirectUri: 'http://localhost:4200/onkalo-angular' });
  }

No authentication success signals w/ fragment response, standard flow, and iFrame check

I'm currently attempting to use this library with the following init options:

   this.initOptions = {
      adapter: 'default',
      flow: 'standard',
      responseMode: 'fragment',
      checkLoginIframe: true,
      checkLoginIframeInterval: 5
    };

With the latest 0.9.1 release, I've no problem getting a call to login() to redirect to my authentication form and return with an access token, but the application never detects the successful authentication by firing true value down either authenticatedObs or authenticateSuccessObs.

Digging into the code a little bit, I tracked the problem into the URIParser utility used by the callback to extract the required input from the browser's current location. The "oauth" structure it returns currently looks like this:

{ 
    url: "http://www.foo.com/path/is/correct",
    state: "state",
    code: "code"
}

It looks like a fairly easily corrected error near the bottom of the URIParser file. In the loop where it is copying values from the hash of parsed fragment key/value pairs it is simply assigning the keys it is iterating over instead of their de-referenced values.

I hacked my workspace by changing line 126 of this block:

       for (const param in fragmentParams) {
           if (param) {
              oauth[param] = param;
           }
       }

... to copy the value for each required key instead of setting the key itself ...

       for (const param in fragmentParams) {
           if (param) {
                oauth[param] = fragmentParams[param];
           }
       }

I'm having a little trouble working out how to build and run tests for this project, or I would have tried to attach a test case along with this issue and the associated pull request, but didn't want that to keep me from offering the tip. Would be great to be able to drop the one liner patch from my README file--so far the rest of my experience with this library has been very smooth. Thanks for putting it up!

Keycloak is initiated when Http is declared

Hey,
It seems the Keycloak object is initiated as soon as the Http library is called... Which is problematic since it fires up with all the basic config and not the one I would like to set.

Any ideas why this is happening ?

Thanks !

After login success parsedToken, isAuthenticated and profile is null or false (v 0.9)

After login the following variables are false or null

parsenToken
isAuthenticated
profile

this is the HomeComponent

export class HomeComponent implements OnInit {

  private parsedToken: any;
  private isAuthenticated: boolean;

  products: string[] = [];
  private profile: any;
  constructor(private keycloak: Keycloak,
              private keycloakAuthz: KeycloakAuthorization,
              private http: Http) {


    Keycloak.authenticatedObs.subscribe(auth => {
      this.isAuthenticated = auth;
      this.parsedToken = keycloak.tokenParsed;
      /*console.info('APP: authentication status changed...');*/
    });
  }

  ngOnInit() {
   /* console.info('APP : initializing home component...');*/

    this.keycloakAuthz.init();

    // comment or change regarding your app-name
    this.keycloak.config = 'keycloak.json';

    this.keycloak.init({
      checkLoginIframe: false
    });
  }


  login() {
    this.keycloak.login({});
  }

  logout() {
    this.keycloak.logout({});
  }

  loadProfile() {
    this.keycloak.loadUserProfile().subscribe(profile => {
      this.profile = profile;
    });
  }
}

I have change the Keycloak.tokenParsed with keycloak.tokenParsed

after login success
schermata del 2017-08-25 19-45-11

Premature Token Expiration

Working on trying to integrate the Observable signal sources I've bumped into a bug that's causing my sessions to get closed down right after returning from login.

The problem seems to be in the service handling code that is attempting to use setTimeout( ) in order to schedule a callback to pushTokenExpired( ) at the calculated expiration time. The calculated time seems to be correct, but instead of passing a reference to pushTokenExpired for future callback, the code is calling pushTokenExpired() and scheduling some behavior for whatever it returns.

`this.tokenTimeoutHandle` = setTimeout(this.pushTokenExpired(), expiresIn * 1000);

All that pushTokenExpired() does is fire one of the expiration observables, so I'm reasonably certain that calling it instead of passing it as a reference is a mistake and the intended logic is:

`this.tokenTimeoutHandle` = setTimeout(this.pushTokenExpired, expiresIn * 1000);

A workaround for the moment could be to just ignore the observables for token expiration. The Observables that fire on successful login are separate from those that manage expiration, so I can just disregard the expiration signals for now, but it would be better if they just behaved correctly.

error while loading the keycloak.json config

Hello,

while using v.0.9.1 there raise an error whiler loading the keycloak.json config.

Keycloak.prototype.loadConfig = function (url) {
        var _this = this;
        return new Observable(function (observer) {
            var configUrl = '';
            if (!_this.config) {
                configUrl = 'keycloak.json';
            }
            else if (typeof _this.config === 'string') {
                configUrl = _this.config;
            }
            if (configUrl) {
                _this.http

http is at this point undefied.

The component:

import { Component, OnInit } from '@angular/core';
import {Keycloak, KeycloakAuthorization} from "@ebondu/angular2-keycloak";
import {Response,Headers, Http, RequestOptionsArgs} from "@angular/http";

@Component({
  selector: 'keycloak-secured-component',
  templateUrl: './keycloak-secured-component.component.html',
  styles: []
})
export class KeycloakSecuredComponentComponent implements OnInit {
    private parsedToken: any;
    private isAuthenticated: boolean;


    products: string[] = [];
    private profile: any;
  //constructor() { }
    constructor(private keycloak: Keycloak, private keycloakAuthz: KeycloakAuthorization, private http: Http) {

        Keycloak.authenticatedObs.subscribe(auth => {
            this.isAuthenticated = auth;
            this.parsedToken = keycloak.tokenParsed;

            console.info('APP: authentication status changed...' + this.isAuthenticated);
        });
    }
    ngOnInit() {
        console.info('APP : initializing home component...');

        this.keycloakAuthz.init();

        this.keycloak.config=JSON.stringify({
            "realm": "Traeger_A",
            "auth-server-url": "....",
            "ssl-required": "external",
            "resource": "app-profile-html5",
            "disable-trust-manager": true,
            "enable-cors": true,
            "credentials": {
                "secret": "..."
            }
        });


        this.keycloak.init({
            checkLoginIframe: false
        });
    }

    login() {
        this.keycloak.login({});
    }

    logout() {
        this.keycloak.logout({});
    }

    loadProfile() {
        this.keycloak.loadUserProfile().subscribe(profile => {
            this.profile = profile;
        });
    }

    reloadData() {
        let headers = new Headers({ 'Content-Type': 'application/json', 'Accept' :'application/json'});
        let options: RequestOptionsArgs = { headers: headers, withCredentials: true };

        // change regarding your backend address
        this.http.get('/database/products', options)
            .map((res: Response) => res.json())
            .subscribe(prods => this.products = prods,
                error => console.log(error));
    }

}

thanks for any help
ticxx

Bug in public updateToken

Hello,

updateToken throw always an error ,
due to a typo in keycloak.core.service.js line 68

'Basic ' + btoa(this.clientId + ': ' + this.clientSecret)

headers.append('Authorization', 'Basic ' + btoa(_this.clientId + ': ' + _this.clientSecret));
should be (no space after the colon)
headers.append('Authorization', 'Basic ' + btoa(_this.clientId + ':' + _this.clientSecret));

regards, ticxx

ERROR in Ng2KeycloakModule is not an NgModule

Trying to integrate this into my angular 4 app.

  • Angular 4.0.0
  • Angular Cli 1.0.3
  • TypeScript 2.2.0

Getting the following error when I try to import the module and run 'ng build':

ERROR in Ng2KeycloakModule is not an NgModule

LogIn in browser not redirect

When login is correct in the same web page it redirect to localhost... not to my app, i think it sould close de navigator maybe?

Error when compile only Import KeycloakModule v 0.9 inside app.module.ts

I use Angular Cli, when import KeycloakModule v 0.9 inside app.module.ts get this error

ERROR in ./~/@ebondu/angular2-keycloak/services/keycloak.core.service.js
Module not found: Error: Can't resolve 'angular2-uuid' in '/home/pasquale/IdeaProjects/onkalo/onkalo-angular/node_modules/@ebondu/angular2-keycloak/services'
 @ ./~/@ebondu/angular2-keycloak/services/keycloak.core.service.js 30:0-37
 @ ./~/@ebondu/angular2-keycloak/keycloak.module.js
 @ ./~/@ebondu/angular2-keycloak/index.js
 @ ./src/app/app.module.ts
 @ ./src/main.ts
 @ multi webpack-dev-server/client?http://localhost:4200 ./src/main.ts

Why checkLoginIframe should be marked as false?

I was using this module but I don't know why checkLoginIframe should be marked as false. Is There a problem if I use checkLoginIframe as true?

I tried to mark checkLoginIframe as true and it seems that login don't work after that...

I need help!

Uncaught Error: Unexpected value 'Ng2KeycloakModule' declared by the module 'AppModule'. Please add a @Pipe/@Directive/@component annotation.

Example App: at-loader errors

I'm getting the following error message when starting the example app in the ng4 branch:

94% asset optimization                                                                  
[at-loader] Checking started in a separate process...

[at-loader] Checking finished with 125 errors

I'm trying to integrate this module in projects generated with angular-starter and jhipster's client generator but I'd like to see it work in an example first.

Compatibility with Angular 4.0.0

Hi,

I'm new in the world JS with Angular + Typescript + Webpack :)

I've tried to implement your module to use KC

My package.json looks like

  "dependencies": {
    "@angular/common": "4.0.0",
    "@angular/compiler": "4.0.0",
    "@angular/core": "4.0.0",
    "@angular/forms": "4.0.0",
    "@angular/http": "4.0.0",
    "@angular/platform-browser": "4.0.0",
    "@angular/platform-browser-dynamic": "4.0.0",
    "@angular/router": "4.0.0",
    "@ebondu/angular2-keycloak": "^0.6.0",
    "angular2-text-mask": "8.0.0",
    "core-js": "^2.4.1",
    "moment": "2.18.1",
    "ng2-bootstrap": "1.6.1",
    "reflect-metadata": "^0.1.3",
    "rxjs": "^5.0.1",
    "ts-promise": "^0.3.4",
    "zone.js": "^0.8.5"
  },

I've modified my main module (named BopModule) and my component to implement OnInit like the usage https://github.com/ebondu/angular2-keycloak#usage

When i run my start my application (npm start), i obtain the error in my JS console

Uncaught Error: Unexpected value 'Ng2KeycloakModule' imported by the module 'BopModule'. Please add a @NgModule annotation.
    at syntaxError (eval at <anonymous> (http://localhost:8080/js/vendor.js:1020:1), <anonymous>:1682:34) [<root>]
    at eval (eval at <anonymous> (http://localhost:8080/js/vendor.js:1020:1), <anonymous>:14137:44) [<root>]
    at Array.forEach (native) [<root>]
    at CompileMetadataResolver.getNgModuleMetadata (eval at <anonymous> (http://localhost:8080/js/vendor.js:1020:1), <anonymous>:14120:49) [<root>]
    at JitCompiler._loadModules (eval at <anonymous> (http://localhost:8080/js/vendor.js:1020:1), <anonymous>:25222:64) [<root>]
    at JitCompiler._compileModuleAndComponents (eval at <anonymous> (http://localhost:8080/js/vendor.js:1020:1), <anonymous>:25181:52) [<root>]
    at JitCompiler.compileModuleAsync (eval at <anonymous> (http://localhost:8080/js/vendor.js:1020:1), <anonymous>:25143:21) [<root>]
    at PlatformRef_._bootstrapModuleWithZone (eval at <anonymous> (http://localhost:8080/js/vendor.js:14:1), <anonymous>:5014:25) [<root>]
    at PlatformRef_.bootstrapModule (eval at <anonymous> (http://localhost:8080/js/vendor.js:14:1), <anonymous>:4999:21) [<root>]
    at HTMLDocument.main (eval at <anonymous> (http://localhost:8080/js/app.js:2216:1), <anonymous>:11:64) [<root>]
    at Zone.runTask (eval at 898 (http://localhost:8080/js/polyfills.js:838:1), <anonymous>:165:47) [<root> => <root>]
    at HTMLDocument.ZoneTask.invoke (eval at 898 (http://localhost:8080/js/polyfills.js:838:1), <anonymous>:460:38) [<root>]

My BopModule look like

import { Ng2KeycloakModule } from '@ebondu/angular2-keycloak';

@NgModule({
    imports: [
        ModalModule.forRoot(),
        BopRoutingModule,
        BrowserModule,
        FormsModule,
        StyleguideModule,
        HttpModule,
        Ng2KeycloakModule
    ],
    providers: [
        routingProviders
    ],
    declarations: [
        BopComponent,
        StyleguideComponent,
    ],
    bootstrap: [BopComponent]
})
export class BopModule {
}

Do you think i've made a mistake ?
Or do you think that your library could be incompatible with Angular4 ?

Thanks for yout help

Authentication data lost after Keycloak redirects back to the app

Hi,

I'm trying to make this module work in my starter project but I hit some walls.

After doing some debugging and googling I came to the conclusion that after Keycloak redirects back to the application, all authentication parameters from the URL (code, state) are stripped by Angular so Keycloak.parseCallback and Keycloak.processCallback functions are unable to initialize the Keycloak object properly.

I tried to put the Keycloak initialization in a module constructor (link) so it runs before Angular strips the URL but Keycloak.prototype.processInit being called asynchronously (after keycloak.json is loaded) by the time it runs, the URL is stripped.

Maybe the initialization should be done synchronously? Or am missing something?

I used the following initOptions:

{
            checkLoginIframe: false,
            responseMode: 'query',
            flow: 'standard',
}

Could someone please provide a working example?

Thank you!

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.