Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

An authentication handler for using GSSAPI with Python Requests. Drop-in replacement for old requests-kerberos.

License

NotificationsYou must be signed in to change notification settings

pythongssapi/requests-gssapi

Repository files navigation

Requests is an HTTP library, written in Python, for human beings. This libraryadds optional GSSAPI authentication support and supports mutualauthentication.

It provides a fully backward-compatible shim for the oldpython-requests-kerberos library: simply replaceimport requests_kerberoswithimport requests_gssapi. A more powerful interface is provided by theHTTPSPNEGOAuth component, but this is of course not guaranteed to becompatible. Documentation below is written toward the new interface.

Basic GET usage:

>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth>>>r=requests.get("http://example.org",auth=HTTPSPNEGOAuth())...

The entirerequests.api should be supported.

Setup

In order to use this library, there must already be a Kerberos Ticket-GrantingTicket (TGT) in a credential cache (ccache). Whether a TGT is available canbe easily determined by running theklist command. If no TGT isavailable, then it first must be obtained (for instance, by running thekinit command, or pointing the $KRB5CCNAME to a credential cache with avalid TGT).

In short, the library will handle the "negotiations" of Kerberosauthentication, but ensuring that a credentials are available and valid is theresponsibility of the user.

Authentication Failures

Client authentication failures will be communicated to the caller by returninga 401 response. A 401 response may also be the result of expired credentials(including the TGT).

Mutual Authentication

Mutual authentication is a poorly-named feature of the GSSAPI which doesn'tprovide any additional security benefit to most possible uses ofrequests_gssapi. Practically speaking, in most mechanism implementations(including krb5), it requires another round-trip between the client and serverduring the authentication handshake. Many clients and servers do not properlyhandle the authentication handshake taking more than one round-trip. If youencounter a MutualAuthenticationError, this is probably why.

So long as you're running over a TLS link whose security guarantees you trust,there's no benefit to mutual authentication. If you don't trust the link atall, mutual authentication won't help (since it's not tamper-proof, and GSSAPIisn't being used post-authentication. There's some middle ground between thetwo where it helps a small amount (e.g., passive adversary overencrypted-but-unverified channel), but for Negotiate (what we're doing here),it's not generally helpful.

For a more technical explanation of what mutual authentication actuallyguarantees, I refer you to rfc2743 (GSSAPIv2), rfc4120 (krb5 in GSSAPI),rfc4178 (SPNEGO), and rfc4559 (HTTP Negotiate).

DISABLED

By default, there's no need to explicitly disable mutual authentication.However, for compatability with older versions of request_gssapi orrequests_kerberos, you can explicitly request it not be attempted:

>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth,DISABLED>>>gssapi_auth=HTTPSPNEGOAuth(mutual_authentication=DISABLED)>>>r=requests.get("https://example.org",auth=gssapi_auth)...

REQUIRED

This was historically the default, but no longer is. If requested,HTTPSPNEGOAuth will require mutual authentication from the server, and ifa server emits a non-error response which cannot be authenticated, arequests_gssapi.errors.MutualAuthenticationError will be raised. (Seeabove for what this means.) If a server emits an error which cannot beauthenticated, it will be returned to the user but with its contents andheaders stripped. If the response content is more important than the need formutual auth on errors, (eg, for certain WinRM calls) the stripping behaviorcan be suppressed by settingsanitize_mutual_error_response=False:

>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth,REQUIRED>>>gssapi_auth=HTTPSPNEGOAuth(mutual_authentication=REQUIRED,sanitize_mutual_error_response=False)>>>r=requests.get("https://windows.example.org/wsman",auth=gssapi_auth)...

OPTIONAL

This will causerequests_gssapi to attempt mutual authentication if theserver advertises that it supports it, and cause a failure if authenticationfails, but not if the server does not support it at all. This is probably notwhat you want: link tampering will either cause hard failures, or silentlycause it to not happen at all. It is retained for compatability.

>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth,OPTIONAL>>>gssapi_auth=HTTPSPNEGOAuth(mutual_authentication=OPTIONAL)>>>r=requests.get("https://example.org",auth=gssapi_auth)...

Opportunistic Authentication

