0

It is my first try with OAuth. I am using Angular 13 + angular-oauth2-oidc library and I am trying to configure code flow. My problem is that in tutorial discovery document is used by default but my auth server does not have anything like that so when in the beggining app asking about identity_provider_url/.well-known/openid-configuration I am getting an 404 error. Question is how to configure code flow without loading discovery document from auth server? I found only configuration without discovery document for implicit flow. That is how my code looks like right now:

auth.config.ts

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

export const authCodeFlowConfig: AuthConfig = {
  // Url of the Identity Provider
  issuer: '**************', // identity provider URL,
  redirectUri: window.location.origin + '/index.html',
  clientId: 'spa',
  dummyClientSecret: 'secret',
  responseType: 'code',
  scope: 'read, write',
  showDebugInformation: true,
};

app.component.ts

import {Component} from '@angular/core';
import {authCodeFlowConfig} from './sso.confiig';
import {OAuthService} from 'angular-oauth2-oidc';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'sso';

  constructor(private oAuthService: OAuthService) {
    this.oAuthService.configure(authCodeFlowConfig);
    this.oauthService.loadDiscoveryDocumentAndTryLogin(); // I don`t want this
  }
}

login.component.ts

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

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {

  constructor(private oAuthService: OAuthService) {
    this.oAuthService.events.subscribe(e => (e instanceof OAuthErrorEvent) ? console.error(e) : console.warn(e));
  }

  public async login(): Promise<void> {
    await this.oAuthService.initCodeFlow();
  }

  public logout(): void {
    this.oAuthService.logOut();
  }

  public get userName() {
    let claims = this.oAuthService.getIdentityClaims();
    if (!claims) return null;
    return claims;
  }
}
obaram
  • 321
  • 2
  • 4
  • 13
  • What kind of identity provider do you use? – SaschaLeh Feb 09 '22 at 06:58
  • @SaschaLeh It is based on https://github.com/doorkeeper-gem/doorkeeper/wiki/Authorization-Code-Flow#requesting-the-access-token – obaram Feb 09 '22 at 07:04
  • As far as i can tell the "Discovery Document" is part of the `OpenID Connect` Protocol and `doorkeeper` just implements the OAuth2 Standard. I think you need to extend `doorkeeper` whith the `OpenID Connect` extension to make it work. Or use the `Implicit Flow` https://github.com/doorkeeper-gem/doorkeeper-openid_connect – SaschaLeh Feb 09 '22 at 07:16
  • @SaschaLeh Linked GitHub repo does talk about "Authorization Code" flow being supported though? Not sure if PKCE is supported too? – Jeroen Feb 10 '22 at 09:02
  • OP, are you sure the well-known endpoint is not in your IDS? The [Doorkeeper repo has routes for the discovery document](https://github.com/doorkeeper-gem/doorkeeper-openid_connect/blob/805b7ca9c42a011e357b2d6daac88c45e7f2172a/spec/lib/routes_spec.rb#L24-L27) it seems? - Either way, you can [go through the relevant Angular code](https://github.com/manfredsteyer/angular-oauth2-oidc/blob/d95d7da788e2c1390346c66de62dc31f10d2b852/projects/lib/src/oauth-service.ts#L518-L608) to see which exact fields you _can_ configure, and choose those relevant to your situation. – Jeroen Feb 10 '22 at 09:04

2 Answers2

2

Have a look at the AuthConfig class and try setting loginUrl to the authorize endpoint and also set the token endpoint explicitly. See if this gives you a different error.

A good library should allow you to set endpoints explicitly. As an example, a couple of years ago an SPA of mine did not work with Azure AD since it did not allow CORS requests to the token endpoint. I worked around this by setting a token endpoint in the oidc client library to point to an API, so that I could call the token endpoint from there.

Gary Archer
  • 22,534
  • 2
  • 12
  • 24
0

Extending auth.config about additional loginUrl and tokenUrl solved the issue.

This is finall version of my config file:

export const OAUTH_CONFIG: AuthConfig = {
  issuer: environment.identityProviderBaseUrl,
  loginUrl: environment.identityProviderLoginUrl,
  logoutUrl: environment.identityProviderLogoutUrl,
  redirectUri: environment.identityProvideRedirectUrl,
  tokenEndpoint: environment.identityProviderTokenUrl,
  clientId: environment.clientId,
  dummyClientSecret: environment.clientSecret,
  responseType: 'code',
  requireHttps: false,
  scope: 'write',
  showDebugInformation: true,
  oidc: false,
  useIdTokenHintForSilentRefresh: false
};

Of corse then we should remember to remove loadDiscoveryDocumentAndTryLogin() .

  public configureCodeFlow(): void {
    this.authService.configure(OAUTH_CONFIG);
    this.authService.setupAutomaticSilentRefresh(undefined, 'access_token');
    this.authService.tryLoginCodeFlow();
  }
obaram
  • 321
  • 2
  • 4
  • 13