私のIdentityServerはidentityserver4フレームワークを使用しています( http:// localhost:90 )。そして、以下のようにクライアントをIdentityServerに登録します。
clients.Add(
new Client
{
ClientId = "customer.api",
ClientName = "Customer services",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:60001/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:60001/signout-callback-oidc" },
ClientSecrets = new List<Secret>
{
new Secret("testsecret".Sha256())
},
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess,
"customerprivatelinesvn.api",
},
AllowOfflineAccess = true,
AlwaysIncludeUserClaimsInIdToken = true,
AllowedCorsOrigins = { "http://localhost:60001" }
});
これが私のクライアントアプリでの認証です( http:// localhost:60001 )。
private void AddAuthentication(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie()
.AddOpenIdConnect("oidc", options =>
{
Configuration.GetSection("OpenIdConnect").Bind(options);
});
}
"OpenIdConnect": {
"SignInScheme": "Cookies",
"Authority": "http://localhost:9000/",
"RequireHttpsMetadata": false,
"ClientId": "customer.api",
"ClientSecret": "testsecret",
"Scope": [ "customerprivatelinesvn.api", "offline_access" ],
"CallbackPath": "/signin-oidc",
"ResponseType": "code id_token token",
"GetClaimsFromUserInfoEndpoint": true,
"SaveTokens": true
}
クライアントアプリのHomeController
[Authorize]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
ユーザーがログインした後のクライアントアプリのCookieは次のとおりです。
以下のようにサインアウトアクションを実装しようとしています
public class AccountController : Controller
{
public async Task<IActionResult> Signout()
{
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
return RedirectToAction("Index", "Home");
}
}
ただし、ユーザーがサインアウトしても、IDサーバーのエンドセッションエンドポイントは呼び出されません。フィドラーのトラフィックを見ると、IDサーバーへのリクエストはありません。
私の期待は、ユーザーがサインアウトすると、IDサーバーのエンドセッションエンドポイントを呼び出し、以下のようにIDサーバーのログアウトリンクにリダイレクトすることです。
OwinContextサインアウトを呼び出すことで、MVCアプリケーションでこれを簡単に行うことができます
private void LogoutOwin(IOwinContext context)
{
context.Authentication.SignOut();
}
ただし、サインアウト方法はASP.NET Core2では機能しなくなりました。
注:クライアントアプリはAJAX 5アプリであるため、angular postからサインアウトアクションを呼び出しています。
ASP.NET Core 2でサインアウトを正しく実装する方法を知っている人はいますか?
どうもありがとうございました。
よろしく、
ケビン
私は今私の問題を解決することができます。
1)SignOutResultを返すと、エンドセッションエンドポイントが呼び出されます。
2)フォームを送信するためにAJAX投稿を変更します。
public class AccountController : Controller
{
public IActionResult Signout()
{
return new SignOutResult(new[] { "oidc", "Cookies" });
}
}
<form action="/Account/Signout" id="signoutForm" method="post" novalidate="novalidate">
<ul class="nav navbar-nav navbar-right">
<li><a href="javascript:document.getElementById('signoutForm').submit()">Sign out</a></li>
</ul>
</form>
サインアウトを許可するには、次のログアウトアクションを使用します。
_public async Task Logout()
{
await HttpContext.SignOutAsync("Cookies");
await HttpContext.SignOutAsync("oidc");
}
_
これはまさにクイックスタートが使用するように言っていることです( http://docs.identityserver.io/en/release/quickstarts/3_interactive_login.html )。あなた(そして私)は賢すぎました。チュートリアルのアクションを見て、「それは完了していません。アクションの結果が返されないので、自分のページにリダイレクトしてみましょう」と思いました。
実際に起こることは、HttpContext.SignOutAsync("oidc");
がデフォルトのActionResultを設定することです(これは、サインアウトを完了するためにOpenIdConnectプロバイダーにリダイレクトすることです)。 return RedirectToAction("Index", "Home");
で独自に指定することにより、これをオーバーライドするため、サインアウトアクションは発生しません。
この回答 から、ログアウトが完了した後にリダイレクトURLを指定する方法は、AuthenticationPropertiesを使用することです。
_public async Task Logout()
{
await context.SignOutAsync("Cookies");
var prop = new AuthenticationProperties
{
RedirectUri = "/logout-complete"
};
// after signout this will redirect to your provided target
await context.SignOutAsync("oidc", prop);
}
_
Net Core 2.0では、列挙型CookieAuthenticationDefaultsおよびOpenIdConnectDefaultsを使用するようにコードを変更します
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(SetOpenIdConnectOptions);
private static void SetOpenIdConnectOptions(OpenIdConnectOptions options)
{
options.ClientId = "auAuthApp_implicit";
options.Authority = "http://localhost:55379/";
options.SignInScheme = "Cookies";
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.ResponseType = "id_token token";
options.GetClaimsFromUserInfoEndpoint = true;
}
そして...
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
return RedirectToAction("Index", "Home");
}