WCF AuthorizationContext is not cleared between calls from different clients. (was: When does the WCF service session really end?)

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 . .

+3
4

, . , , WCF .

? ?

+1

, SessionMode:

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required)]
public interface ICalculatorSession

http://msdn.microsoft.com/en-us/library/ms733040.aspx

http://msdn.microsoft.com/en-us/library/system.servicemodel.sessionmode.aspx

+1

WsHttp , . ( ), , .

, - - , - , - "". - wsHttpBinding:

  <wsHttpBinding>
    <binding>
      <reliableSession inactivityTimeout="00:10:00"/>
    </binding>
  </wsHttpBinding>

.

: "", , .

[ServiceContract(SessionMode=SessionMode.Required)]
interface YourServiceContract
{
    [OperationContract(IsInitiating = true)]
    void InitMethod();

    [OperationContract]
    void WorkMethod()

    [OperationContract(IsTerminating=true)]
    void EndSessionMethod()
}

EndSessionMethod , .

: , FaultException, , .

, , , . ....

+1

I have a similar problem - I see that the AuthorizationContext remains unchanged after every call.

I noticed that in your configuration file you have

<serviceAuthorization principalPermissionMode="Custom" ....

Try removing mainPermissionMode = "Custom." At least in my case, each new call has a zero authorization context.

0
source

Source: https://habr.com/ru/post/1713684/


All Articles