angular-oauth2-oidc: getIdentityClaims always returns null with implicit flow
I’m trying to make an example implicit flow to work with Keycloak as an identity provider.
I’ve basically followed this tutorial and replaced all the things regarding Okta with Keycloak. When I click on the “login” button (that triggers this.oauthService.initImplicitFlow(); I’m correctly redirected to the Keycloak login page where I can login without any issue.
I’m then redirected back to my application that receives the token and a state in the URL: http://localhost:4200/#state=sijg...&id_token=eyJhb… (replaced long token with …)
I’ve tested the token on jwt.io and it seems to be correct and has the informations that I request (openid profile email).
But, when in the homepage I try to call var claims = this.oauthService.getIdentityClaims();, claims is null. Calling this.oauthService.hasValidIdToken() also returns false.
I’m not 100% sure what should be stored in the sessionStorage, but while debugging I can see that I have a “nonce” stored.
I’ve tried to compare with your sample application, but can’t see anything different. Here’s a copy of the most important files:
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { SearchComponent } from './search/search.component';
import { EditComponent } from './edit/edit.component';
import { OAuthModule } from 'angular-oauth2-oidc';
import { HomeComponent } from './home/home.component';
import { AuthGuard } from './shared';
const appRoutes: Routes = [
{ path: 'search', component: SearchComponent, canActivate: [AuthGuard] },
{ path: 'edit/:id', component: EditComponent },
{ path: 'home', component: HomeComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '*', redirectTo: 'home' }
];
@NgModule({
declarations: [
AppComponent,
SearchComponent,
EditComponent,
HomeComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
OAuthModule.forRoot(),
RouterModule.forRoot(appRoutes)
],
providers: [AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }
app.module.ts
import { Component } from '@angular/core';
import { SearchService } from './shared';
import { Http } from '@angular/http';
import { OAuthService } from 'angular-oauth2-oidc';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
viewProviders: [SearchService]
})
export class AppComponent {
title = 'app';
constructor(private oAuthService: OAuthService) {
this.oAuthService.redirectUri = window.location.origin;
this.oAuthService.clientId = 'demo-app';
this.oAuthService.scope = 'openid profile email';
this.oAuthService.oidc = true;
this.oAuthService.setStorage(sessionStorage);
this.oAuthService.issuer = 'http://[myKeycloakServer]/auth/realms/test';
this.oAuthService.requireHttps = false;
const url = 'http://[myKeycloakServer]/auth/realms/test/.well-known/openid-configuration';
this.oAuthService.loadDiscoveryDocument(url).then((doc) => {
this.oAuthService.tryLogin();
console.debug('discovery succeeded', doc);
});
}
}
auth.guard.service.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { OAuthService } from 'angular-oauth2-oidc';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private oauthService: OAuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
if (this.oauthService.hasValidIdToken()) {
return true;
}
this.router.navigate(['/home']);
return false;
}
}
home.component.ts
import { Component, OnInit } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(private oauthService: OAuthService) { }
ngOnInit(): void { }
login() {
this.oauthService.initImplicitFlow();
}
logout() {
this.oauthService.logOut();
}
get givenName() {
const claims = this.oauthService.getIdentityClaims();
if (!claims) {
return null;
}
return claims['name'];
}
}
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 18 (6 by maintainers)
@manfredsteyer I had a similar issue as this. I found I had to change my “blank” Angular route from
{ path: '', redirectTo: '/home', pathMatch: 'full' }to
{ path: '', redirectTo: 'home', pathMatch: 'full' }(no slash)When I had the slash it seemed like Angular is now eating the hash with the tokens before the auth had a chance to read it. Without the slash, auth is able to process it, and then it goes to the home route as I want.
Found the solution, replaced the redirect URI from
this.oAuthService.redirectUri = window.location.origin;tothis.oAuthService.redirectUri = window.location.origin + '/index.html';and now it’s working.Not quite sure what the issue is here, why do you have to add the index.html in the URI to make it work?