세션 기반 보안 WCF 서비스가 있습니다. (아마도 연합 보안을 사용합니다).사용자 당 동시 wcf 세션 수를 제한하십시오.
사용자 당 동시 세션을 1 개 허용하고 싶습니다. 예를 들어 bob은 세션을 열고 서버와 통신 할 수 있지만 첫 번째 세션을 닫지 않고 다른 세션을 열려고하면 성공하지 못합니다.
WCF가이 제품을 즉시 지원합니까? 감사합니다.
세션 기반 보안 WCF 서비스가 있습니다. (아마도 연합 보안을 사용합니다).사용자 당 동시 wcf 세션 수를 제한하십시오.
사용자 당 동시 세션을 1 개 허용하고 싶습니다. 예를 들어 bob은 세션을 열고 서버와 통신 할 수 있지만 첫 번째 세션을 닫지 않고 다른 세션을 열려고하면 성공하지 못합니다.
WCF가이 제품을 즉시 지원합니까? 감사합니다.
나는 자동으로 그렇게 할 생각이 없다. 하지만 당신은 아마도이 같은 서비스에 메모리에 세션 (OperationContext.Current.Channel.SessionId
) 및 관련 사용자의 목록을 유지하여 수동으로 TI을 할 수있는 : 당신이 어떤 요청을 처리하기 전에
private static Dictionary<string, Guid> activeSessions = new Dictionary<string, Guid>();
, 즉 사용자가이 있는지 확인 다른 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);
};
이 접근 방식에는 큰 문제가 있습니다. 채널을 제대로 닫지 않고 클라이언트가 충돌하면 서비스를 다시 시작할 때까지 다시 연결할 수 없습니다. 그 문제에 대한 해결책이 있습니까? – chris
@Chris - 채널을 닫지 않고 클라이언트가 충돌하면 채널이 계속 닫힙니다. Net.TCP와 같은 연결 지향 바인딩을 사용하고 있다면 즉시 닫힙니다. 긴 폴링 바인딩 중 하나를 사용하는 경우 시간이 초과 될 때까지 시간이 걸릴 수 있습니다. 그러나 "Channel.OnClosed"이벤트는 결국 어느 경우에도 실행됩니다. –
는 기본적으로, 당신은 다음을 수행해야합니다 클라이언트와 서비스에
다음 구성 및 코드 샘플을 참조하십시오.
클라이언트 구성 :
<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);
}
}
편집 : 14,도우미 클래스는 세션 정보 추적하는 데 사용 첫 번째 세션이 활성화 된 후를, 세션에 대한 각각 다음과 같은 요청은 System.ServiceModel.Security.SecurityAccessDeniedException가 발생합니다 : 액세스가 거절 당했다. 예외가 발생합니다.
왜이 작업을 수행 하시겠습니까? 세션이 너무 비싸습니까? –
예를 들어, 경합이있을 수 있기 때문에 사용자가 2 대의 다른 컴퓨터에서 서비스에 로그인 할 수 없도록하려는 경우 (예 : 다른 컴퓨터에서 Gmail에 로그인하는 경우와 같은 방법으로 원래 컴퓨터에서 시작). –
사실, 원하는만큼의 컴퓨터에서 gmail에 로그인 할 수 있습니다. 하지만 그것은 측면 문제입니다 :-). –