C# 为什么Thread.CurrentPrincipal.Identity.IsAuthenticated始终为false?
我有这个WCF服务,我正在尝试在其中应用身份验证和授权机制。C# 为什么Thread.CurrentPrincipal.Identity.IsAuthenticated始终为false?,c#,wcf,authentication,current-principal,C#,Wcf,Authentication,Current Principal,我有这个WCF服务,我正在尝试在其中应用身份验证和授权机制。 这是我第一次这样做,我拥有的是服务的web.configserviceModel标记: <system.serviceModel> <services> <service name="RoleBasedServices.SecureServiceExternal" behaviorConfiguration="externalServiceBehavior"> <endpoin
这是我第一次这样做,我拥有的是服务的web.config
serviceModel
标记:
<system.serviceModel>
<services>
<service name="RoleBasedServices.SecureServiceExternal" behaviorConfiguration="externalServiceBehavior">
<endpoint contract="AuthService.IService1" binding="wsHttpBinding" bindingConfiguration="wsHttpUsername" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsHttpUsername">
<security mode="Message">
<message clientCredentialType="UserName" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!--To avoid disclosing metadata information, set the values below to false before deployment-->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!--To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information-->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="externalServiceBehavior">
<serviceAuthorization principalPermissionMode="UseAspNetRoles" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider" />
<serviceCertificate findValue="RPKey" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
然后调用另一个受限方法,让它成为GetData
:
AuthService.Service1Client s = new AuthService.Service1Client();
s.Login();
s.GetData()
在服务端的Login
方法中,仅出于测试目的,我这样做:
public void Login()
{
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("Bob"), new[] { "Admin" });
FormsAuthentication.SetAuthCookie("BobUserName", false);
}
受限制的方法的一个例子是:
[PrincipalPermission(SecurityAction.Demand, Role = "Admin")]
public void GetData()
{
return "Hello";
}
我所有的服务和客户,我缺少什么?
每次在调试中,我都会在我找到的Thread.CurrentPrincipal.Identity.IsAuthenticated方法中检查Thread.CurrentPrincipal
,但即使客户端调用GetData()
方法,它的访问被拒绝
PS:我正在使用控制台应用程序进行测试,这有什么区别吗?
谢谢这里有一个可能导致解决方案的解决方案。
一般的想法是,你有2个对象作为主体。
HttpContext.Current.User
和Thread.CurrentPrincipal
。您正在设置Thread.CurrentPrincipal
,此时HttpContext.Current.User
已实例化,其角色保留为默认
您可能想尝试以下方法:
HttpContext.Current.User = new GenericPrincipal(new GenericIdentity("Bob"), new[] { "Admin" });
对GetData()
的调用被拒绝的原因是,WCF对在Login()
期间设置的表单身份验证cookie一无所知
你使用的是一个控制台应用程序,这没有什么区别。您可以尝试以下方法
在Login()中设置cookie
:
然后在您的控制台应用程序中:
public static void TestLoginAndGetData()
{
var sharedCookie = string.Empty;
using (var client = new YourClient())
using (new OperationContextScope(client.InnerChannel))
{
client.Login("username", "password");
// get the cookie from the response
HttpResponseMessageProperty response = (HttpResponseMessageProperty)
OperationContext.Current.IncomingMessageProperties[
HttpResponseMessageProperty.Name];
sharedCookie = response.Headers["Set-Cookie"];
// add it to the request
HttpRequestMessageProperty request = new HttpRequestMessageProperty();
request.Headers["Cookie"] = sharedCookie;
OperationContext.Current.OutgoingMessageProperties[
HttpRequestMessageProperty.Name] = request;
var result = client.GetData();
Console.WriteLine(result);
}
}
您还可以考虑将代码返回>类型> GETDATA()/<代码>改为<代码>字符串< /代码>。< /P>不应该充当“构建管理员”角色吗?
public static void TestLoginAndGetData()
{
var sharedCookie = string.Empty;
using (var client = new YourClient())
using (new OperationContextScope(client.InnerChannel))
{
client.Login("username", "password");
// get the cookie from the response
HttpResponseMessageProperty response = (HttpResponseMessageProperty)
OperationContext.Current.IncomingMessageProperties[
HttpResponseMessageProperty.Name];
sharedCookie = response.Headers["Set-Cookie"];
// add it to the request
HttpRequestMessageProperty request = new HttpRequestMessageProperty();
request.Headers["Cookie"] = sharedCookie;
OperationContext.Current.OutgoingMessageProperties[
HttpRequestMessageProperty.Name] = request;
var result = client.GetData();
Console.WriteLine(result);
}
}