2011-02-26 24 views
11

我知道还有其他的问题,但他们已经过时了,我找不到在任何地方都可靠的答案。Stack Overflow真的使用了什么OpenID解决方案?

Stack实际使用的是什么 溢出到aunttificate用户?该网站DotNetOpenAuth声称是。但对我来说,最(看起来)类似的看起来是OAuth C# Library

那它真的用了什么?或者我如何模仿相同的用户界面?

我想创建使用ASP.NET MVC的相同的OpenID身份验证。

+0

我觉得这个问题需要特殊的评论。既然有人问到它被问到它已经移到了StackOverflow meta,然后又回到了主StackOverflow,再次回到了meta并回到了main。感觉它是属于这两个网站还是非属于他们?我相信它属于StackOverflow主,我最初发布它。那是因为我没有要求,因为对SO网站本身的好奇心,而是因为我想使用相同的解决方案,相同的技术。因此,Lirick的回答对我的问题是很好的答案,但这样的回答在元(技术上)上没有任何关系,所以它留在这里。 – drasto 2011-08-05 22:55:39

回答

17

StackOverflow使用DotNetOpenAuth

blog

,但幸运的是我们有安德鲁·阿诺特,我们使用

15

我能得到OpenID身份验证与开源DotNetOpenAuth库的主要作者一个很好的对话我的网站(www.mydevarmy.com)在相当短的时间内(请注意,我总共为noob到ASP.NET,MVC,DotNetOpenAuth等)的DotNetOpenAuth

DotNetOpenAuth配备了各种样品,他们甚至有一个ASP.NET MVC的样品,但它们只提供样品中的视图和控制器,他们实际上并没有一个模型,它是中号在MVC :) 。后来我问的SO以下问题:

What are the responsibilities of the components in an MVC pattern for a simple login

因此,如何将一个很简单 OpenID登录样子的MVC?好吧,让我们来看看...

1.您将需要一个型号:

public class User 
{ 
    [DisplayName("User ID")] 
    public int UserID{ get; set; } 

    [Required] 
    [DisplayName("OpenID")] 
    public string OpenID { get; set; } 
} 

public class FormsAuthenticationService : IFormsAuthenticationService 
{ 
    public void SignIn(string openID, bool createPersistentCookie) 
    { 
     if (String.IsNullOrEmpty(openID)) throw new ArgumentException("OpenID cannot be null or empty.", "OpenID"); 

     FormsAuthentication.SetAuthCookie(openID, createPersistentCookie); 
    } 

    public void SignOut() 
    { 
     FormsAuthentication.SignOut(); 
    } 
} 

2.您将需要一个控制器:

[HandleError] 
public class UserController : Controller 
{ 
    private static OpenIdRelyingParty openid = new OpenIdRelyingParty(); 
    public IFormsAuthenticationService FormsService { get; set; } 

    protected override void Initialize(RequestContext requestContext) 
    { 
     if (FormsService == null) 
     { 
      FormsService = new FormsAuthenticationService(); 
     } 

     base.Initialize(requestContext); 
    } 

    // ************************************** 
    // URL: /User/LogIn 
    // ************************************** 
    public ActionResult LogIn() 
    { 
     if (User.Identity.IsAuthenticated) 
     { 
      return RedirectToAction("Profile", "User"); 
     } 

     Identifier openID; 
     if (Identifier.TryParse(Request.QueryString["dnoa.userSuppliedIdentifier"], out openID)) 
     { 
      return LogIn(new User { OpenID = openID }, Request.QueryString["ReturnUrl"]); 
     } 
     else 
     { 
      return View(); 
     } 
    } 

