2017-08-16 133 views
15

在使用Identity Server 4和ASP.NET Identity添加身份驗證功能後,我打算添加Google Provider,以便用戶還可以使用其Google +帳戶登錄。我使用Angular作爲我的前端,並使用ASP.NET Web Api(Core)作爲後端。使用Identity Server 4和ASP.NET Identity添加外部登錄

// Login client 
public login(email: string, password: string): Observable<any> { 
    let body: any = this.encodeParams({ /* cliend_id, grant_type, username, password, scope */ }); 

    return this.http.post("http://localhost:64023/connect/token", body, this.options) 
     .map((res: Response) => { 
      const body: any = res.json(); 
       if (typeof body.access_token !== "undefined") { 
        // Set localStorage with id_token,.. 
       } 
     }).catch((error: any) => { /**/); 
} 

// Register Web API 
[HttpPost("Create")] 
[AllowAnonymous] 
public async Task<IActionResult> Create([FromBody]CreateUserViewModel model) 
{ 
    var user = new ApplicationUser 
    { 
     FirstName = model.FirstName, 
     LastName = model.LastName, 
     AccessFailedCount = 0, 
     Email = model.Email, 
     EmailConfirmed = false, 
     LockoutEnabled = true, 
     NormalizedEmail = model.Email.ToUpper(), 
     NormalizedUserName = model.Email.ToUpper(), 
     TwoFactorEnabled = false, 
     UserName = model.Email 
    }; 

    var result = await _userManager.CreateAsync(user, model.Password); 

    if (result.Succeeded) 
    { 
     await addToRole(model.Email, "user"); 
     await addClaims(model.Email); 
    } 

    return new JsonResult(result); 
} 

// Identity Server Startup 
app.UseGoogleAuthentication(new GoogleOptions 
{ 
    AuthenticationScheme = "Google", 
    DisplayName = "Google", 
    SignInScheme = "Identity.External", 
    // ClientId, ClientSecret,.. 
}); 

用戶登錄後,localStorage被設置,我可以保護安全控制器。對於谷歌提供我增加了一個額外的按鈕,下面的方法:

initGoogleAPI() { 
    let self = this; 
    gapi.load('auth2', function() { 
     self.auth2 = gapi.auth2.init({ /* client_id, cookiepolicy, scope */ }); 
     self.externalLogin(document.getElementById('google-button')); 
    }); 
} 

externalLogin(element) { 
    let self = this; 
    this.auth2.attachClickHandler(element, {}, 
     function (googleUser) { 
      // retrieved the id_token, name, email,... 
     }, function (error) { 
     alert(JSON.stringify(error, undefined, 2)); 
    }); 
} 

我已經找到了幾個解決方案,但僅適用於MVC應用程序而不是使用客戶方框架SPA。接下來需要採取哪些步驟才能使外部登錄工作?當用戶首次使用外部提供商登錄時,是否需要在AspNetUsers表中創建新記錄?

回答

2

登錄名應該由identityServer4來處理。無論本地登錄還是第三方,它都會向Web應用程序返回類似的標記。

如果您需要Web API後端中的用戶數據,它應該作爲聲明傳遞。

IdentityServer4快速啓動可能對您的代碼有幫助,他們有一個External logins的示例,您將其添加到IdentityServer以及如何從JavaScript application執行登錄流程。

+0

不應該登錄由供應商來處理?選擇一個谷歌帳戶後,我從提供者生成的響應中檢索一個令牌,而不是由Identity Server生成。我已經按照您向我發送的指南進行了操作,但不幸的是,它沒有提供任何有關將外部提供者添加到與ASP.NET身份相結合的SPA的信息。 – Sam

+0

您正在從Identity Server和Google接收令牌,具體取決於登錄類型,它們可能不包含您需要的聲明。如果您的身份服務器允許Google登錄,那麼您的應用程序只會從Identity Server獲取一種令牌類型。 Identity Server仍然會將您傳遞給Google進行身份驗證,但它會在返回到您的應用程序之前返回到Identity Server。 –

3

你可以檢查這個存儲庫,你可以忽略ids4服務器項目,並檢查角客戶端你應該使用openid客戶端來做到這一點,然後客戶端被重定向到你登錄的ids4項目登錄頁面,並返回一個令牌你保存它,所以你以後可以使用它

https://github.com/nertilpoci/Aspnetcore-identityserver4-webapi-angular

https://github.com/nertilpoci/Aspnetcore-identityserver4-webapi-angular/tree/master/ClientApp

+0

感謝您分享該存儲庫。如果我沒有誤認爲用戶只能在使用提供者登錄到MVC視圖時才登錄,但如果我想在Angular組件中包含登錄表單和Google按鈕,會發生什麼情況。這不可能嗎? – Sam

+1

我認爲發送給權威的鏈接可以手動構建,因此它只指向谷歌身份驗證,但我沒有實現一個我自己,我會發布在這裏,如果我讓它工作。好問題 – user5195490