How to pass windows authentication(browser) from react application to Spnego Kerberos Spring SSO?
Asked Answered
A

2

2

We have a react application which used get that data from spring boot webservice. Both is deployed in a same server(tomcat). But we only need Kerberos authentication for webservice call from the React application. Anyone can open the React application but when it navigate then it calls to the webservcie to get the data. So if we configure the spring to support spnego kerberos spring sso, is it possible that browser will automatically pass( from React app, as react run on the browser) the logged in Windows credentials to the spring boot web service.

We are calling the service from react app as follows -

export const client = rest
  .wrap(mime, { registry: registry })
  .wrap(errorCode)
  .wrap(defaultRequest, {
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    },
    method: 'GET'
  })



export const fetchPDSIs = (Id) =>
  APIHelpers.client(APIHelpers.buildPDSIReq(Id))
    .then(
      response => (response.entity || []).sort((a, b) => a.portalinstance.localeCompare(b.portalinstance))
      ,
      response => {
        global.msg.error(<div className='smallTextNotification'>`Fetching instances and portal for {Id} error: {response.status.code} -> {response.status.text}</div>)
        return []
      }
    )

export const buildPDSIReq = (Id) => ({path: `${serverAddr}/msd232/pdsiii/${Id}`})
Acanthus answered 13/6, 2019 at 5:1 Comment(1)
Hi @Subhajit Pal, Could you please let me know what solution you have applied for this, since I am having a similar type of issue, your help will be appreciated. Thanks!Typeface
S
1

Yes, it's possible, requirements on the client side:

  1. User logged into domain account on OS.
  2. Proper config in your browser, see Spring documentation

E.g. for Internet Explorer:

E.3 Internet Explorer

Complete following steps to ensure that your Internet Explorer browser is enabled to perform Spnego authentication.

Open Internet Explorer.
Click Tools > Intenet Options > Security tab.
In Local intranet section make sure your server is trusted by i.e. adding it into a list.

Kerberos auth is triggered by HTTP header returned from backend service:

WWW-Authenticate: Negotiate

If your OS and browser are correctly configured this will trigger service ticket generation, which browser will send as Authorization HTTP header value.

EDIT: If your application is split into frontend and backend hosted separately on different hosts, then you have to register SPN (and generate keytab) for the fronted host which users will enter. Example:

  • Backend: api.test.com
  • Frontend: application.test.com

For SSO to work, you have to register SPN: application.test.com, backend host name is irrelevant here. Command:

setspn -A HTTP/[email protected] ad_user_to_registern_spn_for 
Sydneysydnor answered 9/7, 2019 at 11:14 Comment(5)
I am able to call the web service by using the curl command. It is taking the correct logged in windows credentials. But when I am trying to call from the react app by using browser it is giving 500. Also before every GET,POST and DELETE call OPTIONS method get calledAcanthus
I would recommend logging all requests on backend side as precisely as possible, viewing network traffic thru wireshark might also help you. In this case it looks like invalid browser configuration. It is possible, that when browser has incorrect config, browser calls backend service, receives HTTP 401 with header WWW-Authenticate: Negotiate, then browser creates NTLM ticket and sends it as Authorization HTTP header value which will result in ticket validation error and HTTP 500 error seen in browser logs. From FE app request handler it might look like 1 request.Sydneysydnor
I have found some discrepancies . When I do nslookup with my application url (a-test-sam.test.com) then it is showing the below nslookup a-test-sam.test01.test.com Server: test03.test.com Address: 10.***.**.** Name: a27.test01.test.com Address: 10.**.**.** Aliases: a-test-sam.test01.test.com Is possible that as I have used c name that why the url(a-test-sam.test01.test.com) points to a back end server with a different name(a27.test01.test.com). Also we have setup the SPN with the url . setspn -A HTTP/a-test-sam.test01.test.com test01\ap-sdw-sam-tAcanthus
I'm not sure if I understand your comment and all this URLs enough, so I edited my answer to add more generic advice. It looks like you registered SPN for backend host, whereas it should be frontend host, this explains why it works when you call backend directly with curl and does not work when using frontend application.Sydneysydnor
Yes you are right after changing the DNS name and pointed to correct url it resolved.Acanthus
H
2

Using the fetch API, it worked for me by adding credentials: 'include'

fetch(${authBase}/auth, {credentials: 'include'})

I know it isn't what you are using but it may help other readers

Herlindaherm answered 25/3, 2020 at 12:16 Comment(0)
S
1

Yes, it's possible, requirements on the client side:

  1. User logged into domain account on OS.
  2. Proper config in your browser, see Spring documentation

E.g. for Internet Explorer:

E.3 Internet Explorer

Complete following steps to ensure that your Internet Explorer browser is enabled to perform Spnego authentication.

Open Internet Explorer.
Click Tools > Intenet Options > Security tab.
In Local intranet section make sure your server is trusted by i.e. adding it into a list.

Kerberos auth is triggered by HTTP header returned from backend service:

WWW-Authenticate: Negotiate

If your OS and browser are correctly configured this will trigger service ticket generation, which browser will send as Authorization HTTP header value.

EDIT: If your application is split into frontend and backend hosted separately on different hosts, then you have to register SPN (and generate keytab) for the fronted host which users will enter. Example:

  • Backend: api.test.com
  • Frontend: application.test.com

For SSO to work, you have to register SPN: application.test.com, backend host name is irrelevant here. Command:

setspn -A HTTP/[email protected] ad_user_to_registern_spn_for 
Sydneysydnor answered 9/7, 2019 at 11:14 Comment(5)
I am able to call the web service by using the curl command. It is taking the correct logged in windows credentials. But when I am trying to call from the react app by using browser it is giving 500. Also before every GET,POST and DELETE call OPTIONS method get calledAcanthus
I would recommend logging all requests on backend side as precisely as possible, viewing network traffic thru wireshark might also help you. In this case it looks like invalid browser configuration. It is possible, that when browser has incorrect config, browser calls backend service, receives HTTP 401 with header WWW-Authenticate: Negotiate, then browser creates NTLM ticket and sends it as Authorization HTTP header value which will result in ticket validation error and HTTP 500 error seen in browser logs. From FE app request handler it might look like 1 request.Sydneysydnor
I have found some discrepancies . When I do nslookup with my application url (a-test-sam.test.com) then it is showing the below nslookup a-test-sam.test01.test.com Server: test03.test.com Address: 10.***.**.** Name: a27.test01.test.com Address: 10.**.**.** Aliases: a-test-sam.test01.test.com Is possible that as I have used c name that why the url(a-test-sam.test01.test.com) points to a back end server with a different name(a27.test01.test.com). Also we have setup the SPN with the url . setspn -A HTTP/a-test-sam.test01.test.com test01\ap-sdw-sam-tAcanthus
I'm not sure if I understand your comment and all this URLs enough, so I edited my answer to add more generic advice. It looks like you registered SPN for backend host, whereas it should be frontend host, this explains why it works when you call backend directly with curl and does not work when using frontend application.Sydneysydnor
Yes you are right after changing the DNS name and pointed to correct url it resolved.Acanthus

© 2022 - 2024 — McMap. All rights reserved.