我有一个简单的.NET 4.5 MVC网站。登录后,会创建一个带有一些测试声明的ClaimsPrincipal
:
List<Claim> claims = new List<Claim>();
claims.Add(new Claim("Test", "Test"));
claims.Add(new Claim(ClaimTypes.NameIdentifier, "nameid"));
var id = new ClaimsIdentity(claims, "Forms");
var cp = new ClaimsPrincipal(id);
var token = new SessionSecurityToken(cp);
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(token);
web.config
能够实现这一目标:
<!-- (have snipped out standard, not interesting web.config) -->
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthenticationModule" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="false" persistentSessionLifetime="2"/>
从网络应用程序的其他地方,我可以使用ClaimsPrincipal.Current
来获取声明。
我需要将这些声明发送到友好的WCF服务(仅限Intranet)。从上面可以看出,令牌是在Web应用程序中创建的,而不是在STS上创建的。我希望能够将该令牌传递给WCF服务,并让服务将其设置为ClaimsPrincipal。
该服务如下:
// IClaimsCheckService
[ServiceContract]
public interface IClaimsCheckService
{
[OperationContract]
void CheckClaims();
// ClaimsCheckService.svc
public class ClaimsCheckService : IClaimsCheckService
{
public void CheckClaims()
{
var claimsPrincipal = ClaimsPrincipal.Current;
}
}
服务器web.config
是:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization principalPermissionMode="Always" />
<serviceCredentials useIdentityConfiguration="true" />
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
客户端的web.config
- 这是上面描述的MVC网站,此配置是上面代码段的其余配置。
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<clientCredentials useIdentityConfiguration="true">
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IClaimsCheckService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:59343/ClaimsCheckService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IClaimsCheckService"
contract="CCS.IClaimsCheckService" name="BasicHttpBinding_IClaimsCheckService" />
</client>
</system.serviceModel>
我读过Dominick Baier关于WCF and Identity in .NET 4.5的精彩系列。我也读过密集的MSDN article on Claims based authorization.与其他问题不同,我没有使用STS,而是在网站上创建联合令牌。
当调用服务时,我希望WCF客户端将客户端线程中的Principal发送到WCF服务,这样当我在服务器上执行var claimsPrincipal = ClaimsPrincipal.Current;
时,我会获得相同的Principal。
ClaimsPrincipal.Current
为空(新),不包含客户端的任何信息。
我觉得创建自己的令牌不起作用,因为WCF服务无法将其解码回声明。另外,我担心我不能使用basicHttpBinding而没有安全性。
提前谢谢!
答案 0 :(得分:1)
你的故事中有一些弱点,但我会跳过它们。 (例如:如果您创建安全令牌,则 是STS。) 对于您想要做的事情,有几种方法。最标准但最困难的是对您的服务使用ws2007federationhttpbinding绑定。这需要一个支持WS-Trust协议的完整STS(带有securitytoken服务类等)。如果您的服务需要从互联网上调用并且标准很重要(比如在混合的Java / c#环境中),我会建议这种方法。
在Intranet方法中,还可以回退到将安全令牌作为数据提取的一部分传递。您在客户端上序列化claimprincipal(使用您选择的securitytokenhandler)并在您的服务中反序列化它(使用相同的安全性令牌处理程序)。根据安全要求,您可以或多或少严格遵守序列化令牌的安全性。如果它需要是安全的,您可以选择在客户端上签名,然后验证服务上的签名(使用对称密钥或基于您的偏好的证书)。
如果您希望发送的claimprincipal自动反序列化并分配给ClaimsPrincipal.Current,那么您可以考虑创建一个小的WCF服务行为,该行为将主体发送到服务并在服务中解压缩。此行为中的功能与第二种方法大致相同。这是一项更多的工作,但它是一个可重用的解决方案。如果你在这种行为上走得太远,那么解决方案1是一种更好的方法。
作为最后的评论。如果你想&#34;检查索赔&#34;然后你想迁移想要使用ClaimsAuthorizationManager而不是服务来做到这一点。在这种情况下,您不需要通过电汇传递任何ClaimsPrincipal。