Escrevendo um cliente SSPI autenticado

Todas as sessões de cliente/servidor RPC exigem uma associação entre o cliente e o servidor. Para adicionar segurança a aplicativos cliente/servidor, os programas devem usar uma associação autenticada. Esta seção descreve o processo de criação de uma associação autenticada entre o cliente e o servidor.

Para obter informações relacionadas, consulte Procedimentos usados com a maioria dos pacotes e protocolos de segurança no SDK (Platform Software Development Kit).

Criando identificadores de associação do lado do cliente

Para criar uma sessão autenticada com um programa de servidor, os aplicativos cliente devem fornecer informações de autenticação com seu identificador de associação. Para configurar um identificador de associação autenticado, os clientes invocam a função RpcBindingSetAuthInfo ou RpcBindingSetAuthInfoEx . Essas duas funções são quase idênticas. A única diferença entre eles é que o cliente pode especificar a qualidade do serviço com a função RpcBindingSetAuthInfoEx .

O fragmento de código a seguir mostra a aparência de uma chamada para RpcBindingSetAuthInfo .

// This code fragment assumes that rpcBinding is a valid binding 
// handle between the client and the server. It also assumes that
// pAuthCredentials is a valid pointer to a data structure which
// contains the user's authentication credentials.

dwStatus = DsMakeSpn(
    "ldap",
    "ServerName.domain.com",
    NULL,
    0,
    NULL,
    &pcSpnLength,
    pszSpn);

//...

rpcStatus = RpcBindingSetAuthInfo(
    rpcBinding,                       // Valid binding handle
    pszSpn,                           // Principal name 
    RPC_C_AUTHN_LEVEL_PKT_INTEGRITY,  // Authentication level
    RPC_C_AUTHN_GSS_NEGOTIATE,        // Use Negotiate SSP
    NULL,                             // Authentication credentials <entity type="ndash"/> use current thread credentials
    RPC_C_AUTHZ_NAME);                // Authorization service

Depois que o cliente chama com êxito as funções RpcBindingSetAuthInfo ou RpcBindingSetAuthInfoEx , a biblioteca de tempo de execução RPC autentica automaticamente todas as chamadas RPC na associação. O nível de segurança e autenticação que o cliente seleciona se aplica somente a esse identificador de associação. Os identificadores de contexto derivados do identificador de associação usarão as mesmas informações de segurança, mas as modificações subsequentes no identificador de associação não serão refletidas nos identificadores de contexto. Para obter mais informações, consulte Identificadores de contexto.

O nível de autenticação permanece em vigor até que o cliente escolha outro nível ou até que o processo seja encerrado. A maioria dos aplicativos não exigirá uma alteração no nível de segurança. O cliente pode consultar qualquer identificador de associação para obter suas informações de autorização invocando RpcBindingInqAuthClient e passando-lhe o identificador de associação.

Fornecendo credenciais de cliente para o servidor

Os servidores usam as informações de associação do cliente para impor a segurança. Os clientes sempre passam um identificador de associação como o primeiro parâmetro de uma chamada de procedimento remoto. No entanto, os servidores não podem usar o identificador, a menos que ele seja declarado como o primeiro parâmetro para procedimentos remotos no arquivo IDL ou no arquivo de configuração de aplicativo (ACF) do servidor. Você pode optar por listar o identificador de associação no arquivo IDL, mas isso força todos os clientes a declarar e manipular o identificador de associação em vez de usar a associação automática ou implícita. Para obter mais informações, consulte Os arquivos IDL e ACF.

Outro método é deixar os identificadores de associação fora do arquivo IDL e colocar o atributo explicit_handle no ACF do servidor. Dessa forma, o cliente pode usar o tipo de associação mais adequado para o aplicativo, enquanto o servidor usa o identificador de associação como se fosse declarado explicitamente.

O processo de extração das credenciais do cliente do identificador de associação ocorre da seguinte maneira:

  • Os clientes RPC chamam RpcBindingSetAuthInfo e incluem suas informações de autenticação como parte das informações de associação passadas para o servidor.
  • Normalmente, o servidor chama RpcImpersonateClient para se comportar como se fosse o cliente. Se o identificador de associação não for autenticado, a chamada falhará com RPC_S_NO_CONTEXT_AVAILABLE. Para obter o nome de usuário do cliente, chame RpcBindingInqAuthClient durante a representação ou, no Windows XP ou em versões posteriores do Windows, chame RpcGetAuthorizationContextForClient para obter o contexto de autorização e use as funções Authz para recuperar o nome.
  • O servidor normalmente chamará CreatePrivateObjectSecurity para criar objetos com ACLs. Depois que isso for feito, as verificações de segurança posteriores se tornarão automáticas.