    [HttpPost] 
    public ActionResult LogIn(User model, string returnUrl) 
    { 
     string openID = ModelState.IsValid?model.OpenID:Request.Form["openid_identifier"]; 

     if (User.Identity.IsAuthenticated) 
     { 
      return RedirectToAction("Profile", "User"); 
     } 
     else if (!string.IsNullOrEmpty(openID)) 
     { 
      return Authenticate(openID, returnUrl); 
     } 
     else if(ModelState.IsValid) 
     { 
      ModelState.AddModelError("error", "The OpenID field is required."); 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

    // ************************************** 
    // URL: /User/LogOut 
    // ************************************** 
    public ActionResult LogOut() 
    { 
     if (User.Identity.IsAuthenticated) 
     { 
      FormsService.SignOut(); 
     } 

     return RedirectToAction("Index", "Home"); 
    } 

    // ************************************** 
    // URL: /User/Profile 
    // ************************************** 
    [Authorize] 
    public ActionResult Profile(User model) 
    { 
     if (User.Identity.IsAuthenticated) 
     { 
      // ------- YOU CAN SKIP THIS SECTION ---------------- 
      model = /*some code to get the user from the repository*/; 

      // If the user wasn't located in the database 
      // then add the user to our database of users 
      if (model == null) 
      { 
       model = RegisterNewUser(User.Identity.Name); 
      } 
      // -------------------------------------------------- 

      return View(model); 
     } 
     else 
     { 
      return RedirectToAction("LogIn"); 
     } 
    } 

    private User RegisterNewUser(string openID) 
    { 
     User user = new User{OpenID = openID}; 

     // Create a new user model 

     // Submit the user to the database repository 

     // Update the user model in order to get the UserID, 
     // which is automatically generated from the DB. 
     // (you can use LINQ-to-SQL to map your model to the DB) 

     return user; 
    } 

    [ValidateInput(false)] 
    private ActionResult Authenticate(string openID, string returnUrl) 
    { 
     var response = openid.GetResponse(); 
     if (response == null) 
     { 
      // Stage 2: user submitting Identifier 
      Identifier id; 
      if (Identifier.TryParse(openID, out id)) 
      { 
       try 
       { 
        return openid.CreateRequest(openID).RedirectingResponse.AsActionResult(); 
       } 
       catch (ProtocolException ex) 
       { 
        ModelState.AddModelError("error", "Invalid OpenID."); 

        ModelState.AddModelError("error", ex.Message); 
        return View("LogIn"); 
       } 
      } 
      else 
      { 
       ModelState.AddModelError("error", "Invalid OpenID."); 
       return View("LogIn"); 
      } 
     } 
     else 
     { 
      // Stage 3: OpenID Provider sending assertion response 
      switch (response.Status) 
      { 
       case AuthenticationStatus.Authenticated: 
        Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay; 
        FormsAuthentication.SetAuthCookie(response.FriendlyIdentifierForDisplay, true); 
        if (!string.IsNullOrEmpty(returnUrl)) 
        { 
         return Redirect(returnUrl); 
        } 
        else 
        { 
         return RedirectToAction("Profile", "User"); 
        } 
       case AuthenticationStatus.Canceled: 
        ModelState.AddModelError("error", "Authentication canceled at provider."); 
        return View("LogIn"); 
       case AuthenticationStatus.Failed: 
        ModelState.AddModelError("error", "Authentication failed: " + response.Exception.Message); 
        return View("LogIn"); 
      } 
     } 
     return new EmptyResult(); 
    } 
} 

3。您需要查看:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<YourProject.Models.User>" %> 

<asp:Content ID="loginTitle" ContentPlaceHolderID="TitleContent" runat="server"> 
    Log in - YourWebSiteName 
</asp:Content> 
<asp:Content ID="loginContent" ContentPlaceHolderID="MainContent" runat="server"> 
     <p> 
      <%--- If you have a domain, then you should sign up for an affiliate id with MyOpenID or something like that ---%> 
      Please log in with your OpenID or <a href="https://www.myopenid.com/signup?affiliate_id=????">create an 
       OpenID with myOpenID</a> if you don't have one. 
     </p> 
     <% 
     string returnURL = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]); 
     if (returnURL == null) 
     { 
      returnURL = string.Empty; 
     } 

     using (Html.BeginForm("LogIn", "User", returnURL)) 
     {%> 
      <%= Html.LabelFor(m => m.OpenID)%>: 
      <%= Html.TextBoxFor(m => m.OpenID)%> 
      <input type="submit" value="Log in" /> 
     <% 
     } %> 

     <%--- Display Errors ---%> 
     <%= Html.ValidationSummary()%> 
</asp:Content> 

请注意,我没有为您提供Profile视图,但该视图应该足够简单。

+0

谢谢!这是非常好的答案!我会尝试它,如果它有效,你应该写这个到你的博客,如果你碰巧有一些。希望这会得到更多的投票。我必须接受Oded的权威,因为我已经承诺过。 – drasto 2011-02-27 08:59:34

+0

@drasto,没问题...我不是那么有兴趣在meta上获得积分,而Oded反正有更多的选票。我只是希望这有助于:) – Kiril 2011-02-27 11:23:37

+1

@drasto,我创建了一篇关于此的博客文章:http://codesprout.blogspot.com/2011/03/using-dotnetopenauth-to-create-simple.html – Kiril 2011-03-06 20:35:07