HTTPSPNEGOAuth can be forced to preemptively initiate the GSSAPIexchange and present a token on the initial request (and allsubsequent). By default, authentication only occurs after a401 Unauthorized response containing a Negotiate challengeis received from the origin server. This can cause mutual authenticationfailures for hosts that use a persistent connection (eg, Windows/WinRM), asno GSSAPI challenges are sent after the initial auth handshake. Thisbehavior can be altered by settingopportunistic_auth=True:

>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth>>>gssapi_auth=HTTPSPNEGOAuth(opportunistic_auth=True)>>>r=requests.get("https://windows.example.org/wsman",auth=gssapi_auth)...

Expect-Continue

Sincehttplib does not support theExpect-Continue header, a request with a body will fail with401 Unauthorized and must be repeated with a GSSAPI exchange. This causesseveral issues:

  • Additional overhead for request retransmission
  • Requests with non-repeatable bodies will fail
  • Some servers will already send the approriate error response while yourclient is still streaming the request. Not all reverse proxies can handle thatproperly and will rather fail.

Therefore, in such cases you must enable opportunistic authentication.

Hostname Override

If communicating with a host whose DNS name doesn't match itshostname (eg, behind a content switch or load balancer),the hostname used for the GSSAPI exchange can be overridden bypassing in a custom name (string orgssapi.Name):

>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth>>>gssapi_auth=HTTPSPNEGOAuth(target_name="internalhost.local")>>>r=requests.get("https://externalhost.example.org/",auth=gssapi_auth)...

Explicit Principal

HTTPSPNEGOAuth normally uses the default principal (ie, the user for whomyou last rankinit orkswitch, or an SSO credential ifapplicable). However, an explicit credential can be in instead, if desired.

>>>importgssapi>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth>>>name=gssapi.Name("user@REALM",gssapi.NameType.user)>>>creds=gssapi.Credentials(name=name,usage="initiate")>>>gssapi_auth=HTTPSPNEGOAuth(creds=creds)>>>r=requests.get("http://example.org",auth=gssapi_auth)...

Explicit Mechanism

HTTPSPNEGOAuth normally lets SPNEGO decide which negotiation mechanism to use.However, an explicit mechanism can be used instead if desired. Themechparameter will be passed straight through togssapi without interference.It is expected to be an instance ofgssapi.mechs.Mechanism.

>>>importgssapi>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth>>>try:...krb5=gssapi.mechs.Mechanism.from_sasl_name("GS2-KRB5")...exceptAttributeError:...krb5=gssapi.OID.from_int_seq("1.2.840.113554.1.2.2")>>>gssapi_auth=HTTPSPNEGOAuth(mech=krb5)>>>r=requests.get("http://example.org",auth=gssapi_auth)...

Delegation

requests_gssapi supports credential delegation (GSS_C_DELEG_FLAG).To enable delegation of credentials to a server that requests delegation, passdelegate=True toHTTPSPNEGOAuth:

>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth>>>r=requests.get("http://example.org",auth=HTTPSPNEGOAuth(delegate=True))...

Be careful to only allow delegation to servers you trust as they will be ableto impersonate you using the delegated credentials.

Logging

This library makes extensive use of Python's logging facilities.

Log messages are logged to therequests_gssapi andrequests_gssapi.gssapi named loggers.

If you are having difficulty we suggest you configure logging. Issues with theunderlying GSSAPI libraries will be made apparent. Additionally, copious debuginformation is made available which may assist in troubleshooting if youincrease your log level all the way up to debug.

Channel Bindings

Optional simplified support for channel bindings is available, but limited tothetls-server-end-point bindings type (manual construction of differentchannel bindings can be achieved using the raw API). When requesting this kindof bindings python-cryptography must be available as request-gssapi will tryto import its x509 module to process the peer certificate.

>>>importrequests>>>fromrequests_gssapiimportHTTPSPNEGOAuth>>>gssapi_auth=HTTPSPNEGOAuth(channel_bindings='tls-server-end-point')>>>r=requests.get("https://windows.example.org/wsman",auth=gssapi_auth)...

It should be noted that this will not work for connections that are closed onthe initial authentication failure. If the connection is closed, the peercertificate may be purged from internal data structures and is not availableto extract thetls-server-end-point value required to completeauthentication.

About

An authentication handler for using GSSAPI with Python Requests. Drop-in replacement for old requests-kerberos.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors29


[8]ページ先頭

©2009-2025 Movatter.jp