kerberos - idiot's guide to browser's interaction with client-side javascript

861 views
Skip to first unread message

Calvin

unread,
May 9, 2023, 1:29:37 PM5/9/23
to Chromium-dev
Hi
got thrown into doing some kerberos auth with client-side vue.js.

I've read the RFC and all the docs i can get my hands on, and i think i totally understand the handshake between a server-side application and the browser. 

What i'm really struggling with is how client-side code interacts with the browser. I dont even know how to successfully google search it. All i can find is really vague stuff like this that says: 

The Access-Control-Allow-Credentials response header tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials) is include

I've looked up all references to spnego/kerberos in the chrome/chromium codebase but cant find anything that talks about the requirements for the browser to hand over kerberos credentials/ticket over to the javascript (so it can place it in the Authorization header)

Thanks

Calvin

PhistucK

unread,
May 9, 2023, 2:24:29 PM5/9/23
to calvin...@gmail.com, Chromium-dev
If I am not mistaken, Keberos is basically using the system-logged-in user to authenticate against web services. This means that client-side JavaScript will not have any access to those (unless the server intentionally leaked something to it). Are you sure this kind of thing (client-side Kerberos) exists? I doubt it...

PhistucK


--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-dev/e91b0544-ffb0-48d7-bf2d-0ea06e9c8d60n%40chromium.org.

PhistucK

unread,
May 9, 2023, 6:06:52 PM5/9/23
to Calvin, Chromium-dev
I believe you have to proxy it via a server, this is an internal flow between the browser and the server and the server and the Kerberos server (the server-to-server is probably with specific protocols that are probably not even HTTP, so JavaScript cannot do it alone). Having it available on the client opens it to risks of leakage, I guess (like non-HTTP-only cookies). I cannot say that I have enough knowledge to tell you for sure,
I think it is a similar limitation to OAuth where you cannot get a refreshable token client-side (or a token without showing the user anything), you have to use a server.

While you are asking this in a Chromium specific group, I think the question is broader than that. Does any browser allow you to do it in client-side JavaScript alone (which is off topic here)?
I believe the answer is no.

PhistucK


On Tue, May 9, 2023 at 9:53 PM Calvin <calvin...@gmail.com> wrote:
Thanks for the reply!!

Keberos is basically using the system-logged-in user to authenticate against web services.

correct - as far as i understand, the browser handles the entire process of: 
  • finding the user's existing kerberos TGT (ticket granting ticket) 
  • use the User's TGT to ask the kerberos servers to give access to a specific SPN resource (i.e some registered resource in Active Directory e.g. a website)
  • receiving the ticket that grants access to that specific SPN resource (website)
the end of the flow though is that the browser should 
  • make that ticket available to be sent to the SPN resource (i.e. our website)
then the SPN resource (website) should:
  • communicate with the kerberos servers to check that the received ticket is a valid ticket.
  • login is allowed
This is what i understand from reading the RFC and from this excellent article showing spnego flow

 This means that client-side JavaScript will not have any access to those 
this bit is what i'm a bit in doubt about. the user's ticket has to be verified by the SPN resource (website) to allow the SSO auth loop to complete.
So if you have a server-side website, then the ticket is simply sent to the server by the browser
But if you have a website using client-side code, then afaik the client-side javascript must be able to grab the ticket from the browser and verify it. 

Lots of websites imply that this is what happens.  

Calvin

unread,
May 9, 2023, 7:09:29 PM5/9/23
to Chromium-dev, PhistucK, Chromium-dev, calvin...@gmail.com
Thanks for the reply!!

Keberos is basically using the system-logged-in user to authenticate against web services.

correct - as far as i understand, the browser handles the entire process of: 
  • finding the user's existing kerberos TGT (ticket granting ticket) 
  • use the User's TGT to ask the kerberos servers to give access to a specific SPN resource (i.e some registered resource in Active Directory e.g. a website)
  • receiving the ticket that grants access to that specific SPN resource (website)
the end of the flow though is that the browser should 
  • make that ticket available to be sent to the SPN resource (i.e. our website)
then the SPN resource (website) should:
  • communicate with the kerberos servers to check that the received ticket is a valid ticket.
  • login is allowed
This is what i understand from reading the RFC and from this excellent article showing spnego flow

 This means that client-side JavaScript will not have any access to those 
this bit is what i'm a bit in doubt about. the user's ticket has to be verified by the SPN resource (website) to allow the SSO auth loop to complete.
So if you have a server-side website, then the ticket is simply sent to the server by the browser
But if you have a website using client-side code, then afaik the client-side javascript must be able to grab the ticket from the browser and verify it. 

Lots of websites imply that this is what happens.  
On Tuesday, May 9, 2023 at 8:24:29 PM UTC+2 PhistucK wrote:

Reilly Grant

unread,
May 10, 2023, 12:56:58 PM5/10/23
to phis...@gmail.com, Calvin, Chromium-dev
Browsers which allow you to authenticate with a server using Kerberos do so using the HTTP Negotiate authentication method. This isn't exposed to JavaScript. It just happens automatically when the browser makes a connection to the server, it requests authentication and the browser responds by authenticating using ambient credentials from the user session. This kind of ambient authentication is a privacy problem and so it is only allowed for sites listed in the AuthServerAllowlist policy.
Reilly Grant | Software Engineer | rei...@chromium.org | Google Chrome


Calvin

unread,
May 12, 2023, 5:58:15 PM5/12/23
to Chromium-dev, Reilly Grant, Calvin, Chromium-dev, phis...@gmail.com
many thanks Reilly and Phistuck!
you were both right (of course!), it was just very difficult for me to filter out all my misunderstandings. 

I finally got it working. 
Quite a simple noob-concept that's actually quite hard to formulate into a question. 

So answer here is just for anyone that comes across this thread looking for the same answers i was.

afaik the vue code i wrote is frontend-only code. it is executed within the browser by the browser's engine (e.g. v8 in chrome). 
in my frontend-only config, there is no nodejs server running any code. 
so the vue code running in the user's browser talks directly to my backend api.  
(since i last looked, now people are doing backend rendering and shifting more work to an actual nodejs-based server, but it appears i have none of that in my code). 

my first misunderstanding was that i thought for the kerberos/spnego handshake, i had to write frontend code to be the middleman between my API server and the browser (like i saw in this thread). 
but what i found out was that if the backend sends a correctly-formed response to the browser, then the browser (not the frontend code!) will automatically reply with the kerberos token!

the second misunderstanding was that i thought:
* that development nodejs server was running some code for me (i.e. that everything was NOT running in the browser)
* that the development nodejs server was the owner of the kerberos SPN
as a result i was sending queries from the browser to the API server with destination IP http://127.0.0.1:7777 

The problem here was that the API server should be the "owner" of the kerberos SPN and so it was essential that requests to the API were done with the URL contained within the SPN..
once i changed the two misunderstandings above then it worked fine. 

many thanks again!




Reply all
Reply to author
Forward
0 new messages