日内瓦框架中RP-STS的简单声明转换

时间:2009-05-01 12:12:14

标签: federated-identity geneva-framework claims-based-identity

在阅读有关使用Microsoft Geneva Framework实现自定义STS的MSDN文章(http://msdn.microsoft.com/en-us/magazine/2009.01.genevests.aspx)后,我对其中的一个场景感到有些困惑。此方案显示在上面引用文章的图13中。

我的问题是RP如何发起对RP-STS的呼叫,以便传递已经从IP-STS获得的声明?如何将期望的方法DeleteOrder()变为RP-STS的Action声明的声明请求,该声明响应Action声明,其值为Delete,授权呼叫?我还认为这个数字有点不正确,因为RP-STS和策略引擎之间的交互应该有相反的声明和箭头。

我可以看到结构,但不清楚Geneva / WCF提供了什么以及在RP内部的代码中需要做些什么,这看起来有点奇怪,因为我们无法保护具有PrincipalPermission需求的DeleteOrder方法删除“权限”但必须首先要求一个角色,然后在该点之后获得删除操作的细粒度声明。

如果我错过了这一点(因为我无法在网上轻易找到这个案例),那么道歉!

提前致谢。

2 个答案:

答案 0 :(得分:1)

我在日内瓦论坛上提出了同样的问题 http://social.msdn.microsoft.com/Forums/en/Geneva/thread/d10c556c-1ec5-409d-8c25-bee2933e85ea?prof=required 得到了这个回复:

嗨Dokie,

当我读到那篇文章时,我想知道同样的事情。当我思考如何实施这样的场景时,我提出了两个想法:

  1. RP实际上配置为要求来自RP-STS的声明; RP-STS需要来自IP-STS的安全令牌。结果,当主体请求RP的资源时,它将他反弹到RP-STS,后者将他反弹到IP-STS。在那里进行身份验证后,他将被退回到RP-STS,以身份为中心的声明被转换为做出授权决定所必需的声明并返回到RP。

  2. RP被配置为具有拦截器(例如,如果它是WCF服务的AuthorizationPolicy),它可以抓取调用,查看以身份为中心的声明,创建RST(使用WSTrustClient),将其传递给RP-STS,该服务将声明扩展为返回到RP的新声明,并且RP做出授权决定。

  3. 我从未实现过这个,但是,如果我要去,我会进一步探索这两个想法。

    HTH!


    此致

    Travis Spencer

    所以我先尝试选项2然后看看是否有效,然后在这里制定答案。

答案 1 :(得分:0)

我的情况很好。 在我的情况下,AD FS是身份服务,自定义STS是资源STS。

所有webapp都使用相同的资源STS,但在用户访问其他应用程序后,由于用户已经过身份验证,因此AD FS不会再次添加身份相关的声明。如何再次强制或请求AD FS的基本声明?

我已经使用ActAs创建了对AD FS的调用,现在它返回了我的身份声明。 请记住为用于调用AD FS的凭据启用委派允许规则。

string stsEndpoint = "https://<ADFS>/adfs/services/trust/2005/usernamemixed";
     var trustChannelFactory = new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), stsEndpoint);

     trustChannelFactory.Credentials.UserName.UserName = @"DELEGATE";
     trustChannelFactory.Credentials.UserName.Password = @"PASSWORD";

     trustChannelFactory.TrustVersion = TrustVersion.WSTrustFeb2005;

     //// Prepare the RST.
     //var trustChannelFactory = new WSTrustChannelFactory(tokenParameters.IssuerBinding, tokenParameters.IssuerAddress);
     var trustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel();

     var rst = new RequestSecurityToken(RequestTypes.Issue);

     rst.AppliesTo = new EndpointAddress(@"https:<RPADDRESS>");

     // If you're doing delegation, set the ActAs value.
     var principal = Thread.CurrentPrincipal as IClaimsPrincipal;
     var bootstrapToken = principal.Identities[0].BootstrapToken;

     // The bootstraptoken is the token received from the AD FS after succesfull authentication, this can be reused to call the AD FS the the users credentials
     if (bootstrapToken == null)
     {
        throw new Exception("Bootstraptoken is empty, make sure SaveBootstrapTokens = true at the RP");
     }

     rst.ActAs = new SecurityTokenElement(bootstrapToken);

     // Beware, this mode make's sure that there is no certficiate needed for the RP -> AD FS communication
     rst.KeyType = KeyTypes.Bearer;

     // Disable the need for AD FS to crypt the data to R-STS
     Scope.SymmetricKeyEncryptionRequired = false;

     // Here's where you can look up claims requirements dynamically.
     rst.Claims.Add(new RequestClaim(ClaimTypes.Name));
     rst.Claims.Add(new RequestClaim(ClaimTypes.PrimarySid));

     // Get the token and attach it to the channel before making a request.
     RequestSecurityTokenResponse rstr = null;
     var issuedToken = trustChannel.Issue(rst, out rstr);
     var claims = GetClaimsFromToken((GenericXmlSecurityToken)issuedToken);

 private static ClaimCollection GetClaimsFromToken(GenericXmlSecurityToken genericToken)
  {
     var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers;
     var token = handlers.ReadToken(new XmlTextReader(new StringReader(genericToken.TokenXml.OuterXml)));
     return handlers.ValidateToken(token).First().Claims;
  }