Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use the keycloak access token in angular

I've integrated the Keycloak adapter in my Spring Boot application, as described in the documentation. The workflow is working. Initially, I was using the session token-store in the properties, but I want to get rid of that and be stateless. So, I changed the option to a cookie token-store.

I can see that my Spring Boot app does send the Keycloak access token in the KEYCLOAK_ADAPTER_STATE cookie (screenshot). As expected, it's flagged as an HTTP cookie.

However, further angular http requests do not send that cookie when I query my back-end, even if I turn on the withCredentials option in the query.

let options : RequestOptions = new RequestOptions();
options.withCredentials = true;
this.http.get('myservice', options)

How can I use that token in stateless http calls ?

Many thanks !

like image 283
Thomas Gilbert Avatar asked Oct 17 '25 07:10

Thomas Gilbert


2 Answers

As explained in the angular-keycloak documentation HttpClient interceptor by default will add the Authorization header in the format of: Authorization: Bearer TOKEN for all the HTTP requests from your application to the server.

You can configure request URLs that you want to exclude from adding the HTTP Authorization header with the keycloak token in the HTTPClient interceptor configuration.

The HttpClient interceptor can be configured in the keycloak initializer function in the app-init.ts (refer the angular-keycloak documentation) as below;

import { KeycloakService } from 'keycloak-angular';

export function initializer(keycloak: KeycloakService): () => Promise<any> {
    return (): Promise<any> => keycloak.init({
        config: {
            url: 'http://localhost:8080/auth',
            realm: 'your-realm',
            clientId: 'client-id'
        },
        initOptions: {
            onLoad: 'login-required',
            checkLoginIframe: false
        },
        enableBearerInterceptor: true,
        bearerPrefix: 'Bearer',
        bearerExcludedUrls: [
            '/assets',
            '/clients/public']
    });
}
like image 92
Dileepa Jayakody Avatar answered Oct 19 '25 22:10

Dileepa Jayakody


Use Interceptors:

HTTP Interception is a major feature of @angular/common/http. With interception, you declare interceptors that inspect and transform HTTP requests from your application to the server. The same interceptors may also inspect and transform the server's responses on their way back to the application. Multiple interceptors form a forward-and-backward chain of request/response handlers

import { AuthService } from '../auth.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private auth: AuthService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    // Get the auth token from the service.
    const authToken = this.auth.getAuthorizationToken();

    // Clone the request and replace the original headers with
    // cloned headers, updated with the authorization.
    const authReq = req.clone({
      headers: req.headers.set('Authorization', authToken)
    });

    // send cloned request with header to the next handler.
    return next.handle(authReq);
  }
}

...

I think you should set options.withCredentials = true; to any requests

import { Injectable } from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse, HttpErrorResponse} from '@angular/common/http';
import {Router} from '@angular/router';

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/do';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private router: Router) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    req = req.clone({
      withCredentials: true
    });

    return next
      .handle(req)
      .do(event => {
        if (event instanceof HttpResponse) {}
      }, (error: any) => {
        if (error instanceof HttpErrorResponse) {
          if (error.status === 401) {
            this.router.navigate(['/login']);
          }
        }
      });
  }
}
like image 28
Yerkon Avatar answered Oct 19 '25 20:10

Yerkon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!