Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if Windows Authentication is available with JavaScript

Is there a way to check whether Windows Authentication (Negotiate, Kerberos, NTLM...) is available in the browser (with JavaScript or other methods) without browser prompting for username and password if it is not?

Background

We are developing Angular2 SPA corporate application and want to have SSO with Windows Authentication if it is available (user is accessing the application from Domain joined computer) and gracefully fail over to form based authentication if it is not available (accessing from the Internet or non domain joined computer).

Setup

Have a resource on server side (namely a REST method) which is protected by Windows Authentication. When you call this REST method with JavaScript, either of two things will happen:

  1. If Windows Authentication is available, method will be invoked and you will get a 200 OK response
  2. If Windows Authentication is not available, 401 Unathorized will be returned with WWW-Authenticate header set to Negotiate which will result in browser (at least IE, not tested in others but need to be able to detect this regardless of the browser used) displaying Login prompt

Problem

Displaying of Login prompt is undesired, we want to gracefully fall back to form based login.

Some solutions suggest to remove WWW-Authenticate header from response but this will prevent Windows Authentication to work since this step is part of broser-server negotiating an authentication protocol. If removed, browser will never send NTLM or Kerberos token.

We control both the front end and the backend so can modify either one to make it work. Also, there is no CORS, everything is server from a single domain.

Any method that will detect whether Windows Authentication is available or not from the client is good enough for us. What I have found so far is this but it is only for IE and requires ActiveX to be enabled. This question is somewhat related but it too doesn't have a solution and is quite old.

like image 339
Marko Vodopija Avatar asked Nov 07 '22 23:11

Marko Vodopija


1 Answers

We are using an XmlHttpRequest within an Web Worker. This way it is possible to perform Kerberos authentication without triggering the login window if it fails.

Web Workers are supported by IE11, so you should be good to use it.

This involves proving an single API end point where you can try to authenticate via Kerberos, e.g. 'yourhost.tld/krb5LoginUrl'

Your Webworker (provide as e.g. task.js):

self.addEventListener('message', function(e) {

  var oReq = new XMLHttpRequest();
  oReq.addEventListener("load", reqListener);
  oReq.open("GET",  e.data);
  oReq.send(null);

  function reqListener () {
    self.postMessage(this.status);
  }, false);

Register the worker in your main application code: const worker = new Worker('task.js');

worker.postMessage(/krb5LoginUrl); // Sends the url to our worker and triggers xmlHttpRequest.

worker.addEventListener('message', function (e) {
  if (e.data == 200) {
    console.log("Krb5 login successful");
  } else {
    console.log("Krb5 login failed");
  }
 }, false);
}
like image 115
Tadeus Senf Avatar answered Nov 14 '22 21:11

Tadeus Senf