Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建委派令牌-can';t创建SecurityTokenService_C#_Visual Studio 2012_.net 4.5_Adfs2.0 - Fatal编程技术网

C# 创建委派令牌-can';t创建SecurityTokenService

C# 创建委派令牌-can';t创建SecurityTokenService,c#,visual-studio-2012,.net-4.5,adfs2.0,C#,Visual Studio 2012,.net 4.5,Adfs2.0,我正在尝试建立一个与ADF和索赔相关的系统。目前,这只是一个“玩具”实现 我构建了一个非常简单的MVC web应用程序,使用Visual Studio中的“标识和访问…”向导将其设置为与ADFS 2.0服务器对话,并将其部署到IIS服务器。所有工作都很好,我可以检查并列出收到的索赔 下一步是构建基于Web API的REST服务(表示MVC应用程序将依赖的后端服务),因此我希望将凭据传递给后端服务器,以便它能够做出适当的授权决策 因此,我的第一步是创建委派令牌(然后,我希望能够在HttpClien

我正在尝试建立一个与ADF和索赔相关的系统。目前,这只是一个“玩具”实现

我构建了一个非常简单的MVC web应用程序,使用Visual Studio中的“标识和访问…”向导将其设置为与ADFS 2.0服务器对话,并将其部署到IIS服务器。所有工作都很好,我可以检查并列出收到的索赔

下一步是构建基于Web API的REST服务(表示MVC应用程序将依赖的后端服务),因此我希望将凭据传递给后端服务器,以便它能够做出适当的授权决策

因此,我的第一步是创建委派令牌(然后,我希望能够在
HttpClient
类中解决如何使用它来进行rest调用)。我有这个:

//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
System.IdentityModel.Services
中,我都找不到从这个类派生的任何类型,而且上面没有任何对ADFS服务器的引用,我显然需要在某个时候提供这些引用

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


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

From


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

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

我猜web api很可能也会支持这一点,因为它是基于wcf构建的,从http的角度来看,它没有理由不支持ws-federation/saml 2令牌

编辑:

我认为,视频(从35:00+-)展示了一种使用ws-federation saml令牌实现您所需的方法。我猜使用saml2令牌也有可能

我正在从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();
                }
            }
        }
    }
public SecurityToken GetToken(out-RequestSecurityTokenResponse-rstr)
{
Console.WriteLine(“连接到STS…”);
WSTrustChannelFactory=null;
尝试
{
如果(使用凭据)
{
//使用用户名信任绑定进行用户名身份验证
工厂=
新工厂(
新用户名WSTrustBinding(SecurityMode.TransportWithMessageCredential),
"https:///adfs/services/trust/13/UsernameMixed");
factory.TrustVersion=TrustVersion.WSTrust13;
//用户名和密码在这里。。。
factory.Credentials.UserName.UserName=“UserName”;
factory.Credentials.UserName.Password=“Password”;
}
其他的
{
//基于传输安全的Windows身份验证
工厂=新工厂(
新WindowsWSTrustBinding(SecurityMode.Transport),
"https:///adfs/services/trust/13/windowstransport”{TrustVersion=TrustVersion.WSTrust13};
}
var rst=新的RequestSecurityToken
{
RequestType=RequestTypes.Issue,
AppliesTo=SvcEndpoint,
KeyType=KeyTypes.Symmetric,
RequestDisplayToken=true
};
Console.WriteLine(“为STS创建频道…”);
IWSTrustChannelContract channel=factory.CreateChannel();
WriteLine(“从“+StsEndpoint.Uri”请求令牌);
SecurityToken令牌=通道问题(rst,out rstr);
WriteLine(“从“+StsEndpoint.Uri”接收的令牌);
返回令牌;
}
最后
{
如果(工厂!=null)
{
尝试
{
工厂关闭();
}
捕获(通信对象故障异常)
{
factory.Abort();
}
}
}
}

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

我不想实现一个STS——我想和ADFS对话,让它发布一个委托令牌——我似乎找不到一个方法来实现。我知道我不想自己创建一个——但我想向ADFS发送一个请求,请求委托令牌——理想情况下,我正在寻找类似
var STS=new SomeStsObject的东西(adfsEndpointAddress);var tokan=sts.Issue(rst);
,但还没有找到。如果我理解正确,这不是它应该如何工作的;您不应该发送ad fs委托请求。您应该根据它进行身份验证并接收令牌,就像在通常的流程中一样。然后,您将收到的令牌委托给下一个消费者,假设他信任它。您不是允许任何代码行执行某些操作