Welcome 1 8 B I - 11 3

Data Source / oAuth On the Wire Explaining Kerberos Constrained Delegation with Protocol Transition and Oauth for Data Source Single Sign On

John Kew Speaker Name (if needed) Manager / Connectivity Job Title Tableau Company / Org Name

Explaining Kerberos Constrained Delegation with Protocol Transition And oAuth for Data Source Single Sign On Everyone dreams of SSO via anything but Kerberos

Agenda

Server settings

SQL Server impersonation

User filters and data source filters

Run as user oAuth connections

Enable Kerberos delegation User Filters and Data Source Filters Run as User Oauth (and SAML) Why Kerberos? Two-Factor Auth Trust Constrained Delegation Introducing Bagel DB Bageld—Bagel Database of the Future

/* Bageld - A system for the organization, storage, and retrieval of Bagel information

John V. Kew Assignment 2 CPEx317 w/ Dr. Nico Winter, 2002

This program sets up a decision tree for the organization of bagel information. The program will use a database file in the local directory called "bagels.db" - If this file does not exist, it will create it so that bagel information can be added.

Files: bageld.c bageld.h string.c string.h

Compilation: Use cmake

Usage: ./bageld [bagel database] [optional: kerberos keytab]

Without a database, the program will first ask you for a bagel type. Then begin filling the database with Caleb bagels, Monkey bagels, and Toast bagels.

All answers are of "yes", "no", [Bagel Name], or a question about a bagel.

*/ Bageld—Bagel Database of the Future

Bagels + Kerberos = Enterprise Single Hop Kerberos with Bagel DB Casting Call

Narrator: John Kew Alice the Bagel Database: Jason Burns Bob the Server: Eve the Bagel Database Client: Single Hop Kerberos: The Setup

Narrator: A bagel shop. Alice the Bagel Database is happily responding to requests from customers about all the different types of bagels. But Alice doesn’t just trust anyone… Microsoft Bob ( to Alice): You have your service key right? Without it I can’t vouch for anyone wanting to access your bagel database. Alice: Yeah; totally, my Domain Administrator set me up for Kerberos . I’ll trust the people you trust. (Eve walks into the bagel shop) Review: Who Knows What?

Client (Eve) knows her (Often in keytab) Database Service (Alice) knows her password (Often in keytab) Active Directory / KDC knows everything (Often in LDAP) Authentication Service: Getting a (TGT)

Eve: Hey Bob; you know me right? Here’s my username Authentication Service: Getting a Ticket Granting Ticket (TGT)

Microsoft Bob: Yeah; the username is legit; here’s a secret message containing a special decoder ring that only you can use. We will use that as our shared decoder ring for future messages.

Keep that around, at least for 24 hours. That little key is as good as my word; but if you are who you say you are only you should be able to read this. Authentication Service: Getting a Ticket Granting Ticket (TGT) Authentication Service Login (Client Side)

jaas.conf direct.SingleHopBageldClient { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true };

Login.scala ////////////////////////////////////////////////////////////////////////////////// // Authenticate against the KDC using JAAS. def login(username: String, password: String) = { val loginCtx: LoginContext = new LoginContext(configName, new LoginCallbackHandler(username, password)) loginCtx.login() this.subject = loginCtx.getSubject() } Authentication Service Login (Client Side) Requesting a Service Ticket: Getting a Service Ticket

Eve: Thanks Bob; you know I was thinking of starting a transaction with Alice the Bagel Database; you think you could give me a service ticket which I can use to start a transaction? Here is that request encrypted with our cool little decoder ring. Requesting a Service Ticket: Getting a Service Ticket

Microsoft Bob: Sure thing; but this ticket is encrypted with Alice’s secret decoder ring. She’s the only one who can read it. Now leave me alone, it’s patch Tuesday and I need some TLC. Requesting a Service Ticket: Getting a Service Ticket Requesting a Service Ticket (Client Side)

KerberosClient.scala //////////////////////////////////////////////////////////////////////////////////////////////// // Configure our request for the service TGT println("initializing security context " + subject + " for service " + servicePrincipalName) val gssServerName: GSSName = manager.createName(servicePrincipalName, KRB5_PRINCIPAL_NAME_OID) val context:GSSContext = manager.createContext(gssServerName, KRB5_NAME_OID, null, GSSContext.DEFAULT_LIFETIME)

val token: Array[Byte] = new Array[Byte](0) // This is a one pass context initialisation. context.requestMutualAuth(false) context.requestCredDeleg(true) context.requestAnonymity(false)

//////////////////////////////////////////////////////////////////////////////////////////////// // Initialize the security context; this is the part that actually // gets the service session setup from the TGS val ticket = context.initSecContext(token, 0, token.length) Wireshark: Authenticating to the Database

Eve (to Alice): Hello Bagel Database. Alice: I don’t talk to anyone about bagels unless they have a kerberos ticket. Wireshark: Authenticating to the Database

