0

I am currently setting up an identity server with a SPA client and a few REST services to consume data from.

Everything seems to work but I currently struggle to understand, why every API call with a valid access_token triggers a request to the /authorize endpoint of the identity server.


Button on the login page


This button simply calls my REST API via an instance of the HttpClient from @angular/common/http

Those buttons are on my /login page.

The callback from the identity server is set up to go to /login/callback.

enter image description here


Request to the /authorize endpoint


Each click on the button sends a request to the /authorize endpoint and as a result redirects me with a http 302 to the /login/callback page.

The request stills goes through and everything work but there is always this redirect which is happening.

I would have expected that in case of a valid access_token, this request wouldn't be necessary?

enter image description here

enter image description here


AccessToken Interceptor


Within the AccessTokenInterceptor I do call my OidcService which has access to the UserManager from the oidc-client library.

For some reason every request which involves getUser() on the UserManager triggers this /authorize request in response - even though the access_token is still valid. What am I missing here?

@Injectable()
export class AccessTokenInterceptor implements HttpInterceptor {

constructor(private oidcService: OidcService) { }

intercept(request: HttpRequest<any>, next: HttpHandler): 
Observable<HttpEvent<any>> {

return this.oidcService.getUser()
  .mergeMap((user: User) => {

    if (user) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${user.access_token}`
        }
      });
    }

    return next.handle(request);
   });
  }
 }

I appreciate any help in that matter and please let me know in case you need some more code samples.


Update 1


Once I call the "Call Api" button, the following three request are made.

  1. OPTIONS request to my REST API.
  2. /authorize request (which ends up returning a http 302 and does the redirect which I would like to avoid)
  3. GET request to which is what I intended to do.

enter image description here

enter image description here

enter image description here


Update 2


Web Application - UserManagerSettings

{
    "authority": "https://localhost:44327",
    "client_id": "webClient",
    "response_type": "id_token token",
    "scope": "openid testclientapi testclientapi.read testclientapi.write",
    "redirect_uri": "http://localhost:4200/login/callback",
    "post_logout_redirect_uri": "http://localhost:4200/logout/callback",
    "silent_redirect_uri": "http://localhost:4200/login/silentLogin",
    "automaticSilentRenew": true,
    "monitorSession": true,
    "revokeAccessTokenOnSignout": true,
    "loadUserInfo": true
}

Identity Server - Client Configuration

       new Client {
                    ClientId = "webClient",
                    ClientName = "myclient",
                    AllowedGrantTypes = GrantTypes.Implicit,

                    AccessTokenType = AccessTokenType.Reference,
                    AccessTokenLifetime = 60 * 60,
                    IdentityTokenLifetime = 30,
                    RequireConsent = false,
                    AllowOfflineAccess = true,
                    AllowAccessTokensViaBrowser = true,

                    ClientSecrets =
                    {
                        new Secret("XYZ)
                    },

                    AllowedCorsOrigins = new string[]
                    {
                        "http://localhost:4200",
                    },
                    RedirectUris =
                    {
                        "http://localhost:4200/login/callback",
                        "http://localhost:4200/login/silentLogin",
                        "http://localhost:4200/logout/callback",

                    },
                    PostLogoutRedirectUris =
                    {
                        "http://localhost:4200/logout/callback",                         
                    },

                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        "testclientapi",
                        "testclientapi.read",
                        "testclientapi.write"
                    }
                }
            };

Update 3


getUser() : Observable<User> {
    return Observable.fromPromise(this.userManager.getUser())
  }
HansMusterWhatElse
  • 671
  • 1
  • 13
  • 34
  • 1
    Does your login-callback component properly call the `signinRedirectCallback()` method? Do you have a valid session stored by oidc-client in your browsers session storage? There should be a key like `oidc.user:https://yoururl.com` – mode777 Apr 07 '18 at 19:04
  • The only thing I call during login is `signinRedirect()` as part of the initial login process. The access token gets stored without any troubles and I am able to call my REST API service. I am just curious why the `/authorize` endpoints gets called for each subsequent request, even though I have a perfectly valid `access_token`. – HansMusterWhatElse Apr 08 '18 at 13:36
  • If you dont call `signinRedirectCallback`, how do you let oidc-client know that it should parse the authentication response from the url? – mode777 Apr 08 '18 at 14:57
  • This is just a hook but in my case I don't see a reason why I would need that. All I want to do, is to call my REST service without triggering an `/authorize` request to my identity server. – HansMusterWhatElse Apr 08 '18 at 15:24
  • For example, have a look at this - they don't utilize the `signinRedirectCallback()` event at all. http://docs.identityserver.io/en/release/quickstarts/7_javascript_client.html – HansMusterWhatElse Apr 08 '18 at 15:25
  • They do call it! Look at the section callback.html. – mode777 Apr 08 '18 at 16:14
  • 1
    Ok this certanly is strange. Apparently your interceptor somehow triggers the login every time Can you post your usermanager config (can be anonymized - i dont care for scopes and urls) and maybe your getUser implementation (it's apparently not just the usermanager which acts here) – mode777 Apr 08 '18 at 18:05
  • sorry, I mixed it up - of course I do call it. Login works just fine and the callback is done. Everything works as it should - I only have the problem that everytime I call the REST api, a request to `/authorize` is sent (have a look at the updated question) – HansMusterWhatElse Apr 08 '18 at 18:06
  • I've added the `UserManagerSettings` and the `Client` configurations to my latest update. – HansMusterWhatElse Apr 08 '18 at 18:27
  • 1
    Still nothing out of the ordinary. You could try turning off silentRenew and loadUserInfo for testing puproses. What does your oidcService.getUser() method do? – mode777 Apr 08 '18 at 18:31
  • At the moment nothing which would explain it (see update). I will try to to the API call from an other route - maybe there are some issues because I do the request from the `/login` route ... apart from that I run out of ideas. Initially I was also thinking maybe its because of the `access_token` which is set to `AccessTokenType.Reference`.. `silentRenew` and `loadUserInfo` also didn't do the trick. – HansMusterWhatElse Apr 08 '18 at 18:56
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/168507/discussion-between-mode777-and-hansmusterwhatelse). – mode777 Apr 08 '18 at 19:05

1 Answers1

0

I found a temporary workaround for the issue.

It works like magic, once I didn't trigger the REST API request from my /login route but instead from an other location e.g /admin.

Which ends up not sending any requests to the /authorize endpoint.

I will update this answer once I figured out why exactly this is happening.

REST API Request

Update 1

I've run now into simular issues when doing /logout requests - also had to moved it to a complete other route ...

HansMusterWhatElse
  • 671
  • 1
  • 13
  • 34