問題描述
我正在嘗試編寫一個使用混合身份驗證方案的 ASP.NET 應用程序.用戶可以將其用戶名和密碼哈希存儲在 UserStore 中,也可以通過 Azure Active Directory 進行身份驗證.
I am attempting to write an ASP.NET application that uses a hybrid authentication scheme. A user can either have his username and password hash stored in the UserStore, or he can authenticate via Azure Active Directory.
我已經創建了如圖所示的登錄表單.它具有標準的 UserName
和 Password
輸入,還具有通過 Active Directory 登錄"按鈕.
I have created the login form pictured. It has the standard UserName
and Password
inputs, but also has a "Login via Active Directory" button.
這很好用.
現在解決問題:應用程序的主頁具有 [Authorize]
屬性.
Now for the problem: The application's home page has the [Authorize]
attribute.
public class DefaultController : Controller
{
[Authorize]
public ViewResult Index()
{
// Implementation
}
}
如果用戶沒有登錄,我希望它重定向到頁面Account/Login
,讓用戶選擇認證方式.
If the user is not logged in, I want it to redirect to the page Account/Login
, allowing the user to choose the authentication method.
將 IAppBuilder.UseOpenIdConnectAuthentication
添加到管道設置后,它不再重定向到該頁面.相反,它直接進入 Microsoft 登錄頁面.
Once I added IAppBuilder.UseOpenIdConnectAuthentication
to the pipeline setup, it no longer redirects to that page. Instead, it goes straight to the Microsoft Login page.
我如何配置它以使 OpenID 身份驗證成為系統的一部分,但允許我指定在用戶未通過身份驗證時如何執行重定向?
How do I configure it so that OpenID authentication is part of the system, but allow me to specify how to perform redirections when the user is not authenticated?
這是我設置管道的代碼:
Here's the code where I set up the pipeline:
appBuilder.SetDefaultSignInAsAuthticationType(CookieAuthenticationDefaults.AuthenticationType_;
var cookieAuthenticationOptions = new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationType.ApplicationCookie,
LoginPath = new Microsoft.Owin.PathString("/Account/Login"),
Provider = new Security.CookieAuthenticationProvider()
};
appBuilder.UseCookieAuthentication(cookieAuthenticationOptions);
// Now the OpenId authentication
var notificationHandlers = new OpenIdConnectAuthenticationNotificationHandlers
{
AuthorizationCodeReceived = async(context) => {
var jwtSecurityToken = context.JwtSecurityToken;
// I've written a static method to convert the claims
// to a user
var user = await GetOrCreateUser(context.OwinContext, jwtSecurityToken.Claims);
var signInManager = context.OwinContext.Get<SignInManager>();
await signInManager.SignInAsync(user, true, false);
}
}
var openIdOptions = new OpenIdConnectAuthenticationOptions
{
ClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx",
Authority = "https://login.microsoftonline.com/xxxxx.onmicrosoft.com",
PostLogoutRedirectUri = "https://localhost:52538/Account/Login",
Notifications = notifcationHandlers
}
appBuilder.UseOpenIdConnectAuthentication(openIdOptions);
當您單擊Active Directory 登錄"時,它會發布到Account/SignInWithOpenId"
When you click "Active Directory Signin", it posts to "Account/SignInWithOpenId"
public ActionResult SignInWithOpenId()
{
// Send an OpenID Connect sign-in request.
if (!Request.IsAuthenticated)
{
var authenticationProperties = new AuthenticationProperties
{
RedirectUri = "/"
};
HttpContext.GetOwinContext().Authentication.Challenge
(
authenticationProperties,
OpenIdConnectAuthenticationDefaults.AuthenticationType
);
return new EmptyResult();
}
else
{
return RedirectToAction("Index", "Default");
}
}
推薦答案
對 IAppBuilder.UseOpenIdConnectAuthentication(...)
的調用將 Owin 中間件組件放入管道中.當 ASP.NET MVC 返回 401(未授權)的 HttpResponse 時,Owin 中間件組件會檢測到這一點并將其更改為 Http Redirect(代碼 302),并且重定向路徑是 Open Id 提供程序.
The call to IAppBuilder.UseOpenIdConnectAuthentication(...)
puts an Owin middleware component in the pipeline. When ASP.NET MVC returns an HttpResponse of 401 (Unauthorized), the Owin Middleware component detects this and changes it to an Http Redirect (code 302), and the redirection path is to the Open Id provider.
但是有一種方法可以解決這個問題:在中間件組件執行重定向之前,它會調用回調 RedirectToIdentityProvider
.從這里,您可以覆蓋此重定向.
But there's a way to get around this: before the middleware component performs the redirect, it invokes the callback RedirectToIdentityProvider
. From here, you can override this redirection.
這是我的代碼,它會覆蓋重定向,除非它來自請求路徑 Account/SignInWithOpenId
.
Here is my code that overrides the redirection unless it is from the request path Account/SignInWithOpenId
.
var notificationHandlers = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async(context) => {
// Sign in the user here
},
RedirectToIdentityProvider = (context) => {
if(context.OwinContext.Request.Path.Value != "/Account/SignInWithOpenId")
{
context.OwinContext.Response.Redirect("/Account/Login");
context.HandleResponse();
}
return Task.FromResult(0);
}
}
var openIdOptions = new OpenIdConnectAuthenticationOptions
{
ClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx",
Authority = "https://login.microsoftonline.com/xxxxx.onmicrosoft.com",
PostLogoutRedirectUri = "https://localhost:52538/Account/Login",
Notifications = notifcationHandlers
}
appBuilder.UseOpenIdConnectAuthentication(openIdOptions);
這篇關于帶有 OpenIdAuthentication 的 ASP.NET:如果未授權,則重定向到 url的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!