2016-08-22 73 views
0

我正在使用IdentityServer3处理asp mvc网站中的用户身份验证。IdentityServer3:将手动凭据登录与社交选项结合

登录屏幕托管在应用程序本身的视图中(不使用Identity Server隐式流)。我还提供了“使用Google登录”选项,用户可以通过单击登录屏幕上的按钮来选择该选项。

具有任何页面[授权]应未经认证的用户重定向到登录屏幕:

public void Configuration(IAppBuilder app) 
    { 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = "Cookies", 
      LoginPath = new PathString("/Account/Login") 
     }); 
    } 

账户控制器概况如下所示。 “表单身份验证”方案将起作用(as described here)。

通过指定“acr_values”参数,“使用Google登录”按钮的作用为as described here(跳过ID服务器登录页面,直接转到Google)。

在我登录Google之后,我应该如何处理来自OpenID Connect的回调?我尝试添加OpenId Connect middleware,但它在Cookie身份验证中的'LoginPath'功能不能很好地发挥作用:未经身份验证的用户现在被重定向到ID Server登录屏幕,而不是本地登录屏幕。

我在IdentityServer samples中看不到任何解决此情况的任何内容。

public class AccountController : Controller 
{ 
    [HttpGet] 
    public ActionResult Login() 
    { 
     ViewBag.GoogleLogin = CreateLoginUrl("Google"); 

     return View(); 
    } 

    [HttpPost] 
    public ActionResult Login(LoginViewModel vm) 
    { 
     // Call IdentityServer here with credentials 
     // Validate token and do the Owin Authentication SignIn 
     // Redirect to 'ReturnUrl' 

     // If errors: 
     return View(vm); 
    } 

    public ActionResult Callback() 
    { 
     // What goes here?? 

     return new RedirectResult("/"); 
    } 

    private string CreateLoginUrl(string provider) 
    { 
     var state = Guid.NewGuid().ToString("N"); 
     var nonce = Guid.NewGuid().ToString("N"); 

     var request = new AuthorizeRequest(new Uri("https://localhost:44312/connect/authorize")); 
     var startUrl = request.CreateAuthorizeUrl(
        clientId: "mvc", 
        responseType: "id_token token", 
        scope: "openid profile roles sampleApi", 
        redirectUri: "https://localhost:44319/Account/Callback", 
        state: state, 
        acrValues: "idp:" + provider, 
        nonce: nonce); 

     return startUrl; 
    } 
} 

回答

0

我用地图IAppBuilder扩展仅适用公开识别中间件连接到单个端点回避矛盾的认证供应商的问题。通过这种方式,社交登录流程完全由中间件处理,认证cookie由两个认证提供者共享。

public void Configuration(IAppBuilder app) 
{ 
    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = "Cookies", 
     LoginPath = new PathString("/Account/Login") 
    }); 
    app.Map(new PathString("/Account/SocialLogin"), ctx => 
    { 
     ctx.UseOpenIdConnectAuthentication(Options()); 
    }); 
} 

而且的AccountController位:

public class AccountController : Controller 
{ 
    [HttpGet] 
    public ActionResult Login(string returnUrl) 
    { 
     return View(new LoginViewModel { ReturnUrl = returnUrl }); 
    } 

    [HttpPost] 
    public async Task<ActionResult> Login(LoginViewModel vm) 
    { 
     if (!ModelState.IsValid) 
     { 
      return View(vm); 
     } 

     // Call IdentityServer here with credentials 
     TokenResponse token = await GetToken(vm.UserName, vm.Password); 

     // Validate token and do the Owin Authentication SignIn 
     // Redirect to 'ReturnUrl' 

     await SignInAsync(token); 

     return new RedirectResult(vm.ReturnUrl); 
    } 

    [Authorize] 
    public ActionResult SocialLogin(string returnUrl) 
    { 
     return new RedirectResult(returnUrl); 
    } 

    // Some helpers omitted 
}