Limit the number of concurrent wcf sessions per user

I have a WCF service that is session-based and secure (likely to use federated security).

I would like to allow only 1 concurrent session for each user. For example, bob can open a session and contact the server, but if it tries to open another session without closing the first, it will not succeed.

Does WCF support this out of the box? Thank!

+3
source share
2 answers

I can’t figure out how to do this automatically. But you can do it manually by storing the list of sessions ( OperationContext.Current.Channel.SessionId) and associated users in memory in your service, perhaps like this:

private static Dictionary<string, Guid> activeSessions = new Dictionary<string, Guid>();

, , . , . , / . OperationContext.Current.Channel.OnClosed, , . , :

OperationContext.Current.Channel.OnClosed += (s, e) =>
    {
        Guid sessionId = ((IContextChannel)sender).SessionId;
        var entry = activeSessions.FirstOrDefault(kvp => kvp.Value == sessionId);
        activeSessions.Remove(entry.Key);
    };
+3

, :

  • , .
  • , / .
  • serviceAuthorization, .

. .

:

<system.serviceModel>
    <client>
        <endpoint name="NetTcpBinding_IService"
                  address="net.tcp://localhost:13031/Service"
                  binding="netTcpBinding" bindingConfiguration="TCP"
                  contract="Common.IService"/>
    </client>
    <bindings>
        <netTcpBinding>
            <binding name="TCP">
                <security mode="Transport">
                    <transport clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
</system.serviceModel>

:

<system.serviceModel>
    <services>
        <service name="Server.Service" behaviorConfiguration="customAuthorization">
            <endpoint address="net.tcp://localhost:13031/Service"
                      binding="netTcpBinding" bindingConfiguration="TCP"
                      contract="Common.IService" />
        </service>
    </services>
    <bindings>
        <netTcpBinding>
            <binding name="TCP">
                <security mode="Transport">
                    <transport clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="customAuthorization">
                <serviceAuthorization 
                    serviceAuthorizationManagerType="Extensions.SingleSessionPerUserManager, Extensions"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

:

public class SingleSessionPerUserManager : ServiceAuthorizationManager
{
    private SessionStorage Storage { get; set; }

    public SingleSessionPerUserManager()
    {
        Storage = new SessionStorage();
    }

    protected override bool CheckAccessCore( OperationContext operationContext )
    {
        string name = operationContext.ServiceSecurityContext.PrimaryIdentity.Name;
        if ( Storage.IsActive( name ) )
            return false;

        Storage.Activate( operationContext.SessionId, name );
        operationContext.Channel.Closed += new EventHandler( Channel_Closed );
        return true;
    }

    private void Channel_Closed( object sender, EventArgs e )
    {
        Storage.Deactivate( ( sender as IContextChannel ).SessionId );
    }
}

, :

public class SessionStorage
{
    private Dictionary<string, string> Names { get; set; }

    public SessionStorage()
    {
        Names = new Dictionary<string, string>();
    }

    public void Activate( string sessionId, string name )
    {
        Names[ name ] = sessionId;
    }

    public void Deactivate( string sessionId )
    {
        string name = ( from n in Names where n.Value == sessionId select n.Key ).FirstOrDefault();
        if ( name == null )
            return;

        Names.Remove( name );
    }

    public bool IsActive( string name )
    {
        return Names.ContainsKey( name );
    }
}

: System.ServiceModel.Security.SecurityAccessDeniedException: ..

+3

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


All Articles