2009-07-27 64 views
5

我正在使用MVC Storefront中的以下代碼來測試MVC中的OpenId。 如何將其與我的ASP.Net成員資格集成,以便我可以使用角色併爲我的表中的用戶保存用戶名?我相信SO也使用類似的東西。如何將OpenId與MVC中的ASP.Net成員集成

public ActionResult OpenIdLogin() 
    { 
     string returnUrl = VirtualPathUtility.ToAbsolute("~/"); 
     var openid = new OpenIdRelyingParty(); 
     var response = openid.GetResponse(); 
     if (response == null) 
     { 
      // Stage 2: user submitting Identifier 
      Identifier id; 
      if (Identifier.TryParse(Request["openid_identifier"], out id)) 
      { 
       try 
       { 
        IAuthenticationRequest req = openid.CreateRequest(Request["openid_identifier"]); 

        var fetch = new FetchRequest(); 
        //ask for more info - the email address 
        var item = new AttributeRequest(WellKnownAttributes.Contact.Email); 
        item.IsRequired = true; 
        fetch.Attributes.Add(item); 
        req.AddExtension(fetch); 

        return req.RedirectingResponse.AsActionResult(); 
       } 
       catch (ProtocolException ex) 
       { 
        ViewData["Message"] = ex.Message; 
        return View("Logon"); 
       } 
      } 
      else 
      { 
       ViewData["Message"] = "Invalid identifier"; 
       return View("Logon"); 
      } 
     } 
     else 
     { 
      // Stage 3: OpenID Provider sending assertion response 
      switch (response.Status) 
      { 
       case AuthenticationStatus.Authenticated: 

        var fetch = response.GetExtension<FetchResponse>(); 
        string name = response.FriendlyIdentifierForDisplay; 
        if (fetch != null) 
        { 
         IList<string> emailAddresses = fetch.Attributes[WellKnownAttributes.Contact.Email].Values; 
         string email = emailAddresses.Count > 0 ? emailAddresses[0] : null; 
         //don't show the email - it's creepy. Just use the name of the email 
         name = email.Substring(0, email.IndexOf('@')); 
        } 
        else 
        { 

         name = name.Substring(0, name.IndexOf('.')); 
        } 

        //FormsAuthentication.SetAuthCookie(name, false); 
        SetCookies(name, name); 
        AuthAndRedirect(name, name); 

        if (!string.IsNullOrEmpty(returnUrl)) 
        { 
         return Redirect(returnUrl); 
        } 
        else 
        { 
         return RedirectToAction("Index", "Home"); 
        } 
       case AuthenticationStatus.Canceled: 
        ViewData["Message"] = "Canceled at provider"; 
        return View("Logon"); 
       case AuthenticationStatus.Failed: 
        ViewData["Message"] = response.Exception.Message; 
        return View("Logon"); 
      } 
     } 
     return new EmptyResult(); 

    } 

    ActionResult AuthAndRedirect(string userName, string friendlyName) 
    { 
     string returnUrl = Request["ReturnUrl"]; 
     SetCookies(userName, friendlyName); 

     if (!String.IsNullOrEmpty(returnUrl)) 
     { 
      return Redirect(returnUrl); 
     } 
     else 
     { 
      return RedirectToAction("Index", "Home"); 
     } 
    } 

回答

6

有像StackOverflow已經存在的幾個問題。 This one看起來特別相似。

如果您已經在您的網站中使用了會員提供商,並且只是在其中添加OpenID,那麼我想您現在已經被會員卡住了,並且可以使用我鏈接到的問題的答案之一來獲取一個半體面的會員供應商,可以爲你工作。如果你正在編寫一個新的站點,並且只是想像你說的那樣在用戶的角色中使用角色併爲用戶保存一個用戶名,那麼請不要使用ASP.NET Membership。這是不值得的!它不適合OpenID的無密碼範例,只會導致更多的悲傷。如果你不擔心自己的數據庫訪問,那就這樣做吧。只需發出您自己的FormsAuthentication.RedirectFromLoginPageFormsAuthentication.SetAuthCookie呼叫並傳遞用戶填寫的角色,您就可以非常輕鬆地獲得角色行爲。

+0

我正在玩一個新的實現,所以我不特別嫁給ASP.NET會員。您能否以您提及的方式提示示例代碼? – Picflight 2009-07-27 16:32:22

1

開放標識提供程序將返回有關用戶的數據。如果您不要求/需要特定的信息標記,那麼您將獲得的所有信息都是用戶的顯示名稱和標識URL。

根據您使用的開放id庫的不同,您可以請求令牌如FirstName LastName,DOB(如果您真的關心),並且用戶提供了有關其所選身份的信息,則會返回到您。

然後,您可以使用它在會員系統中創建一個新用戶。您可能必須給他們一個虛擬密碼來解決Membership API的需求。

要驗證登錄,請提供1個表單,其中需要用戶名爲&的密碼,另一個表單需要身份網址。在通過開放標識驗證用戶之後,請嘗試通過Membership API中的用戶名(標識url)來查找用戶。如果它不存在,請創建它。