最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

kerberos - Is it possible to get TGT ticket from TGS? - Stack Overflow

programmeradmin3浏览0评论

I have the following architecture:

  1. Browser requests TGT ticket
  2. Browser requests TGS ticket(sending TGT as argument of request)
  3. Browser requests WEB server and sends TGS ticket(in HTTP header )
  4. Web-server wants to request Backend Servcice(This request should be send from behalf of a user which sends request from browser(impersonation))

From codebase standpoint I have the following code: STEP 3

private val authService: AuthenticationService,
private val ticketValidator: SunJaasKerberosTicketValidator,
....
@Throws(AuthenticationException::class)
override fun authenticate(authentication: Authentication): Authentication {
    val token = (authentication as KerberosServiceRequestToken).token
    val ticketValidation = ticketValidator.validateTicket(token)
     ...
    return KerberosServiceRequestToken(
        authenticatedUser, ticketValidation,
        authenticatedUser.authorities, token,
    ).apply {
        details = authentication.getDetails()
    }
}

Speaking about step4 the idea that I need to take TGT ticket from previous step, put it to the GSS API context and pass to the backend service:

val ssoConnectionProperties = GSSAPIBindRequestProperties(null, null as String?)
    .apply {
        realm = ...
        kdcAddress = ...
        ticketCachePath = krbTgtPath
        keyTabPath = ...

        setUseKeyTab(true)
        setRequireCachedCredentials(true)
        setUseTicketCache(true)
        setEnableGSSAPIDebugging(true)
    }

val bindRequest: BindRequest = GSSAPIBindRequest(ssoConnectionProperties)
return LDAPConnection(connectionOptions, ssoKdcAddress, ldapConnectionProperties.port)

The code above is working but I have no idea how to take tgt ticket from previous step ?

I have the following architecture:

  1. Browser requests TGT ticket
  2. Browser requests TGS ticket(sending TGT as argument of request)
  3. Browser requests WEB server and sends TGS ticket(in HTTP header )
  4. Web-server wants to request Backend Servcice(This request should be send from behalf of a user which sends request from browser(impersonation))

From codebase standpoint I have the following code: STEP 3

private val authService: AuthenticationService,
private val ticketValidator: SunJaasKerberosTicketValidator,
....
@Throws(AuthenticationException::class)
override fun authenticate(authentication: Authentication): Authentication {
    val token = (authentication as KerberosServiceRequestToken).token
    val ticketValidation = ticketValidator.validateTicket(token)
     ...
    return KerberosServiceRequestToken(
        authenticatedUser, ticketValidation,
        authenticatedUser.authorities, token,
    ).apply {
        details = authentication.getDetails()
    }
}

Speaking about step4 the idea that I need to take TGT ticket from previous step, put it to the GSS API context and pass to the backend service:

val ssoConnectionProperties = GSSAPIBindRequestProperties(null, null as String?)
    .apply {
        realm = ...
        kdcAddress = ...
        ticketCachePath = krbTgtPath
        keyTabPath = ...

        setUseKeyTab(true)
        setRequireCachedCredentials(true)
        setUseTicketCache(true)
        setEnableGSSAPIDebugging(true)
    }

val bindRequest: BindRequest = GSSAPIBindRequest(ssoConnectionProperties)
return LDAPConnection(connectionOptions, ssoKdcAddress, ldapConnectionProperties.port)

The code above is working but I have no idea how to take tgt ticket from previous step ?

Share Improve this question edited Mar 31 at 22:08 gstackoverflow asked Mar 31 at 21:21 gstackoverflowgstackoverflow 36.6k138 gold badges418 silver badges785 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Your bind request already has service credentials (the keyTabPath). Do you want to bind using the service keytab or do you want to bind using the user's TGT? Choose one or the other.

In normal operation, service tickets do not contain a TGT inside them. (That's kind of the whole point of Kerberos: the reason tickets are used is so that merely authenticating to a service wouldn't give away your entire "keys to the castle" and let that service act as you.)

To get the TGT, you need to explicitly enable the unconstrained delegation feature. It is a bit risky, as your server becomes a good place for stealing everyone's credentials if someone breaks in.

The web app's account (the one holding the "HTTP" SPN) has to be marked as "Trusted for delegation to all services" in AD. Also, delegation may need to be explicitly enabled in clients (browsers); e.g. both Chrome and Firefox have an "AuthNegotiateDelegateWhitelist" policy separate from the usual "allow negotiate auth". Also, it won't work for domain admins, nor users whose machines are configured with Credential Guard.

(Also, the process is a bit slow as it causes the client to request a fresh "delegated TGT" so it should be limited to just a few specific endpoints if possible. I think Windows might cache such TGTs but Linux doesn't.)

Once enabled, the webapp has to request delegation using securityContext.requestCredDeleg(true). (Or something similar; I merely found this in the docs.)

After receiving an authenticated request, ticketValidation.getDelegationCredential() should allow you to get a GSSCredential that represents the user's delegated TGT.

(Alternatively, after validator.holdOnToGSSContext(true) you might be able to call validation.getGssContext().getDelegCred() to get the same thing.)

There are two alternative ways to authenticate as the user:

  • Constrained delegation (primarily found in AD), where your service uses S4U2Self/S4U2Proxy to craft "impersonated" tickets.

  • Protocol-specific impersonation methods, e.g. OpenLDAP (but not AD) has a concept of separate 'authentication' and 'authorization' identities so the LDAP client could bind as one user (authcid) but act as another (authzid).


TGS (ticket-granting service) is not a ticket type; it is the KDC function that issues tickets. Therefore "TGS tickets", as in tickets granted by the TGS, would be better called "service tickets". (Otherwise you would have to call the TGT an "AS ticket"...)

发布评论

评论列表(0)

  1. 暂无评论