Python 사용 SSO 용 SPNEGO (Kerberos 토큰 생성/검증)
-
06-09-2019 - |
문제
참여 서버 중 일부가 Windows (IIS) 상자가 될 시나리오에서 간단한 단일 부호를 구현하려고합니다. Spnego가 이것에 대한 합리적인 길인 것 같습니다.
시나리오는 다음과 같습니다.
- 사용자 이름과 비밀번호를 사용하여 사용자가 내 SSO 서비스에 로그인합니다. 나는 약간의 메커니즘을 사용하여 그를 인증합니다.
- 나중에 사용자는 앱 A에 액세스하려고합니다.
- 앱 A에 대한 사용자의 요청은 SSO 서비스에 의해 차단됩니다. SSO 서비스는 SPNEGO를 사용하여 사용자를 앱 A에 로그인합니다.
- SSO 서비스는 웹 페이지에서 앱을 치고 "www-authenticate : 협상"응답을받습니다.
- SSO 서비스는 사용자를 대신하여 "승인 : XXX 협상"응답을 생성하고 APP A에 응답합니다. 사용자는 이제 APP A에 로그인되었습니다.
- SSO 서비스는 App A에 대한 후속 사용자 요청을 가로 채고 App A에 전달하기 전에 권한 부인 헤더를 삽입합니다.
- 앱 A에 대한 사용자의 요청은 SSO 서비스에 의해 차단됩니다. SSO 서비스는 SPNEGO를 사용하여 사용자를 앱 A에 로그인합니다.
그 소리가 맞습니까?
두 가지가 필요합니다 (적어도 지금 생각할 수있는 것) :
- 사용자를 대신하여 "승인 : XXX 협상"토큰을 생성하는 기능, 바람직하게는 Python을 사용합니다.
- Python에서 "승인 : 협상 XXX 협상"헤더를 검증하는 기능 (프로젝트의 후반부)
해결책
이것이 바로 Apple이하는 일입니다 캘린더 서버. 그들은 가지고 있습니다 파이썬 Gssapi 구현하기 위해 프로세스의 Kerberos 부분을위한 라이브러리 SPNEGO.
서버 인증 부분의 경우 Calendarserver/TwistedCaldav/Authkerb.py를 살펴보십시오. Kerberos 모듈 (AC 모듈)에는 유용한 docstrings가 없지만 Pykerberos/pysrc/kerberos.py에는 모든 기능 정의가 있습니다.
SVN 트렁크의 URL은 다음과 같습니다.
http://svn.calendarserver.org/repository/calendarserver/calendarserver/trunk
http://svn.calendarserver.org/repository/calendarserver/pykerberos/trunk
다른 팁
살펴보십시오 http://spnego.sourceforge.net/credential_delegation.html 지도 시간. 당신이하려는 일을하고있는 것 같습니다.
나는 비슷한 무언가 (Linux에서)에 대해 꽤 오랫동안 검색해 왔는데,이 페이지는 여러 번이 페이지로 이어지지 만 답을주지 않았습니다. 그래서 여기에 내 해결책이 있습니다.
웹 서버는 mod_auth_kerb가있는 아파치입니다. 이미 꽤 오랫동안 Active Directory, 단일 사인온 설정으로 실행 중입니다. 내가 이미 할 수 있었던 일 :
- Linux에서 단일 부호 켜기와 함께 Chromium 사용 (KRB5 설정, Kinit user@domain이 작동하는 적절한 KRB5 설정)
- Pywin32 패키지에서 SSPI를 사용하여 Python Connect 및 단일 부호가있는 것과 같은
sspi.ClientAuth("Negotiate", targetspn="http/%s" % host)
다음 코드 스 니펫은 퍼즐 (및 내 필요)을 완성하여 Linux의 Kerberos와 함께 Python Single Sign을 사용하여 (Python-GSSAPI 사용) :
in_token=base64.b64decode(neg_value)
service_name = gssapi.Name("HTTP@%s" % host, gssapi.C_NT_HOSTBASED_SERVICE)
spnegoMechOid = gssapi.oids.OID.mech_from_string("1.3.6.1.5.5.2")
ctx = gssapi.InitContext(service_name,mech_type=spnegoMechOid)
out_token = ctx.step(in_token)
buffer = sspi.AuthenticationBuffer()
outStr = base64.b64encode(out_token)