I did some unit tests and ran into an interesting problem in WCF. I have a service using wsHttpBindingconfigured as such:
<bindings>
<wsHttpBinding>
<binding name="wsHttpUnsecured">
<security mode="None">
<transport clientCredentialType="None" />
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
Service implementation:
public void DoWork()
{
OperationContext o = OperationContext.Current;
if (o == null) return;
if (o.ServiceSecurityContext.AuthorizationContext.Properties.ContainsKey("x"))
throw new ApplicationException();
o.ServiceSecurityContext.AuthorizationContext.Properties.Add("x", "x");
}
All he does is check the context of the operation, and if there is no “X” in the AuthorizationContext, add it. If there was already an “X,” then the exception is the exception. (This is set strictly as a simple test. In normal use, this will happen in the custom AuthorizationManager and Token Authenticator).
Basically, if we call the method more than once within the same operationContext and AuthorizationContext, we will see an exception.
.
[Test]
public void CallTwice()
{
using (var cli1 = new TestBusinessClient())
{
cli1.DoWork();
cli1.Close();
}
using (var cli2 = new TestBusinessClient())
{
cli2.DoWork();
cli2.Close();
}
}
, , :
TestBusinessClient.DoWork().DoWork() "X" AuthorizationContext.Properties.DoWork() "X" AuthorizationContext.Properties.- .
TestBusinessClient.DoWork().DoWork() "X" - .DoWork() .
, ; OperationContext AuthorizationContext , ? , wsHttpBinding , , . , WCF , , , .
- ? AuthorizationContext.Properties reset DoWork() .
1
PerCall PerSession, .
, .
. , :
OperationContext first; // context from first call to DoWork()
OperationContext second; // context from second call to DoWork()
(first == second) = false
(first.ServiceSecurityContext == second.ServiceSecurityContext) = false
(first.ServiceSecurityContext.AuthorizationContext == second.ServiceSecurityContext.AuthorizationContext) = true
, , /, - AuthorizationContext .
2
:
[ServiceContract]
public interface ITestBusiness
{
[OperationContract(Action = "*", ReplyAction = "*")]
string DoWork();
}
public class TestBusiness : ITestBusiness
{
public string DoWork()
{
System.ServiceModel.OperationContext o = System.ServiceModel.OperationContext.Current;
if (o != null)
{
if (o.ServiceSecurityContext.AuthorizationContext.Properties.ContainsKey("x"))
throw new ApplicationException();
else
o.ServiceSecurityContext.AuthorizationContext.Properties.Add("x", "x");
}
}
return "";
}
, :
- WCF ( Cassini/Integrated VS 2008).
- 1
DoWork(). TestDriven.NET VS 2008..dll NUnit's GUI .
, . , , AuthorizationContext.
, - WCF - WindowsAuthentication Auth, ? AuthorizationManager:
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="My.Namespace.CustomAuthMgr" />
</behavior>
My.Namespace.CustomAuthMgr ServiceAuthorizationManager. CustomAuthMgr.CheckAccess(), operationContext.ServiceSecurityContext.AuthorizationContext , , . , WCF, - AuthorizationContext.
3
: , , , :
public string DoWork()
{
var o = System.ServiceModel.OperationContext.Current.ServiceSecurityContext.AuthorizationContext;
if (o != null)
{
if (o.Properties.ContainsKey("x"))
o.Properties["x"] = (int)o.Properties["x"] + 1;
else
o.Properties.Add("x", 1);
}
return o.Properties["x"].ToString() + " | " + System.AppDomain.GetCurrentThreadId().ToString();
}
NUnit GUI :
1 | 3816
NUnit, :
2 | 3816
NUnit TestDriven.NET Visual Studio:
3 | 3816
, AuthorizationContext , , , , AuthorizationContext Thread-static -?
, . Thread.Sleep(10000); , 2 NUnit GUI, "2", :
2 | 5500
2 | 5764
, AuthorizationContext . .