1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using System.Net;
using System.Runtime;
using System.Security.Authentication.ExtendedProtection;
using System.Security.Principal;
using System.ServiceModel;
using System.ServiceModel.Diagnostics;
using System.Xml;
using SafeCloseHandle = System.IdentityModel.SafeCloseHandle;
using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials;
sealed class SpnegoTokenAuthenticator : SspiNegotiationTokenAuthenticator
{
bool extractGroupsForWindowsAccounts;
NetworkCredential serverCredential;
bool allowUnauthenticatedCallers;
SafeFreeCredentials credentialsHandle;
public SpnegoTokenAuthenticator()
: base()
{
// empty
}
// settings
public bool ExtractGroupsForWindowsAccounts
{
get
{
return this.extractGroupsForWindowsAccounts;
}
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
this.extractGroupsForWindowsAccounts = value;
}
}
public NetworkCredential ServerCredential
{
get
{
return this.serverCredential;
}
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
this.serverCredential = value;
}
}
public bool AllowUnauthenticatedCallers
{
get
{
return this.allowUnauthenticatedCallers;
}
set
{
this.CommunicationObject.ThrowIfDisposedOrImmutable();
this.allowUnauthenticatedCallers = value;
}
}
// overrides
public override XmlDictionaryString NegotiationValueType
{
get
{
return XD.TrustApr2004Dictionary.SpnegoValueTypeUri;
}
}
public override void OnOpening()
{
base.OnOpening();
if (this.credentialsHandle == null)
{
this.credentialsHandle = SecurityUtils.GetCredentialsHandle("Negotiate", this.serverCredential, true);
}
}
public override void OnClose(TimeSpan timeout)
{
base.OnClose(timeout);
FreeCredentialsHandle();
}
public override void OnAbort()
{
base.OnAbort();
FreeCredentialsHandle();
}
void FreeCredentialsHandle()
{
if (this.credentialsHandle != null)
{
this.credentialsHandle.Close();
this.credentialsHandle = null;
}
}
protected override SspiNegotiationTokenAuthenticatorState CreateSspiState(byte[] incomingBlob, string incomingValueTypeUri)
{
ISspiNegotiation windowsNegotiation = new WindowsSspiNegotiation("Negotiate", this.credentialsHandle, DefaultServiceBinding);
return new SspiNegotiationTokenAuthenticatorState(windowsNegotiation);
}
protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateSspiNegotiation(ISspiNegotiation sspiNegotiation)
{
WindowsSspiNegotiation windowsNegotiation = (WindowsSspiNegotiation)sspiNegotiation;
if (windowsNegotiation.IsValidContext == false)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.InvalidSspiNegotiation)));
}
SecurityTraceRecordHelper.TraceServiceSpnego(windowsNegotiation);
if (this.IsClientAnonymous)
{
return EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
}
using (SafeCloseHandle contextToken = windowsNegotiation.GetContextToken())
{
WindowsIdentity windowsIdentity = new WindowsIdentity(contextToken.DangerousGetHandle(), windowsNegotiation.ProtocolName);
SecurityUtils.ValidateAnonymityConstraint(windowsIdentity, this.AllowUnauthenticatedCallers);
List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
WindowsClaimSet wic = new WindowsClaimSet( windowsIdentity, windowsNegotiation.ProtocolName, this.extractGroupsForWindowsAccounts, false );
policies.Add(new System.IdentityModel.Policy.UnconditionalPolicy(wic, TimeoutHelper.Add(DateTime.UtcNow, base.ServiceTokenLifetime)));
return policies.AsReadOnly();
}
}
}
}
|