2009-07-27 67 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)来查找用户。如果它不存在,请创建它。