I am trying to implement some code that runs after the AuthorizationResult is complete and authorized. In my own code (based on your dotnet-angular-azure-ad-oidc sample), I consistently get AuthorizationResult.unauthorized returned when the user is unauthorized. However, I cannot get it to returnAuthorizationResult.authorized ever. To be clear, the authorization is successful, as I am able to see the token, and use the getIsAuthorized to change the nav bar.
In the constructor, I have:
this.oidcSecurityService.onAuthorizationResult.subscribe(
(authorizationResult: AuthorizationResult) => {
this.onAuthorizationResultComplete(authorizationResult);
});
which calls
private onAuthorizationResultComplete(authorizationResult: AuthorizationResult) {
console.log('AppComponent:onAuthorizationResultComplete');
const path = this.read('redirect');
if (authorizationResult === AuthorizationResult.authorized) {
this.router.navigate([path]);
} else {
this.router.navigate(['/Unauthorized']);
}
}
But as I said above, this only ever gets AuthorizationResult.unauthorized passed into it. My hope is to add my own post-successful login code into the AuthorizationResult.authorized code block above.
I have noticed that whether I run your sample code (pointing to our Azure AD), or my own code, that I get a TypeError: Cannot read property 'toLowerCase' of undefined, which may or may not be related.
stack:"TypeError: Cannot read property 'toLowerCase' of undefined\n at HttpXsrfInterceptor.push../node_modules/@angular/common/fesm5/http.js.HttpXsrfInterceptor.intercept (http://localhost:4200/vendor.js:8032:29)\n at HttpInterceptorHandler.push../node_modules/@angular/common/fesm5/http.js.HttpInterceptorHandler.handle (http://localhost:4200/vendor.js:7412:33)\n at HttpInterceptingHandler.push../node_modules/@angular/common/fesm5/http.js.HttpInterceptingHandler.handle (http://localhost:4200/vendor.js:8085:27)\n at MergeMapSubscriber.project (http://localhost:4200/vendor.js:7163:184)\n at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (http://localhost:4200/vendor.js:79776:27)\n at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (http://localhost:4200/vendor.js:79766:18)\n at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (http://localhost:420...
Finally, I do have the configuration set to call that event handler:
openIDImplicitFlowConfiguration.trigger_authorization_result_event = true;
This is with Angular 6.0.5 (sample code) and 5.2.9 (my code) on Node 8.11.1.
Any suggestions or ideas?
The console.log line before the error is:
storing to storage, getting the roles
angular-auth-oidc-client.es5.js:1027
I use something like this:
this.isAuthorized$ = Observable.combineLatest(new Observable<boolean>((subscriber) => {
if (this.oidcSecurityService.moduleSetup) {
subscriber.next(true);
subscriber.complete();
}
else {
this.oidcSecurityService.onModuleSetup.take(1).subscribe(() => {
subscriber.next(true);
subscriber.complete();
});
}
}), this.silentRenewSetupComplete$)
.map(([setupComplete, silentRenewSetupComplete]) => {
return setupComplete && silentRenewSetupComplete;
})
.filter((complete) => {
return complete == true;
})
.switchMap(() => {
var race = Observable.race<any>(
this.oidcSecurityService.getIsAuthorized().filter((isAuthorized) => isAuthorized == true),
this.oidcSecurityService.onAuthorizationResult.asObservable()
);
this.oidcSecurityService.refreshSession();
return race;
})
.switchMapTo(this.oidcSecurityService.getIsAuthorized())
.shareReplay(1);
Maybe that can help you?
Thanks @profet23. I was able to get my code to work this morning by putting it in a subscription to getIsAuthorized().
That said, I'd still like to figure out why onAuthorizationResultComplete isn't called for an authorized result. I'll keep digging on that one :)
I figured it out!
Azure AD, which we are authenticating against, has not implemented the UserInfo end point. The default setting for auto_userinfo here in AuthConfiguration is "true". This causes execution to go down the path:
if (this.authConfiguration.auto_userinfo) {
this.getUserinfo(
isRenewProcess,
result,
validationResult.id_token,
validationResult.decoded_id_token
).subscribe(response => {
if (response) {
this.onAuthorizationResult.emit(AuthorizationResult.authorized);
if (!this.authConfiguration.trigger_authorization_result_event && !isRenewProcess) {
this.router.navigate([
this.authConfiguration.post_login_route
]);
}
} else {
this.onAuthorizationResult.emit(AuthorizationResult.unauthorized);
if (!this.authConfiguration.trigger_authorization_result_event && !isRenewProcess) {
this.router.navigate([
this.authConfiguration.unauthorized_route
]);
}
}
});
That subscribe doesn't have a catch/catchError associated with it, so it just never executes. Hence, no AuthorizationResult.authorized is ever emitted, and the onAuthorizationResultComplete is never called.
Setting openIDImplicitFlowConfiguration.auto_userinfo = false; in app.module.ts made everything work properly.
I'll submit a pull request for adding the catch for your review shortly.
PR 246 submitted
fixed in release 6.0.2
Most helpful comment
PR 246 submitted