の NT 資格情報を使用して RequestSecurityToken を積極的に発行するためのサンプル コードを誰か指摘できます Thread.CurrentPrincipal as ClaimsPrincipal
か?
シナリオは、Windows 認証が有効になっている asp.net Web アプリです (したがって、認証済みの WindowsIdentity があります)。私の望みは、passiveRedirect を有効にするのではなく、STS をアクティブに呼び出し、.Net 4.5 ID ライブラリを使用してこれを行うことです。
Claims Helper for Windows PhoneやUsing an Active STSなどのほとんどのコード サンプルでは、username/pwd 入力と UserNameWSTrustBinding を使用して資格情報を設定します。
channelFactory.CreateChannelWithActAsToken()
解決策には、なりすましや、Windows ID から作成されたトークンを使用した呼び出しが含まれる可能性があると思いました。
-- 次の .Net4.5 コードは、/adfs/services/trust/13/windowsmixed エンドポイントにヒットしたときに GenericXmlSecurityToken を取得します。ただし、クレームはサイトが実行されているドメイン アカウントに対するものであり、認証されたユーザーのドメイン アカウントに対するものではありません。エンドポイントを /adfs/services/trust/13/kerberossmixed に切り替えると、いくつかの質問やフォーラムに記載されているように「交渉できません」というエラーが表示されますが、.Net 4.5 で提供されているソリューションを適用できません。Microsoft.IdentityModel から移植されていないクラスの 1 つは、KerberosWSTrustBinding です...
public static void CallSts()
{
try
{
var wsMod = FederatedAuthentication.WSFederationAuthenticationModule;
var appliesToEp = new EndpointReference(wsMod.Realm);
var stsEp = new EndpointAddress(new Uri(wsMod.Issuer), EndpointIdentity.CreateSpnIdentity("stsSpn"));
var msgBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false);
msgBinding.Security.Message.EstablishSecurityContext = false;
msgBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
using(var factory = new WSTrustChannelFactory(msgBinding, stsEp))
{
factory.Credentials.SupportInteractive = false;
factory.TrustVersion = TrustVersion.WSTrust13;
var myRst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = appliesToEp,
KeyType = KeyTypes.Bearer,
};
var channel = factory.CreateChannel();
var stsToken = channel.Issue(myRst) as GenericXmlSecurityToken;
if(stsToken != null)
{
Log.DebugFormat("Reply Token is {0}", stsToken.GetType().Name);
var handlers = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers;
var token = handlers.ReadToken(new XmlTextReader(new StringReader(stsToken.TokenXml.OuterXml)));
var identity = handlers.ValidateToken(token).First();
//TODO write to session
}
else
{
Log.Debug("Reply Token is null.");
}
}
}
catch(Exception ex)
{
Log.Error("Rst.Call has failed", ex);
}
}
@leastprivilege の提案として、次のコードを追加します。
var user = Thread.CurrentPrincipal as ClaimsPrincipal;
var winId = user.Identity as WindowsIdentity;
if(winId != null)
{
// shows my domain account after I was prompted for credentials;
// my domain account does not exist on the client machine, so it is a true domain credential
Log.DebugFormat("WindowsIdentity Name is {0}", winId.Name);
}
using(winId.Impersonate())
{
// again, shows my domain account
Log.DebugFormat("Impersonation Context {0}", WindowsIdentity.GetCurrent(true).Name);
var channel = factory.CreateChannel();
var stsToken = channel.Issue(myRst) as GenericXmlSecurityToken;
// request is issued, but results in SecurityNegotiationException: The caller was not authenticated by the service.
}
「発信者はサービスによって認証されませんでした」で失敗します。同じ STS がパッシブ リダイレクト シナリオで私のドメイン アカウントを認証します。
アップデート:
この質問がかなりの数のビューを受け取ったという通知を受け取ったので、1 つの回避策として次のことを提案します: サーバーを委任用に構成しましたが (Dominick が以下で提案したように)、それでもダブルホップの問題を克服できませんでした。思い出すと、私たちは、ローカル IT 上の単純なネットワーク管理ポリシーから、どの企業も同様に直面する可能性のある障害にぶつかりました。そのため、Windows 認証を使用したサーバーに対してダブル ホップを介して偽装することは許可されていませんが、基本認証を使用してダブル ホップを介して資格情報を偽装することができます。これは、許容できる状況である場合とそうでない場合があります (この場合はイントラネット)。もしそうなら、あなたは追加するでしょう
msgBinding.Security.Message.NegotiateServiceCredential = true;
上記の ChannelBinding 構成に。