Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Redirect to login #141

Open
TheSlimvReal opened this issue Nov 13, 2022 · 4 comments
Open

Redirect to login #141

TheSlimvReal opened this issue Nov 13, 2022 · 4 comments
Assignees
Labels
Type: Enhancement New feature or request

Comments

@TheSlimvReal
Copy link

TheSlimvReal commented Nov 13, 2022

The function keycloak.protect() of keycloak-connect automatically redirects to the keycloak login page if a user is unauthenticated.
Is there a way to implement a similar logic with the AuthGuard of this library?

My use case is that I have GET requests to my backend which redirect the user to another website. Now I want this redirect to only happen if the user is authenticated and if, not redirect the user to the keycloak login page. At the moment I don't find any way to intercept the UnauthorizedException thrown by the AuthGuard in order to start the login process.

@TheSlimvReal
Copy link
Author

TheSlimvReal commented Dec 8, 2022

I managed to solve this with an exception filter

@Catch(UnauthorizedException)
export class RedirectUnauthorizedFilter<T> implements ExceptionFilter {
  constructor(@Inject(KEYCLOAK_INSTANCE) private keycloak: Keycloak) {}

  catch(exception: T, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    const redirectUrl = this.getRedirectUrl(request);
    const uuid = uuidv4();
    const loginURL = this.keycloak.loginUrl(uuid, redirectUrl);

    response.redirect(loginURL);
  }

  private getRedirectUrl(request: Request) {
    const hostname = request.hostname;
    const headerHost = request.headers.host.split(':');
    const port = headerHost[1] || '';
    const protocol = request.protocol;
    const hasQuery = ~(request.originalUrl || request.url).indexOf('?');

    return (
      protocol +
      '://' +
      hostname +
      (port === '' ? '' : ':' + port) +
      (request.originalUrl || request.url) +
      (hasQuery ? '&' : '?') +
      'auth_callback=1'
    );
  }
}

Which can be used in a controller like this

@UseGuards(AuthGuard)
@UseFilters(RedirectUnauthorizedFilter)
@Get('userinfo')
userinfo(@Req() req) {
  return req.user
}  

The code has been taken from the keycloak forceLogin function.

So generally it works, I still feel like there is a lot of room for improvement.
Any idea how this could be made simpler or even whether this could be integrated into this library?

@ferrerojosh
Copy link
Owner

Does your app serve content as well? I assume that is the case. If that is the case, I'm trying to wrap my head around how REST only apps redirect users to login, I assumed they only expect 400 errors, or I'll only allow an option to turn it on to make things easier for people with your use-case.

@ferrerojosh ferrerojosh self-assigned this Dec 16, 2022
@ferrerojosh ferrerojosh added the Type: Enhancement New feature or request label Dec 16, 2022
@TheSlimvReal
Copy link
Author

Yes, the app processes a redirect, the redirect however should only be available for logged-in users. Anyway, Keycloak seems to drop support for their node keycloak library next year...

@smolinari
Copy link

smolinari commented Dec 19, 2022

@TheSlimvReal - Can you offer a link for reference on the dropping of support?

Edit - nevermind. I've found the info. Looks like https://github.com/panva/node-openid-client is the recommendation.

Scott

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Type: Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants