If impersonation succeeds, it means that the client has agreed to let the server be the client to some degree. The varying degrees of impersonation are called impersonation levels, and they indicate how much authority is given to the server when it is impersonating the client.
Currently, there are four impersonation levels: anonymous, identify, impersonate, and delegate. The following list briefly describes each impersonation level:
- anonymous (RPC_C_IMP_LEVEL_ANONYMOUS)
The client is anonymous to the server. The server process can impersonate the client, but the impersonation token does not contain any information about the client. This level is only supported over the local interprocess communication transport. All other transports silently promote this level to identify.
- identify (RPC_C_IMP_LEVEL_IDENTIFY)
The system default level. The server can obtain the client's identity, and the server can impersonate the client to do ACL checks.
- impersonate (RPC_C_IMP_LEVEL_IMPERSONATE)
The server can impersonate the client's security context while acting on behalf of the client. The server can access local resources as the client. If the server is local, it can access network resources as the client. If the server is remote, it can access only resources that are on the same computer as the server.
- delegate (RPC_C_IMP_LEVEL_DELEGATE)
The most powerful impersonation level. When this level is selected, the server (whether local or remote) can impersonate the client's security context while acting on behalf of the client. During impersonation, the client's credentials (both local and network) can be passed to any number of computers.
For impersonation to work at the delegate level, the following requirements must be met:
- The client must set the impersonation level to RPC_C_IMP_LEVEL_DELEGATE.
- The client account must not be marked "Account is sensitive and cannot be delegated" in the Active Directory Service.
- The server account must be marked with the "Trusted for delegation" attribute in the Active Directory Service.
- The computers hosting the client, the server, and any "downstream" servers must all be running in a domain.
By choosing the impersonation level, the client tells the server how far it can go in impersonating the client. The client sets the impersonation level on the proxy it uses to communicate with the server.
There are two ways to set the impersonation level:
- The client can set it processwide, through a call to CoInitializeSecurity.
- A client can set proxy-level security on an interface of a remote object through a call to IClientSecurity::SetBlanket (or the helper function CoSetProxyBlanket).
Different authentication services support delegate-level impersonation to different extents. For instance, NTLMSSP supports cross-thread and cross-process delegate-level impersonation, but not cross-computer. On the other hand, the Kerberos protocol supports delegate-level impersonation across computer boundaries, while Schannel does not support any impersonation at the delegate level. If you have a proxy at impersonate level and you want to set the impersonation level to delegate, you should call SetBlanket using the default constants for every parameter except the impersonation level. COM will choose NTLM locally and the Kerberos protocol remotely (when the Kerberos protocol will work).