2011-02-26 30 views
11

Tôi biết có những câu hỏi khác về vấn đề này, nhưng chúng đã lỗi thời và tôi không thể tìm thấy câu trả lời đáng tin cậy ở bất cứ đâu.Giải pháp OpenID nào thực sự được sử dụng bởi Stack Overflow?

Điều gì thực sự được sử dụng bởi Stack   Tràn cho người dùng autentificate? Các trang web DotNetOpenAuth tuyên bố nó được. Nhưng đối với tôi, hình ảnh tương tự nhất (trực quan) trông giống như OAuth C# Library.

Vì vậy, nó thực sự sử dụng những gì? Hoặc làm thế nào tôi có thể bắt chước cùng một giao diện người dùng?

Tôi muốn tạo xác thực OpenID rất giống nhau bằng ASP.NET MVC.

+0

Tôi cảm thấy câu hỏi này cần loại nhận xét đặc biệt. Kể từ khi nó được hỏi nó đã được yêu cầu nó đã chuyển đến StackOverflow meta, sau đó trở lại chính StackOverflow, để meta một lần nữa và trở lại chính. Cảm thấy như nó thuộc về cả hai trang web hoặc không phải của họ có lẽ? Tôi tin rằng nó thuộc về chính StackOverflow, nơi tôi đăng nó ban đầu. Đó là bởi vì tôi đã không yêu cầu vì tò mò về trang web SO chính nó, nhưng bởi vì tôi muốn sử dụng cùng một giải pháp, cùng một công nghệ. Vì vậy câu trả lời của Lirick là câu trả lời tuyệt vời cho câu hỏi của tôi nhưng câu trả lời như vậy không có gì để làm trên meta (quá kỹ thuật) và do đó, nó ở lại đây. – drasto

Trả lời

17

StackOverflow sử dụng DotNetOpenAuth.

Từ blog:

nhưng may mắn thay, chúng tôi có một hộp thoại xuất sắc với Andrew Arnott, tác giả chính của mã nguồn mở DotNetOpenAuth thư viện chúng tôi sử dụng

15

tôi đã có thể để có được xác thực OpenID với DotNetOpenAuth trên trang web của tôi (www.mydevarmy.com) trong một thời gian khá ngắn (lưu ý rằng tôi là tổng số noob cho ASP.NET, MVC, DotNetOpenAuth, v.v.).

DotNetOpenAuth đi kèm với các mẫu khác nhau và họ thậm chí có một mẫu ASP.NET MVC, nhưng họ chỉ cung cấp một View và Controller trong mẫu đó và họ không thực sự có một mô hình đó là M trong MVC :) . Sau đó tôi hỏi những câu dưới đây trên SO:

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

Vì vậy, làm thế nào một RẤT ĐƠN GIẢN OpenID đăng nhập nhìn như trong MVC? Vâng, chúng ta hãy nhìn ...

1. Bạn sẽ cần một mô hình:

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. Bạn sẽ cần một bộ điều khiển:

[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. Bạn sẽ cần một chế độ xem:

<%@ 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> 

Lưu ý rằng tôi chưa cung cấp cho bạn chế độ xem Profile, nhưng điều đó phải đủ đơn giản để tìm ra.

+0

Cảm ơn bạn vì điều này! Đây là câu trả lời rất hay!Tôi sẽ thử nó và nếu nó hoạt động bạn nên viết điều này vào blog của bạn nếu bạn có một số. Hy vọng rằng điều này đã được bình chọn lên nhiều hơn nữa. Tôi phải chấp nhận của Oded andwer bởi vì tôi đã promissed đó. – drasto

+0

@drasto, không sao cả ... Tôi không quan tâm đến việc kiếm điểm trên meta và Oded có nhiều phiếu bầu hơn nữa. Tôi chỉ hy vọng điều này hữu ích :) – Kiril

+1

@drasto, tôi đã tạo một bài đăng blog về điều này: http://codesprout.blogspot.com/2011/03/using-dotnetopenauth-to-create-simple.html – Kiril

Các vấn đề liên quan