Eve (to Alice): Here’s my kerberos ticket that I got from our friend, Bob. I encoded it in Base64; because I know that’s how you like it. Wireshark: Authenticating to the Database

Alice (inspecting and decoding the service ticket): Good news; you are not an intruder! Wireshark: Authenticating to the Database Accepting a Service Ticket (Database Side)

bageld.c // Convert from base64 to bytes size_t ticketLength; unsigned char *ticket = base64_decode(input, inputLength, &ticketLength); printf("KERBEROS: B64Decoded %u [%s]\n", (unsigned int) ticketLength, ticket); gss_buffer_desc gbuf; gbuf.length = ticketLength; gbuf.value = ticket; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; maj_stat = gss_accept_sec_context(&min_stat, &ctx, GSS_C_NO_CREDENTIAL, &gbuf,GSS_C_NO_CHANNEL_BINDINGS,&name, NULL, &outbuf, &gflags, NULL, NULL); free(ticket); switch (maj_stat) { case GSS_S_COMPLETE: authorized = 1; gss_buffer_desc dsp_name; dsp_name.length = 0; dsp_name.value = NULL; gss_display_name( &min_stat, name, &dsp_name, GSS_C_NO_OID ); printf("KERBEROS: accepting GSS security context for: %s\n", (char *)(dsp_name.value)); break; Review: Tickets and Keys Exchanged

Session key: Used to securely exchange messages between a client and active directory Ticket granting ticket (TGT): Contains the session key to the client from active ticket (TGS): Contains the session key for communication between the client and a service (database). This can only be decrypted by the service Constrained Delegation with Protocol Transition Constrained Delegation with Protocol Transition

Eve: So here’s the problem Bob. I can talk to Alice no problem, but my friend Fred is allergic to garlic and cannot set foot inside that bagel shop. Is there a way for me to ask Alice some questions but make her think she is talking to Fred?

Bob: Sure. This is called Kerberos Constrained Delegation. You probably also want protocol transition because Fred cannot just forward his credentials into the Bagel shop.

You need to file a service ticket with my domain administrator to set this up. Constrained Delegation with Protocol Transition

Constrained Delegation: “Trust this user for delegation to specified services only”

Protocol Transition: “Use any " Service for User to Self: S4U2Self

Eve: Bob? Can I get a service ticket for myself for Fred? I need to be able to make requests for other services, as if I were Fred. Service for User to Self: S4U2Self

Bob: Ahh this is called an Service for User to Self (S4U2Self) call. Yup. Here you go. Service for User to Proxy: S4U2Proxy

Eve: Thanks. Ok. Now that I can make requests using this service ticket, can I have a service ticket for Alice on behalf of Fred? Service for User to Proxy: S4U2Proxy

Bob: Sure. This is an Service for User to Proxy (S4U2Proxy) call. Yup yup yup. Here you go… Connecting to the Database Normally

Eve: Cool. Now I can talk to Alice normally, and Alice will think I’m Fred. Impersonation (Client Side)

KerberosClient.scala

// Impersonation val gssImpersonateName: GSSName = manager.createName(impersonateName, GSSName.NT_USER_NAME, KRB5_NAME_OID) val self:ExtendedGSSCredential = manager.createCredential(null,

GSSCredential.DEFAULT_LIFETIME, KRB5_NAME_OID,

GSSCredential.INITIATE_ONLY).asInstanceOf[ExtendedGSSCredential] println("######### IMPERSONATING: " + gssImpersonateName) self.impersonate(gssImpersonateName).asInstanceOf[ExtendedGSSCredential] Review: Constrained Delegation w/ Protocol Transition Constrained Delegation: Ability to delegate communication to a service to an intermediate entity (Eve, or Tableau Server) Protocol Transition: Ability to initiate impersonation of a user using a Service For User To Self (S4U2Self) call and an Service For User to Proxy (S4U2Proxy) call without the original user’s password being used to retrieve a Ticket Granting Ticket Service Ticket (TGS): Contains the session key for communication between the Client and a Service (Database). This can only be decrypted by the Service Data Source oAuth Tableau Data Source oAuth Implementations

Legacy oAuth WDC oAuth GALOP oAuth Next* oAuth oAuth Limitations

Designed for Web Applications Requires an Accessible Callback Intermediary Tableau Data Source oAuth Implementations 18BI-113

Thank you!

Contact or CTA info goes here RELATED SESSIONS

Connecting to Datasources for Tableau Server on Linux Thursday, October 12 | 12:00pm–1:00pm | South—L3—Palm A

Safeguard Your Data: Row Level Security Thursday, October 12 | 10:30am–11:30am | South—L2—Mandalay Bay G Help us plan the future https://www.surveymonkey.com/r/tableaudatasurvey Please complete the session survey from the Session Details screen in your TC18 app