2011-02-26 9 views
11

Wiem, że są inne pytania na ten temat, ale są one nieaktualne i nie mogę znaleźć odpowiedzi, która byłaby wiarygodna w dowolnym miejscu.Jakie rozwiązanie OpenID jest naprawdę używane w Stack Overflow?

Co tak naprawdę używa Stack   Przepełnienie do użytkowników autentifikacji? Strona twierdzi, że jest. Ale dla mnie najbardziej (wizualnie) podobny wygląda być OAuth C# Library.

Więc, czego tak naprawdę używa? Lub w jaki sposób mogę naśladować ten sam interfejs użytkownika?

Chcę utworzyć to samo uwierzytelnianie OpenID przy użyciu MVC ASP.NET.

+0

Uważam, że to pytanie wymaga specjalnego komentarza. Ponieważ został zapytany, został poproszony o przeniesienie do Meta StackOverflow, a następnie powrót do głównego StackOverflow, do meta ponownie i powrót do głównej. Wygląda na to, że należy do obu stron, a może nie? Uważam, że należy on do głównej wersji StackOverflow, w której opublikowałem ją pierwotnie. To dlatego, że nie pytałem z powodu ciekawości samej strony SO, ale dlatego, że chciałem użyć tego samego rozwiązania, tej samej technologii. Dlatego odpowiedź Liricka jest świetną odpowiedzią na moje pytanie, ale taka odpowiedź nie ma nic wspólnego z meta (zbyt techniczna) i dlatego zostaje tutaj. – drasto

Odpowiedz

17

StackOverflow używa DotNetOpenAuth.

Z blog:

ale na szczęście mamy doskonały dialog z Andrew Arnott, pierwotnego autora open source DotNetOpenAuth biblioteki używamy

15

udało mi się dostać uwierzytelniania OpenID z DotNetOpenAuth na mojej stronie internetowej (www.mydevarmy.com) w dość krótkim czasie (zauważ, że jestem w sumie noob do ASP.NET, MVC, DotNetOpenAuth, itp.).

DotNetOpenAuth pochodzi z różnych próbek i mają nawet próbkę ASP.NET MVC, ale stanowią one tylko widok i kontroler w tej próbce i nie mamy model, który jest M w MVC :) . Następnie poprosiłem następujące pytanie na SO:

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

Więc jak by bardzo prosty logowanie z OpenID wygląda w MVC? Dobrze, rzućmy okiem ...

1. Musisz Model:

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. Musisz Kontroler:

[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ędziesz potrzebować widoku:

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

Należy zauważyć, że nie dostarczyłem Ci widoku Profile, ale powinno to być wystarczająco proste, aby dowiedzieć się.

+0

Dziękuję za to! To jest bardzo dobra odpowiedź!Spróbuję i jeśli to zadziała, powinieneś napisać to na swoim blogu, jeśli masz jakieś. Mam nadzieję, że zostało to jeszcze bardziej głosowane. Muszę zaakceptować wypowiedź Odeda, ponieważ już to obiecałem. – drasto

+0

@drasto, nie ma problemu ... Nie jestem zainteresowany zdobywaniem punktów na meta, a Oded ma więcej głosów w górę. Mam nadzieję, że to pomoże :) – Kiril

+1

@drasto, Stworzyłem post na blogu na ten temat: http://codesprout.blogspot.com/2011/03/using-dotnetopenauth-to-create-simple.html – Kiril

Powiązane problemy