为多个客户端使用一项服务 [英] Using one Service for Multiple Clients
问题描述
我已经建立了具有多个端点的WCF服务.目的是使用WCF服务数据库.一位用户有一个登录名,等等.
I have set up a WCF Service with multiple endpoints. The intention being to use the WCF to serve a database. One user has one log in etc.
因此,在进行了一些研究之后,我对.svc进行了如下装饰:
So after some research I decorate the .svc like so:
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerCall, AutomaticSessionShutdown:=True,
ConcurrencyMode:=ConcurrencyMode.Single, IncludeExceptionDetailInFaults:=True)>
我以为InstanceContextMode为每次调用",它会在每次调用"中创建一个服务实例,这意味着它将在每次调用后触发UsernameAuthentication.不 发生.
I made thought that with the InstanceContextMode being Per Call, that it would create a Service Instance Per Call, meaning it would fire the UsernameAuthentication after each call... However after putting in a line to write to the event log, this doesn't happen.
验证:
Imports System.Data.SqlClient
Imports System.IdentityModel.Selectors
Imports System.Reflection
Imports System.Security
Imports System.Threading
Imports DVPWCFService.Modules
Namespace Classes.Admin
Public Class Validation
Inherits UserNamePasswordValidator
Private _dbUsername As String
Private _dbPassword As SecureString
Public Overrides Sub Validate(userName As String, password As String)
Try
_dbUsername = userName
_dbPassword = ConvertToSecureString(password)
DbUsername = userName
DbPassword = ConvertToSecureString(password)
Dim dummyConnectionForValidation As SqlConnection = LogInTry("A real server name")
dummyConnectionForValidation.Close()
dummyConnectionForValidation.Dispose()
Catch ex As Exception
If ex.GetType Is GetType(SqlException) Then
DVPEventLog.WriteEntry("Authentication has failed for user: '" + userName + "'", EventLogEntryType.Warning)
Else
DVPEventLog.WriteEntry("Error: " & ex.Message & Environment.NewLine & Environment.NewLine & "Stack Trace: " & ex.StackTrace & Environment.NewLine & Environment.NewLine & "Method Name: " & MethodBase.GetCurrentMethod.Name, EventLogEntryType.Error, EventLogEntryType.Error)
End If
Thread.Sleep(5000)
Throw New FaultException("Log in failed.")
End Try
End Sub
Private Function LogInTry(serverName As String) As SqlConnection
LogInTry = New SqlConnection
LogInTry.ConnectionString = "Data Source=" & serverName & ";Persist Security Info=True;MultipleActiveResultSets=True;"
LogInTry.FireInfoMessageEventOnUserErrors = True
LogInTry.Credential = New SqlCredential(_dbUsername, _dbPassword)
LogInTry.Open()
End Function
Private Function ConvertToSecureString(convertee As String) As SecureString
ConvertToSecureString = New SecureString()
For Each stringCharacter In convertee.ToCharArray()
ConvertToSecureString.AppendChar(stringCharacter)
Next
ConvertToSecureString.MakeReadOnly()
End Function
End Class
End Namespace
因此,在验证代码中,我只是确保用户可以登录到服务器.我存储用户名,以便在验证发生后可以再次使用它,因为我认为验证后它会直接转到我进行的呼叫中,而无需处理任何事情.
So in the validation code I just make sure the user can log in to the server. I store the username so I can use it again after the Validation occurs because i presumed after the validation it'd go straight to the call I made without disposing of anything.
应用配置:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2"/>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="SSL Binding" openTimeout="00:00:20" receiveTimeout="08:00:00" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647"
maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" algorithmSuite="TripleDesSha256Rsa15" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="Custom Validation Service Behavior" name="DVPWCFService.DVP">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SSL Binding"
name="IComponent" contract="DVPWCFService.Interfaces.IComponent" />
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SSL Binding"
name="IProgramme" contract="DVPWCFService.Interfaces.IProgramme" />
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SSL Binding"
name="IVehicle" contract="DVPWCFService.Interfaces.IVehicle" />
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SSL Binding"
name="IMiscellaneous" contract="DVPWCFService.Interfaces.IMiscellaneous" />
<endpoint address="mex" binding="mexHttpsBinding" name="metadata"
contract="IMetadataExchange" />
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SSL Binding"
name="IReservation" contract="DVPWCFService.Interfaces.IReservation" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Custom Validation Service Behavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug httpHelpPageEnabled="true" httpsHelpPageEnabled="true"
includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="blahblahblah"
x509FindType="FindByThumbprint" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="DVPWCFService.Classes.Admin.Validation, DVPWCFService"/>
</serviceCredentials>
<dataContractSerializer />
<serviceThrottling maxConcurrentCalls="10" maxConcurrentSessions="10" maxConcurrentInstances="1" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="wsHttpBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="false" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="false"/>
</system.webServer>
</configuration>
当有一个以上的人使用服务时,这一切都会崩溃,因为它会覆盖用户名和密码变量.这很奇怪,因为我将其设置为每次通话和单次通话?我没有正确处理吗?有没有办法确保它得到 处理并让每个呼叫通过验证等?
This all falls apart when there's more than one person using the Service because it overwrites the Username and Password variables. This is strange as I set it to per call and single? Am I not disposing of it properly? Is there a way to make sure it gets disposed of and to make each call go through the validation etc?
推荐答案
目的是使用WCF为数据库提供服务.一位用户有一个登录名,等等.
大多数人只会在连接字符串上使用通用的用户ID和psw,因此无需在数据库级别上对用户进行身份验证.任何用户身份验证都应该在客户端端上很好地实现,甚至在后端代码均未实现之前
Most would just use a generic user-id and psw on the connectionstring so no user would need to be authenticated at the DB level. Any user authentication should be implemented on the client side well before backend code is even called.
这篇关于为多个客户端使用一项服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!