1

我已經設置了我的ASP Net Core 2.0項目以使用Azure AD進行身份驗證(在使用OIDC的VS2017中使用標準Azure AD身份驗證模板)。一切工作正常,應用程序返回到基地址(/)並在驗證成功後運行HomeController.Index操作。如何在Azure AD身份驗證之後重定向到ASP中的其他控制器操作Net Core MVC

但是我現在想在驗證後重定向到不同的控制器操作(AccountController.CheckSignIn),以便我可以檢查用戶是否已經存在於我的本地數據庫表中,如果不存在(即它是新用戶)用戶記錄,然後重定向到HomeController.Index操作。

我可以把這個檢查放在HomeController.Index操作本身,但我想避免每次用戶單擊主頁按鈕時運行此檢查。

這裏有一些代碼片段可能有助於讓清晰......在appsettings.json

AAD設置

"AzureAd": { 
    "Instance": "https://login.microsoftonline.com/", 
    "Domain": "<my-domain>.onmicrosoft.com", 
    "TenantId": "<my-tennant-id>", 
    "ClientId": "<my-client-id>", 
    "CallbackPath": "/signin-oidc" // I don't know where this goes but it doesn't exist anywhere in my app and authentication fails if i change it 
} 

我添加了一個新的動作,我AccountController.CheckSignIn來處理這一要求,但我在認證後找不到方法來調用它。

public class AccountController : Controller 
{ 
    // I want to call this action after authentication is successful 
    // GET: /Account/CheckSignIn 
    [HttpGet] 
    public IActionResult CheckSignIn() 
    { 
     var provider = OpenIdConnectDefaults.AuthenticationScheme; 
     var key = User.FindFirstValue(ClaimTypes.NameIdentifier); 
     var info = new ExternalLoginInfo(User, provider, key, User.Identity.Name); 
     if (info == null) 
     { 
      return BadRequest("Something went wrong"); 
     } 

     var user = new ApplicationUser { UserName = User.Identity.Name }; 
     var result = await _userManager.CreateAsync(user); 
     if (result.Succeeded) 
     { 
      result = await _userManager.AddLoginAsync(user, info); 
      if (!result.Succeeded) 
      { 
       return BadRequest("Something else went wrong"); 
      } 
     } 

     return RedirectToAction(nameof(HomeController.Index), "Home"); 
    } 

    // This action only gets called when user clicks on Sign In link but not when user first navigates to site 
    // GET: /Account/SignIn 
    [HttpGet] 
    public IActionResult SignIn() 
    { 
     return Challenge(
      new AuthenticationProperties { RedirectUri = "/Account/CheckSignIn" }, OpenIdConnectDefaults.AuthenticationScheme); 
    } 

} 

回答

1

我已經找到一種方法,使之通過使用重定向如下工作...

內啓動

app.UseMvc(routes => 
{ 
    routes.MapRoute(
     name: "default", 
     template: "{controller=Account}/{action=SignIn}/{id?}"); 
}); 

裏面的AccountController

// GET: /Account/CheckSignIn 
[HttpGet] 
[Authorize] 
public IActionResult CheckSignIn() 
{ 
    //add code here to check if AzureAD identity exists in user table in local database 
    //if not then insert new user record into local user table 

    return RedirectToAction(nameof(HomeController.Index), "Home"); 
} 

// 
// GET: /Account/SignIn 
[HttpGet] 
public IActionResult SignIn() 
{ 
    return Challenge(
     new AuthenticationProperties { RedirectUri = "/Account/CheckSignIn" }, OpenIdConnectDefaults.AuthenticationScheme); 
} 

內AzureAdServiceCollectionExtensions(.NET核心2.0)

private static Task RedirectToIdentityProvider(RedirectContext context) 
{ 
    if (context.Request.Path != new PathString("/")) 
    { 
     context.Properties.RedirectUri = new PathString("/Account/CheckSignIn"); 
    } 
    return Task.FromResult(0); 
} 
+0

似乎你主張爲正確的工作使用正確的工具,我喜歡它。 – JasonInVegas

1

默認行爲是:用戶將被重定向到原始頁面。例如,用戶未通過身份驗證並訪問索引頁面,經過身份驗證後,他將被重定向到索引頁面;用戶未通過身份驗證並訪問聯繫頁面,經過身份驗證後,他將被重定向到聯繫人頁面。

作爲一種變通方法,您可以修改默認網站路線用戶重定向到特定的控制器/動作:

app.UseMvc(routes => 
{ 
    routes.MapRoute(
     name: "default", 
     template: "{controller=Account}/{action=CheckSignIn}/{id?}" 
    ); 
}); 

您的定製邏輯後,您可以重定向用戶到你的真正的默認頁面(首頁/索引) 。

+0

我喜歡這種方法,因爲它的簡單性,但如果用戶加載一個特定的頁面(即家庭/聯繫人)會怎麼樣。我如何確保直接加載Home/Contact頁面時首先調用Account/CheckSignIn動作? – OjM

+0

您是否使用[授權]屬性來保護您的控制器或操作?如果您使用該功能,則應將其重定向到azure廣告登錄頁面,經過身份驗證後,他將被重定向到Account/CheckSignIn。 –

+0

是的,我正在使用[授權]屬性。問題是,如果我已經顯示了默認路由設置,那麼這種方法只適用於我加載默認網站(即mysite.com)。但是,如果我輸入url mysite.com/Home/關於默認路由被繞過並且帳戶/簽名簽名從不被調用。有沒有辦法解決? – OjM

相關問題