8

我正在尝试构建一个使用 ADFS 和声明的系统。目前,这只是一个“玩具”实现。

我构建了一个非常简单的 MVC Web 应用程序,使用 Visual Studio 中的“身份和访问...”向导对其进行设置,以与 ADFS 2.0 服务器通信,并将其部署到 IIS 服务器。一切正常,我可以检查并列出收到的索赔。

下一步是构建一个基于 Web API 的 REST 服务(代表 MVC 应用程序将依赖的后端服务),所以我想将凭据传递给该后端服务器,以便它可以进行适当的授权决定。

所以第一步是我创建委托令牌(然后,我希望根据HttpClient类来确定如何处理它以进行其余调用)。我有这个:

//We need to take the bootstrap token and create an appropriate ActAs token
var rst = new RequestSecurityToken
{
    AppliesTo = new EndpointReference("https://other-iis.example.com/Rest"),
    RequestType = RequestTypes.Issue,
    KeyType = KeyTypes.Symmetric,
    ActAs = new SecurityTokenElement(((BootstrapContext)((ClaimsIdentity)User.Identity).BootstrapContext).SecurityToken)
};

var sts = new SecurityTokenService(); //This line isn't valid
var resp = sts.Issue(System.Threading.Thread.CurrentPrincipal as ClaimsPrincipal, rst);

但是,问题是SecurityTokenService抽象的。System.IdentityModel我在nor中找不到从此类派生的任何类型System.IdentityModel.Services,并且上面不包含对 ADFS 服务器的任何引用,我显然需要在某些时候提供。

当然,我也可能完全走错了路,或者只是碰到了一个小绊脚石,而没有看到远处有一个更大的绊脚石,所以对此的任何建议也将不胜感激。


例如,我已经看过Identity Delegation Scenario,但是它使用CreateChannelActingAs,我认为当我与休息服务(或者会吗?)交谈时它不会起作用,而且似乎也不起作用适用于 .NET 4.5。

4

3 回答 3

3

我正在从 ADFS 2.0 请求令牌以进行缓存和查看 DisplayToken。也许这可以帮助您入门。

这是我能做的:

    public SecurityToken GetToken(out RequestSecurityTokenResponse rstr)
    {
        Console.WriteLine("Connecting to STS...");

        WSTrustChannelFactory factory = null;

        try
        {
            if (_useCredentials)
            {
                // use a UserName Trust Binding for username authentication
                factory =
                    new WSTrustChannelFactory(
                        new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
                        "https://<adfs>/adfs/services/trust/13/UsernameMixed");

                factory.TrustVersion = TrustVersion.WSTrust13;

                // Username and Password here...
                factory.Credentials.UserName.UserName = "username";
                factory.Credentials.UserName.Password = "password";
            }
            else
            {
                // Windows authentication over transport security
                factory = new WSTrustChannelFactory(
                    new WindowsWSTrustBinding(SecurityMode.Transport),
                    "https://<adfs>/adfs/services/trust/13/windowstransport") { TrustVersion = TrustVersion.WSTrust13 };
            }

            var rst = new RequestSecurityToken
                          {
                              RequestType = RequestTypes.Issue,
                              AppliesTo = SvcEndpoint,
                              KeyType = KeyTypes.Symmetric,
                              RequestDisplayToken = true
                          };

            Console.WriteLine("Creating channel for STS...");

            IWSTrustChannelContract channel = factory.CreateChannel();

             Console.WriteLine("Requesting token from " + StsEndpoint.Uri);
             SecurityToken token = channel.Issue(rst, out rstr);
             Console.WriteLine("Received token from " + StsEndpoint.Uri);

            return token;
        }
        finally
        {
            if (factory != null)
            {
                try
                {
                    factory.Close();
                }
                catch (CommunicationObjectFaultedException)
                {
                    factory.Abort();
                }
            }
        }
    }

如果您想使用它,您可能必须在 ADFS 2.0 中激活 UsernameMixed Endpoint,并且不要忘记之后重新启动服务!

于 2012-06-06T13:32:43.613 回答
1

来自msdn

要创建 STS,您必须从 SecurityTokenService 类派生。在您的自定义类中,您必须至少覆盖 GetScope 和 GetOutputClaimsIdentity 方法。

于 2012-06-05T16:39:09.020 回答
1

不确定这对您有多大帮助,但您不应该创建 SecurityTokenService。您没有在此处创建新令牌,并且您的应用程序不应该充当 STS - 这就是 AD FS 的用途。
您的应用程序应仅将从 AD FS 收到的令牌委托给服务(您在问题中提供的 msdn 链接中描述了该概念)

我猜 web api 很有可能也会支持这一点,因为它建立在 wcf 之上,并且从 http 的角度来看 - 它没有理由不支持 ws-federation/saml 2 令牌。

编辑:
这个视频(从 35:00+- 开始)展示了一种方法,我认为,用 ws-federation saml 令牌来实现你正在寻找的东西。我猜它也可能使用 saml2 令牌

于 2012-06-05T17:02:20.800 回答