使用协议转换 - 防御提示
2009-02-09 13:52:49 来源:WEB开发网Figure3登录服务
[assembly: ApplicationName("PluralsightLogonService")]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(true,
Authentication = AuthenticationOption.Privacy,
ImpersonationLevel = ImpersonationLevelOption.Identify,
AccessChecksLevel = AccessChecksLevelOption.ApplicationComponent)]
public interface ILogonService {
int LogonUserViaProtocolTransition(string upn, int callerPID);
}
[ComponentAccessControl(true)]
[SecureMethod]
public class LogonService : ServicedComponent, ILogonService {
public LogonService() { }
[SecurityRole("ProtocolTransitionUsers")]
[SecurityRole("Marshaler")]
public int LogonUserViaProtocolTransition(
string upn, int callerPID) {
SecurityIdentifier callerSID = null;
CoImpersonateClient();
try {
callerSID = WindowsIdentity.GetCurrent().User;
}
finally {
CoRevertToSelf();
}
using (SafeProcessHandle targetProcess = OpenProcess(
PROCESS_DUP_HANDLE, false, callerPID)) {
if (targetProcess.IsInvalid) {
Marshal.ThrowExceptionForHR(
Marshal.GetLastWin32Error());
}
// this is the line of code that requires high privilege
using (WindowsIdentity identity =
new WindowsIdentity(upn)) {
SafeTokenHandle token = new SafeTokenHandle(
identity.Token, false);
throwIfUserIsAdmin(token);
grantPermission(token, callerSID);
// push the token handle into the caller's process
int targetHandle;
if (!DuplicateHandle(
GetCurrentProcess(), token, // source
targetProcess, out targetHandle, // target
0, false, DUPLICATE_SAME_ACCESS)) {
Marshal.ThrowExceptionForHR(
Marshal.GetLastWin32Error());
}
return targetHandle;
}
}
}
private void grantPermission(SafeTokenHandle token,
SecurityIdentifier callerSID) {
// use our extension to System.Security.AccessControl!
TokenSecurity tokenSecurity = new TokenSecurity(token,
AccessControlSections.Access);
tokenSecurity.AddAccessRule(new TokenAccessRule(callerSID,
TokenRights.All, AccessControlType.Allow));
tokenSecurity.Persist(token, AccessControlSections.Access);
}
//Pinvoke stubs
...
}
您还可能注意到对 CoImpersonateClient 和 CoRevertToSelf 的调用。这些是大多数 DCOM 程序员所熟悉的 Win32 API。它们使我能够发现哪个安全主体正在调用登录服务,我可以将调用方的安全标识符获取到随后用于对令牌授予权限的变量中。
更多精彩
赞助商链接