2011-02-26 23 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