#java #active-directory #kerberos #spnego #gssapi
#java #active-directory #kerberos #spnego #gssapi
Вопрос:
итак, это снова я с некоторыми проблемами AD и Kerberos.
Хорошо, круто, я получаю токен kerberos из заголовка WWW-Authenticate. Теперь я хочу проверить этот токен на соответствие AD, но я не знаю как.
Я нашел кое-что из GSSAPI, но не увидел функции или метода, которые могли бы использовать byte [] в качестве токена Kerberos или любым другим способом.
Я запускаю веб-приложение Java EE.
Что я могу сделать с этим токеном, чтобы получить пользователя и особенно «этот токен и пользователь являются законными» из AD?
Редактировать:
Итак, как сказано в комментариях, я действительно близок к тому, чтобы выполнить единый вход. Итак, я расскажу вам, ребята, о том, что у меня есть.
У меня есть сервер с именем ping01 и мой локальный компьютер. У меня есть приложение, запущенное на Tomcat от имени пользователя mgmt. Итак, я сделал все это:
Создал SPN HTTP/ping01.cool.domain@COOL.DOMAIN у пользователя mgmt.
krb5.conf:
[libdefaults]
default_tkt_enctypes = aes256-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
default_tgs_enctypes = aes256-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
permitted_enctypes = aes256-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
default_realm = COOL.DOMAIN
kdc_timesync = 1
ccache_type = 5
forwardable = true
proxiable = true
[realms]
COOL.DOMAIN = {
kdc = kdc.cool.domain
admin_server = COOL.DOMAIN
default_domain = COOL.DOMAIN
}
[domain_realm]
cool.domain = COOL.DOMAIN
ping01 = COOL.DOMAIN
[login]
krb4_convert = true
krb4_get_tickets = false
Также у меня есть этот код:
/**
* Gets the jaas krb 5 ticket cfg.
*
* @param principal the principal
* @param realm the realm
* @param keyTab the key tab
* @return the jaas krb 5 ticket cfg
*/
private static Configuration getJaasKrb5TicketCfg( final String principal, final String realm, final File keyTab )
{
return new Configuration()
{
@Override
public AppConfigurationEntry[] getAppConfigurationEntry( String name )
{
Map<String, String> options = new HashMap<>();
options.put( "principal", principal );
options.put( "realm", realm );
options.put( "doNotPrompt", "true" );
options.put( "useKeyTab", "true" );
options.put( "keyTab", keyTab.getAbsolutePath() );
options.put( "storeKey", "true" );
options.put( "isInitiator", "false" );
return new AppConfigurationEntry[] {
new AppConfigurationEntry( "com.sun.security.auth.module.Krb5LoginModule", LoginModuleControlFlag.REQUIRED, options ) };
}
};
}
/** {@inheritDoc} */
@Override
public boolean isTicketValid( String spn, byte[] ticket )
{
LoginContext ctx = null;
try
{
/** define the principal who will validate the ticket */
Principal principal = new KerberosPrincipal( spn, KerberosPrincipal.KRB_NT_SRV_INST );
Set<Principal> principals = new HashSet<>();
principals.add( principal );
/** define the subject to execute our secure action as */
Subject subject = new Subject( false, principals, new HashSet<>(), new HashSet<>() );
/** login the subject */
/**
* TODO: Find the correct way to use the commented out version!
*/
// ctx = new LoginContext( "http_ping01_domain", subject );
ctx = new LoginContext( "doesn't matter", subject, null,
getJaasKrb5TicketCfg( "HTTP/ping01.cool.domain@COOL.DOMAIN", "COOL.DOMAIN",
new File( "http_ping01_test.ktab" ) ) );
ctx.login();
/** create a validator for the ticket and execute it */
SingleSignOnImpl validateAction = new SingleSignOnImpl( ticket, spn, log );
String username = Subject.doAs( subject, validateAction );
log.info( "Validated service ticket for user " username " to access service " spn );
return true;
}
catch ( PrivilegedActionException e )
{
/**
* Error reasons for this Exception: - Incorrect Kerberos Mechanism - Incorrect Token received
* - Incorrect keytab
*/
log.error( "Invalid ticket for " spn ": " e );
}
catch ( LoginException e )
{
/**
* Error reasons for this Exception: - False krb5.conf (can't reach KDC) - incorrect SPN -
* False login.conf
*/
log.error( "Error creating validation LoginContext for " spn ": " e );
}
finally
{
try
{
if ( ctx != null )
{
ctx.logout();
}
}
catch ( LoginException e )
{
log.error( "" e );
}
}
return false;
}
In addition to this I have the privilegedAction in a seperate class:
public class SingleSignOnImpl implements PrivilegedExceptionAction<String>
{
/** The ticket from the client. */
private final byte[] ticket;
/** The Service principal name (SPN). */
private final String spn;
/** The log. */
private Log log;
/**
* Inits the.
*
* @param log the log
*/
@Inject
public void init( Log log )
{
this.log = log;
}
/**
* Instantiates a new single sign on impl.
*
* @param ticket the ticket
* @param spn the spn
*/
public SingleSignOnImpl( byte[] ticket, String spn, Log log )
{
this.ticket = ticket;
this.spn = spn;
this.log = log;
}
/** {@inheritDoc} */
@Override
public String run() throws Exception
{
/**
* Kerberos V5 Mechanism or SPNEGO required. the Legacy mechanism is NOT supported. SPNEGO
* (1.3.6.1.5.5.2); Kerberos V5 (1.2.840.113554.1.2.2)
*/
final Oid spnegoOid = new Oid( "1.3.6.1.5.5.2" );
GSSManager gssmgr = GSSManager.getInstance();
/** tell the GSSManager the Kerberos name of the service */
GSSName serviceName = gssmgr.createName( this.spn, GSSName.NT_USER_NAME );
/**
* get the service's credentials. note that this run() method was called by Subject.doAs(), so
* the service's credentials are already available in the Subject
*/
GSSCredential serviceCredentials = gssmgr.createCredential( serviceName, GSSCredential.INDEFINITE_LIFETIME, spnegoOid,
GSSCredential.ACCEPT_ONLY );
/** create a security context for decrypting the service ticket */
GSSContext gssContext = gssmgr.createContext( serviceCredentials );
/** decrypt the service ticket */
log.info( "Entering accpetSecContext..." );
gssContext.acceptSecContext( this.ticket, 0, this.ticket.length );
/**
* get the client name from the decrypted service ticket note that Active Directory created the
* service ticket, so we can trust it
*/
String clientName = gssContext.getSrcName().toString();
log.info( "request from Client {0}", clientName );
/** clean up the context. This is very important */
gssContext.dispose();
return clientName;
}
}
My log spits out this:
AUTHTOKEN: YIIG2gYGKw......
2016-11-08 14:52:34,269 INFO Entering accpetSecContext...
2016-11-08 14:52:34,269 ERROR Invalid ticket for HTTP/ping01.cool.domain@COOL.DOMAIN: java.security.PrivilegedActionException: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
2016-11-08 14:52:34,269 INFO VALID: false
But the good news is that I get a Kerberos token. he enters the Context and can decrypt it. When using klist in cmd I even see a cached ticket for my service. as shown here: directUpload
Active Directory and KDC runs smoothly and no error or warning is shown when I request the ticket to access the service.
The byte[] with the token is taken from the httprequest from the header and decoded from string to byte[] with Base64.getMimeDecoder.decode();
does anybody see my mistake? After rebooting and purging the ticket cache I still get the message.
EDIT 2:
I digged around more and tried around with ktab and kinit. When trying to get a ticket for the SPN with kinit I run into this:
kinit -J-Dsun.security.krb5.debug=true -k -t http_ping01.ktab HTTP/ping01.cool.domain@COOL.DOMAIN
>>>KinitOptions cache name is C:UsersNico.DOMAINXXXX_Nico
Principal is HTTP/ping01.cool.domain@COOL.DOMAIN
>>> Kinit using keytab
>>> Kinit keytab file name: http_ping01.ktab
Java config name: null
LSA: Found Ticket
LSA: Made NewWeakGlobalRef
LSA: Found PrincipalName
LSA: Made NewWeakGlobalRef
LSA: Found DerValue
LSA: Made NewWeakGlobalRef
LSA: Found EncryptionKey
LSA: Made NewWeakGlobalRef
LSA: Found TicketFlags
LSA: Made NewWeakGlobalRef
LSA: Found KerberosTime
LSA: Made NewWeakGlobalRef
LSA: Found String
LSA: Made NewWeakGlobalRef
LSA: Found DerValue constructor
LSA: Found Ticket constructor
LSA: Found PrincipalName constructor
LSA: Found EncryptionKey constructor
LSA: Found TicketFlags constructor
LSA: Found KerberosTime constructor
LSA: Finished OnLoad processing
Native config name: C:Windowskrb5.ini
Loaded from native config
>>> Kinit realm name is COOL.DOMAIN
>>> Creating KrbAsReq
>>> KrbKdcReq local addresses for my_computer are:
[My addresses]
>>> KdcAccessibility: reset
>>> KeyTabInputStream, readName(): COOL.DOMAIN
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): ping01.cool.domain
>>> KeyTab: load() entry length: 98; type: 18
>>> KeyTabInputStream, readName(): COOL.DOMAIN
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): ping01.cool.domain
>>> KeyTab: load() entry length: 82; type: 17
>>> KeyTabInputStream, readName(): COOL.DOMAIN
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): ping01.cool.domain
>>> KeyTab: load() entry length: 82; type: 23
>>> KeyTabInputStream, readName(): COOL.DOMAIN
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): ping01.cool.domain
>>> KeyTab: load() entry length: 90; type: 16
>>> KeyTabInputStream, readName(): COOL.DOMAIN
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): ping01
>>> KeyTab: load() entry length: 80; type: 18
>>> KeyTabInputStream, readName(): COOL.DOMAIN
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): ping01
>>> KeyTab: load() entry length: 64; type: 17
>>> KeyTabInputStream, readName(): COOL.DOMAIN
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): ping01
>>> KeyTab: load() entry length: 64; type: 23
>>> KeyTabInputStream, readName(): COOL.DOMAIN
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): ping01
>>> KeyTab: load() entry length: 72; type: 16
Looking for keys for: HTTP/ping01.cool.domain@COOL.DOMAIN
Added key: 16version: 2
Added key: 23version: 2
Added key: 17version: 2
Added key: 18version: 2
default etypes for default_tkt_enctypes: 18 17 23 16.
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=KDC.cool.domain UDP:88, timeout=30000, number of retries =3, #bytes=270
>>> KDCCommunication: kdc=KDC.cool.domain UDP:88, timeout=30000,Attempt =1, #bytes=270
>>> KrbKdcReq send: #bytes read=106
>>> KdcAccessibility: remove KDC.cool.domain
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
sTime is Wed Nov 09 10:54:46 CET 2016 1478685286000
suSec is 578393
error code is 6
error Message is Client not found in Kerberos database
sname is ActiveDirectory/COOL.DOMAIN@COOL.DOMAIN
msgType is 30
Exception: krb_error 6 Client not found in Kerberos database (6) Client not found in Kerberos database
KrbException: Client not found in Kerberos database (6)
at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:76)
at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:316)
at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:361)
at sun.security.krb5.internal.tools.Kinit.<init>(Kinit.java:219)
at sun.security.krb5.internal.tools.Kinit.main(Kinit.java:113)
Caused by: KrbException: Identifier doesn't match expected value (906)
at sun.security.krb5.internal.KDCRep.init(KDCRep.java:140)
at sun.security.krb5.internal.ASRep.init(ASRep.java:64)
at sun.security.krb5.internal.ASRep.<init>(ASRep.java:59)
at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:60)
... 4 more
итак, я посмотрел на объект ping01 в нашем active directory. Он уже получил кучу атрибутов servicePrincipalName:
Основное имя сервиса: SomeService /PING01.cool.domain
Исходное имя сервиса: SomeService /PING01
Исходное имя сервиса: anotherService / PING01.cool.domain
servicePrincipalName: anotherService/PING01
Исходное имя сервиса: HOST/PING01.cool.domain
Исходное имя сервиса: HOST/ PING01
использование setspn -l mgmt
выводит SPN, который я создал, хотя. Просто не отображается в ldapBrowser вообще.
Я не уверен, есть ли у объекта Ping01 (objectClass = computer) пароль или нет, придется дождаться ответа системного администратора.
РЕДАКТИРОВАТЬ 3: Я понял, что это должна быть какая-то проблема с SPN или, по крайней мере, проблема с AD. Из РЕДАКТИРОВАНИЯ 2: вы можете видеть, что даже собственный инструмент Windows kinit не может выполнить аутентификацию, поскольку kdc отправляет сообщение, что он не знает пользователя. Почему он указывает SPN как user, мне неясно, но включение дополнительных параметров отладки дало мне этот результат:
YIIG2gYGKwYBBQUCoIIGzjCCBsqgMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHgYKKwYBBAGCNwICCqKCBpQEggaQYIIGjAYJKoZIhvcSAQICAQBuggZ7MIIGd6ADAgEFoQMCAQ6iBwMFACAAAACjggUGYYIFAjCCBP6gAwIBBaETGxFGRUxURU5HUk9VUC5MT0NBTKIrMCmgAwIBAqEiMCAbBEhUVFAbGHBpbmcwMS5mZWx0ZW5ncm91cC5sb2NhbKOCBLMwggSvoAMCAR[...]
INFO [stdout] Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is C:pathtohttp_ping01_test.ktab refreshKrb5Config is false principal is HTTP/ping01.cool.domain@COOL.DOMAIN tryFirstPass is false useFirstPass is false storePass is false clearPass is false
INFO [stdout] principal is HTTP/ping01.cool.domain@COOL.DOMAIN
INFO [stdout] Will use keytab
INFO [stdout] Commit Succeeded
INFO [stdout] Found KeyTab C:pathtohttp_ping01_test.ktab for HTTP/ping01.cool.domain@COOL.DOMAIN
INFO Entering accpetSecContext...
INFO [stdout] Entered SpNegoContext.acceptSecContext with state=STATE_NEW
INFO [stdout] SpNegoContext.acceptSecContext: receiving token = a0 82 06 ce 30 82 06 ca a0 30 30 2e 06 09 2a 86 48 82 f7 12 01 02 02 06 09 2a 86 48 86 f7 12 01 02 02 06 0a 2b 06 01 04 01 82 37 02 02 1e 06 0a 2b 06 01 04 01 82 37 02 02 0a a2 82 06 94 04 82 06 90 60 82 06 8c 06 09 2a 86 48 86 f7 12 01 02 02 01 00 6e 82 06 7b 30 82 06 77 a0 03 02 01 05 a1 03 02 01 0e a2 07 03 05 00 20 00 00 00 a3 82 05 06 61 82 05 02 30 82 04 fe a0 03 02 01 05 a1 13 1b 11 46 45 4c 54 45 4e 47 52 4f 55 50 2e 4c 4f 43 41 4c a2 2b 30 29 a0 03 02 01 02 a1 22 30 20 1b 04 48 54 54 50 1b 18 70 69 6e 67 30 31 2e 66 65 6c 74 65 6e 67 72 6f 75 70 2e 6c 6f 63 61 6c a3 82 04 b3 30 82 04 af a0 03 02 01 12 a1 03 02 01 0f a2 82 04 a1 04 82 04 9d e6 c0 24 8d 0d 24 8e e1 4e e8 0d 4e 4d 5b 7e 06 58 d9 f2 04 a6 99 55 e2 61 67 99 60 ec 47 42 7d 60 64 4d bc f7 ef 99 5b f0 3e b8 2f 9a ff 2d 83 19 6d f1 5f ac 44 08 f3 50 d5 c9 53 af 6f d9 d6 81 c1 d7 24 03 6a 9d b4 9d 56 53 93 b3 1d 07 15 77 c5 fb 25 0f bc f8 97 8f 97 0c 26 ae 52 d0 fc f3 72 98 9c 79 4b af e2 88 3b a6 2b 1b 03 b0 93 b6 6a dd b3 c6 f8 c2 01 eb a4 1b 8a 64 74 cb 5b f4 4b 5c d7 02 48 1d 0d 5e 29 3d 2b 82 c5 79 a1 7a e1 4c 92 32 7c 6b f6 56 ff e1 3a 3f b7 ce 0c 92 f8 ae ce 03 f2 f5 18 53 5c 5b 08 07 60 d7 c0 38 7d d0 f5 fa 2b 63 97 61 75 86 b6 95 44 49 76 93 38 88 82 7f 90 07 d7 3d c9 bd c6 c7 b3 af 47 55 cc b0 1a cd 2a e8 4e d0 b9 42 9e 65 3e aa 88 ac b5 25 45 39 20 0f 3c 50 ed 2d 1a f5 24 04 5a 15 99 c9 2e c1 c6 40 4e 26 ea f2 c6 a9 bd 61 24 fc d4 25 6e ed c2 40 3a d6 18 9b 53 ac 4d a1 61 d2 12 aa 99 e1 90 6e 22 c9 14 82 49 78 43 ab 83 a1 60 a3 d0 1d 33 24 11 41 07 4d bb 9c 0e 38 e1 3c 86 6a 62 bc 2f 7c 47 34 b7 42 3e 28 2e 9b 26 66 a1 e8 61 5f 00 61 8a b9 2b 5b 9e b2 aa 1a 4d e7 4e d2 6d 52 e1 25 c4 89 ea 6e 85 1c 1a 56 e0 d9 a2 be 9f 7c ee 89 55 b8 39 cf b9 92 77 33 2d fa 64 29 50 38 2d 6d d7 9d be be 3c e2 04 4c 5c 3e 3b d1 09 39 08 bd 75 5b 9f 6a 89 32 f8 b2 a9 c7 a3 a1 de ca ea fd 62 18 7d df 5e 50 b5 8e 48 71 ec 66 70 ff 0e 1c 40 2a ad 9e f4 c4 15 45 ca 1b 15 b8 0e 30 76 76 9b 81 39 5b 94 c4 0a ec e0 a7 b4 ec 32 9a 4a 9d 74 86 a3 81 5a 91 8c 51 e1 5a f1 b8 44 fa 9d cc 16 34 c5 99 fb 7b 33 bc 06 99 51 9e ec 19 60 88 [...]
INFO [stdout] SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.48018.1.2.2
INFO [stdout] SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.113554.1.2.2
INFO [stdout] SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.30
INFO [stdout] SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.10
INFO [stdout] SpNegoToken NegTokenInit: reading Mech Token
INFO [stdout] SpNegoContext.acceptSecContext: received token of type = SPNEGO NegTokenInit
INFO [stdout] SpNegoContext: negotiated mechanism = 1.2.840.113554.1.2.2
INFO [stdout] SpNegoContext.acceptSecContext: negotiated mech adjusted to 1.2.840.48018.1.2.2
INFO [stdout] Entered Krb5Context.acceptSecContext with state=STATE_NEW
INFO [stdout] Looking for keys for: HTTP/ping01.cool.domain@COOL.DOMAIN
INFO [stdout] Added key: 16version: 2
INFO [stdout] Added key: 23version: 2
INFO [stdout] Added key: 17version: 2
INFO [stdout] Added key: 18version: 2
INFO [stdout] >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
ERROR Invalid ticket for HTTP/ping01.cool.domain@COOL.DOMAIN: java.security.PrivilegedActionException: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
INFO [stdout] [Krb5LoginModule]: Entering logout
INFO [stdout] [Krb5LoginModule]: logged out Subject
Комментарии:
1. Как упоминалось в комментариях к ответу Тодда, когда я пишу ДОМЕН , я имею в виду реальный домен, который отныне будет называться cool.domain просто для примера. Надеюсь, это поможет понять, в чем может заключаться моя проблема. Я застрял на этом уже довольно давно.
Ответ №1:
Фактический процесс проверки токена безопасности, содержащего билет Kerberos, выполняется на вашем сервере приложений — он никогда не связывается с AD. Функции безопасности GSSAPI обрабатывают это — вы не кодируете для этого. Вы можете предоставить токен (выглядит как случайная строка букв), но только keytab может расшифровать его. Когда вы (как сервер приложений) получаете билет Kerberos (токен аутентификации) от пользователя, вы знаете, что пользователь является законным — пользователи не получают билет в первую очередь, если их личность уже не была подтверждена AD — вот как работает Kerberos. Проверьте этот URL для получения дополнительной информации: http://docs.oracle.com/javase/7/docs/technotes/guides/security/jgss/single-signon.html
Некоторые новые наблюдения, которые я сделал на основе вашего отредактированного вопроса:
- SPN неверен. Предоставленный вами формат «SPN HTTP/ping01.domain@DOMAIN «отсутствуют две метки, одна в части хоста в середине и одна в части области в конце. Должно быть похоже «HTTP/ping01.domain.com@DOMAIN.COM «если вы собираетесь использовать его таким образом. При правильно функционирующем DNS на месте и правильно настроенном krb5.conf SPN фактически может быть таким: «HTTP /ping01.domain.com».
Добавьте новый SPN следующим образом:
setspn -S HTTP /ping01.domain.com домен учетная запись
(setspn -S ищет дубликаты перед добавлением, в то время как setspn -A делает это сейчас)
-
В krb5.conf есть ошибки. У вас есть:
default_realm = ДОМЕН
должно быть:
default_realm = DOMAIN.COM
Далее в krb5.conf, в разделах [realms] и {domain_realm], все ссылки на имена также должны быть полными.
-
Это относится и к тем же ссылкам в вашем блоке кода, я заметил, что в именах отсутствуют метки, такие как этот:
getJaasKrb5TicketCfg( «HTTP/ping01.domain@DOMAIN «, «ДОМЕН»,
должно быть:
getJaasKrb5TicketCfg( "HTTP/ping01.domain.com@DOMAIN.COM", "DOMAIN.COM",
Kerberos чрезвычайно зависит от DNS, все ссылки на имена должны быть полностью указаны во всем коде и krb5.conf.
Комментарии:
1. Хорошо, приятно знать, поэтому мне нужно как-то использовать GSSAPI для использования токена. Я знаю, что токен kerberos является законным и означает, что система, связывающаяся со мной, является законной. Я пытаюсь выполнить единый вход, чтобы он просматривал мой веб-сайт, и тогда ему не нужно вводить имя пользователя и пароль. Итак, мне нужно как бы сделать второй шаг после получения токена, который, как я знаю, не подделан, и извлечь оттуда имя пользователя, чтобы затем авторизовать пользователя. Что ж, я рассмотрю GSSAPI более подробно, чем предполагаю. Спасибо
![]()
2. В этом примере есть скриншот, показывающий имя пользователя, извлеченное из билета Kerberos: oracle.com/technetwork/articles/idm /…
3. Я должен поблагодарить вас, мистер. После глубокого изучения kerberos и gss-api я, наконец, так близок к завершению. Итак, я настроил krb5.ini, keytab и конфигурацию, которую может использовать logincontext, и реализовал priviligedAction для приема и извлечения токена. Теперь последняя ошибка, с которой я столкнулся, — это ошибка с контрольной суммой, но я уже вижу, откуда это происходит, и она тоже будет исправлена. Принимается в качестве ответа и 1 за подсказку.
4. @Nico — да, похоже, вы действительно близки к этому. Что касается сообщения «Ошибка с контрольной суммой», я видел это раньше, запустите команду «klist purge», чтобы очистить кеш Kerberos, или просто перезагрузите клиентский компьютер, а затем попробуйте снова получить доступ к ресурсу, защищенному Kerberos, это должно сработать.
5. Я обновил свой вопрос, добавив гораздо больше информации. Может быть, вы сможете помочь мне сейчас с моей проблемой. На самом деле это сложнее, чем предполагалось.
Ответ №2:
Итак, у меня получилось. Проблема заключалась в том, что созданный SPN не был распознан или, по крайней мере, разрешен неправильно. Из-за этого я получил ошибку контрольной суммы при попытке расшифровать ключ.
После некоторой помощи от сообщества technet мы сделали это правильно.
Я создал SPN следующим образом:
setspn -a HTTP/ping01.cool.domain@COOL.DOMAIN mgmt
но это было неверно, и правильная форма настройки SPN является:
setspn -a HTTP/ping01.cool.domain domainmgmt
Это маленькое и простое отличие сделало все волшебное, чтобы мой сервис заработал.
Надеюсь, это когда-нибудь кому-нибудь поможет.
Комментарии:
1. Спасибо, что перезвонил, Нико. Я отметил, что нужно создать SPN без обозначения @KerberosRealm, и я рад, что вы вернулись к этой теме, чтобы проверить это. В будущем предложите также использовать «-s», а не «-a», по причинам, которые я упомянул …
![]()