创建委派令牌 - 无法创建安全令牌服务



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

我已经构建了一个非常简单的MVC Web应用程序,使用"身份和访问..."进行设置。向导,以与 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.IdentityModelSystem.IdentityModel.Services中都找不到从此类派生的任何类型,并且上面不包括对 ADFS 服务器的任何引用,我显然需要在某个时候提供。

当然,我也可能走上了完全错误的路线,或者只是遇到了一个小的绊脚石,没有看到远处隐约可见更大的绊脚石,所以任何关于这方面的建议也将不胜感激。


例如,我已经查看了身份委派方案,但它使用了CreateChannelActingAs,我认为当我与休息服务交谈时,它不起作用(或者会吗?),并且似乎也不适用于.NET 4.5。

我正在从 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 中的用户名混合终结点,则可能需要

激活它,并且之后不要忘记重新启动服务!

来自 msdn

若要创建 STS,必须从 SecurityTokenService 类派生。在自定义类中,必须至少重写 GetScope 和 GetOutputClaimsIdentity 方法。

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

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

编辑:
我认为,此视频(从 35:00+-开始)展示了一种使用 ws-federation saml 令牌实现您正在寻找的内容的方法。我猜它也可以用 SAML2 令牌

最新更新