0

我正在嘗試編寫一個使用混合身份驗證方案的ASP.NET應用程序。 用戶可以將他的用戶名和密碼哈希存儲在UserStore中,或者他可以通過Azure Active Directory進行身份驗證。ASP.NET與OpenIdAuthentication:重定向到url如果未授權

我已創建圖片的登錄表單。它有標準的UserNamePassword輸入,但也有「通過Active Directory登錄」按鈕。

enter image description here

這很好。

現在問題:應用程序的主頁具有[Authorize]屬性。

public class DefaultController : Controller 
{ 
    [Authorize] 
    public ViewResult Index() 
    { 
    // Implementation 
    } 
} 

如果用戶沒有登錄,我希望它重定向到Account/Login頁面,允許用戶選擇身份驗證方法。

一旦我將IAppBuilder.UseOpenIdConnectAuthentication添加到管道設置,它不再重定向到該頁面。相反,它直接進入Microsoft登錄頁面。

如何配置它以便OpenID身份驗證是系統的一部分,但允許我指定如何在用戶未通過身份驗證時執行重定向?

這裏就是我建立了管道代碼:

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的簽到」,它發佈到 「賬號/ 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"); 
    } 
} 
+0

Azure中是否有任何終結點定義覆蓋你的uri? – 1392023093user

回答

0

通話到IAppBuilder.UseOpenIdConnectAuthentication(...)將一個Owin中間件組件放入管道中。當ASP.NET MVC返回401(未授權)的HttpResponse時,Owin中間件組件檢測到此並將其更改爲Http重定向(代碼302),並且重定向路徑指向Open Id提供程序。

但有一種方法可以解決這個問題:在中間件組件執行重定向之前,它會調用回調函數RedirectToIdentityProvider。從這裏,我可以覆蓋這個重定向。

這是我的代碼,覆蓋重定向,除非它是從請求路徑Account/SignInWithOpenId

var notificationHandlers = new OpenIdConnectAuthenticationNotificationHandlers 
{ 
    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); 
0

請嘗試移動UseOpenIdConnectAuthentication之前UseCookieAuthentication,那麼它會將用戶重定向到「登錄」頁面。

// Now the OpenId authentication 
var notificationHandlers = new OpenIdConnectAuthenticationNotificationHandlers 
{ 
    // Handler methods here 
} 
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); 

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); 

請讓我知道它是否有幫助。

更新:

或者你可以使用自定義授權屬性來覆蓋默認行爲,例如:

public class CustomAuthorizeAttribute: AuthorizeAttribute 
    { 
     public CustomAuthorizeAttribute(): base() 
     { 
     } 

     protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
     { 
      if (filterContext.HttpContext.Request.IsAuthenticated) 
      { 

      } 
      else 
      { 
       filterContext.HttpContext.Response.Redirect("Account/login"); 
      }    
     } 
    } 

然後,只需改變你使用情況:

[CustomAuthorize] 
public ActionResult Index() 
{ 
    return View(); 
} 
+0

它會將它重定向到登錄頁面,但它會破壞別的東西。我的通知處理程序之一是'AuthorizationCodeReceived',它從聲明中找出用戶,然後調用'SignInAsync'。出於某種原因,如果我不先調用UseCookieAuthentication,那麼SignInAsync就不起作用。 我將修改我的問題以顯示'AuthorizationCodeReceived'處理程序。 –

+0

那麼如何使用自定義授權屬性:公共類CustomAuthorizeAttribute:AuthorizeAttribute { 公共CustomAuthorizeAttribute():基地(){ } 保護覆蓋無效HandleUnauthorizedRequest(AuthorizationContext filterContext) { 如果(filterContext.HttpContext.Request .IsAuthentication) { } else { filterContext.HttpContext.Response.Redirect(「Account/login」); } } } –

+0

自定義授權屬性可以工作,但我寧願不替換ASP.NET MVC框架的其他部分。我設法想出了一個解決方案。 –

相關問題