ユーザーがユーザー名とパスワードを入力する独自のログイン画面を持つ Web サイトがあります。ログイン ボタンを押すと、ユーザーは ADFS を介して認証され、SAML トークンが返されます。これは機能します。現時点では、ユーザーにログインするために何をする必要があるのか わかりません.不明な理由は、このWebサイトに少しひねりがあるためです. 前述したように、ユーザーは Web サイトのログイン ページから ADFS 経由でサインインします。ただし、ユーザーが許可されていないページにアクセスした場合、ユーザーをログイン ページにリダイレクトするのではなく、ユーザーを ADFS ログイン ページにリダイレクトする必要があります。私はこの方法でプロジェクト全体を開始しました。ユーザーは、ADFS のログイン ページを通じて認証されます。これは、ConfigureAuth メソッド (StartupAuth.cs 内) を次のように設定するだけで簡単に実行できました。
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = realm,
MetadataAddress = adfsMetadata
});
}
簡単です!ページに移動しようとする[Authorized]
と、ADFS ログイン ページに移動します。この後、別のログイン方法 (ログイン ページを使用して ADFS で認証する方法) に取り組みました。どちらの方法で認証しようとしても、同じ ADFS で認証していることに注意してください。1 つは ADFS のログイン ページを使用しており、もう 1 つはカスタム ログイン ページを使用しています。そこで、ログイン用のシンプルで小さなフォームを備えたカスタム ログイン ページを作成します。
<form action="@Url.Action("SignIn", "Account")" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="submit" value="Login" />
</form>
これはうまくいきます。送信ボタンを押すと、SignIn アクションが試行されます。SignIn アクションは次のようになります。
[HttpPost]
public ActionResult SignIn(string username, string password)
{
if (!Request.IsAuthenticated)
{
const string _relyingPartyUri = "https://myrelayingparty/";
const string _serverName = "myservername";
const string certSubject = "CN=mycertsubject";
string endpointUri = string.Format("https://{0}/adfs/services/trust/13/usernamemixed", _serverName);
var factory = new WSTrustChannelFactory(new UserNameWSTrustBinding(), endpointUri)
{
TrustVersion = TrustVersion.WSTrust13
};
factory.Credentials.UserName.UserName = @"mydomain\" + username;
factory.Credentials.UserName.Password = password;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference(_relyingPartyUri),
KeyType = KeyTypes.Bearer
};
var channel = factory.CreateChannel();
var genericToken = channel.Issue(rst) as GenericXmlSecurityToken;
if (genericToken != null)
{
//Setup the handlers needed to convert the generic token to a SAML Token
var tokenHandlers = new SecurityTokenHandlerCollection(new SecurityTokenHandler[] { new SamlSecurityTokenHandler() });
tokenHandlers.Configuration.AudienceRestriction = new AudienceRestriction();
tokenHandlers.Configuration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(_relyingPartyUri));
var trusted = new TrustedIssuerNameRegistry(certSubject);
tokenHandlers.Configuration.IssuerNameRegistry = trusted;
//convert the generic security token to a saml token
SecurityToken samlToken = tokenHandlers.ReadToken(new XmlTextReader(new StringReader(genericToken.TokenXml.OuterXml)));
//convert the saml token to a claims principal
var claimsPrincipal = new ClaimsPrincipal(tokenHandlers.ValidateToken(samlToken).First());
HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true, RedirectUri = "Home/Homepage" },
claimsPrincipal.Identities.ElementAt(0));
}
}
return RedirectToAction("Index", "Home");
}
samlToken を正常に取得して作成でき、それを検証して claimPrincipal を作成することもできます。サインインするためにこの後何をHttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true, RedirectUri = "Home/Homepage" },
claimsPrincipal.Identities.ElementAt(0));
すればよいかわかりません。StartupAuth.cs ファイルに追加の構成が必要ではないかとこっそり疑っていますが、確信が持てません。助けてくれてありがとう!