2013-08-17 79 views
12

我想設置DotNetOpenAuth示例以具有自定義提供程序的工作SSO解決方案。我使用OpenIdProviderMvc示例項目似乎工作正常。Dotnetopenauth單點登錄自定義身份提供商

我的問題是設置「消費者」,在這種情況下OpenIdRelyingPartyMvc示例項目,我不能配置它使用OpenIdProvider。

我試圖建立這樣對消費者的web.config端點:

<trustedProviders rejectAssertionsFromUntrustedProviders="true"> 
    <add endpoint="http://localhost:4864/OpenID/Provider" /> 
</trustedProviders> 

但我得到的是「沒有OpenID端點發現。」錯誤(實際上,我不太確定要在OpenID框上放什麼......)

該項目幾乎沒有文檔記錄。有人能指引我朝着正確的方向嗎?

至少有一個提供者和消費者工作和互相交談?

+0

對於它的價值:我遇到了在運行樣本沒問題(https://github.com/DotNetOpenAuth/DotNetOpenAuth)。在盒子的OpenID 4864:我並沒有取消對值得信賴的供應商部分,在VS啓動兩個實例的服務器和客戶端以及剛剛進入的http://本地主機。默認情況下,我猜測示例客戶端會接受任何openId提供程序。 – jbl

回答

7

讓我們開始:

1-打開Visual Studio 2010轉到文件>新建>項目>網絡> ASP.NET MVC 3應用:

enter image description here

然後選擇互聯網應用肯定有剃刀爲您的視圖引擎,然後單擊確定:

enter image description here

2- Download Assets folder,它包含DotNetOpenAuth DLL和OpenID的選擇文件,我們將使用,

如果你想要去這些項目和更多的細節發現它們隨意。

它解壓到文件夾你想

a - Add the DotNetOpenAuth.dll to references in your site. 

    b- Delete all files/folders in Site Content folder. 

    c- Copy Assets Content files/folders to the site Content . 

    d- Copy the Assets Script files to the site Script. 

你的項目將是這樣的:

enter image description here

3-轉到視圖>共享> _Layout.cshtml,並與這個新的頭取代,我們剛纔添加的新的樣式和腳本:

<head> 
    <title>@ViewBag.Title</title> 
    <link href="@Url.Content("~/Content/Site.css")" 
    rel="stylesheet" type="text/css" /> 
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" 
    type="text/javascript"></script> 
    <link href="@Url.Content("~/Content/openid-shadow.css")" 
    rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/openid.css")" 
    rel="stylesheet" type="text/css" /> 
    <script src="@Url.Content("~/Scripts/openid-en.js")" 
    type="text/javascript"></script> 
    <script src="@Url.Content("~/Scripts/openid-jquery.js")" 
    type="text/javascript"></script> 
    <script type="text/javascript"> 
     $(document).ready(function() { 
      openid.init('openid_identifier'); 
     }); 
    </script> 
</head> 

4-轉到模型> AccountModels。CS,導航到公共類LogOnModel

,並補充說,我們將用它來從OpenID的選擇保存返回OpenID的OpenID的屬性

類看起來就像這樣:

public class LogOnModel 
{ 
    [Display(Name = "OpenID")] 
    public string OpenID { get; set; } 

    [Required] 
    [Display(Name = "User name")] 
    public string UserName { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [Display(Name = "Remember me?")] 
    public bool RememberMe { get; set; } 
} 

導航到公衆類RegisterModel並加入OpenID的屬性

public class RegisterModel 
{ 

    [Display(Name = "OpenID")] 
    public string OpenID { get; set; } 

    [Required] 
    [Display(Name = "User name")] 
    public string UserName { get; set; } 

    [Required] 
    [DataType(DataType.EmailAddress)] 
    [Display(Name = "Email address")] 
    public string Email { get; set; } 

    [Required] 
    [ValidatePasswordLength] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [DataType(DataType.Password)] 
    [Display(Name = "Confirm password")] 
    [Compare("Password", ErrorMessage = 
    "The password and confirmation password do not match.")] 
    public string ConfirmPassword { get; set; } 
} 

然後到服務節中AccountModels.cs

和修改CREATEUSER和添加的getUser獲得通過OpenID的用戶,你的界面

會是這樣的:

public interface IMembershipService 
{ 
    int MinPasswordLength { get; } 
    bool ValidateUser(string userName, string password); 
    MembershipCreateStatus CreateUser(string userName, string password, 
             string email, string OpenID); 
    bool ChangePassword(string userName, string oldPassword, string newPassword); 
    MembershipUser GetUser(string OpenID); 
} 

使用到AccountModels.cs

using System.Security.Cryptography; 
using System.Text; 

然後將這些將此函數添加到AccountModels.cs中,該函數將用於將OpenID轉換爲GUID

注意:隨意使用更好的散列到你的系統,MD5有一些碰撞問題。

public Guid StringToGUID(string value) 
{ 
    // Create a new instance of the MD5CryptoServiceProvider object. 
    MD5 md5Hasher = MD5.Create(); 
    // Convert the input string to a byte array and compute the hash. 
    byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(value)); 
    return new Guid(data); 
} 

還要修改CREATEUSER功能看起來像這樣:使用

public MembershipCreateStatus CreateUser(string userName, string password, 
             string email , string OpenID) 
{ 
    if (String.IsNullOrEmpty(userName)) throw 
    new ArgumentException("Value cannot be null or empty.", "userName"); 
    if (String.IsNullOrEmpty(password)) throw 
    new ArgumentException("Value cannot be null or empty.", "password"); 
    if (String.IsNullOrEmpty(email)) throw 
    new ArgumentException("Value cannot be null or empty.", "email"); 

    MembershipCreateStatus status; 
    _provider.CreateUser(userName, password, email, null, null, true, 
          StringToGUID(OpenID), out status); 
    return status; 
} 

這裏我們使用的會員卡ProviderUserKey存儲OpenID和把戲在這裏,我們轉換的OpenID字符串GUID通過CreateUser和GetUser方法。

現在讓我們來添加這個功能AccountModels.cs將由OpenID的獲取用戶:

public MembershipUser GetUser(string OpenID) 
{ 
    return _provider.GetUser(StringToGUID(OpenID), true); 
} 

5-去查看>帳戶> LogOn.cshtml

與此代替所有的標記一個,我們正在整合OpenID的選擇登錄查看:

@model OpenIDMVC3.Models.LogOnModel 
@{ 
    ViewBag.Title = "Log On"; 
} 
<h2> 
    Log On</h2> 
<p> 
    Please enter your username and password. @Html.ActionLink("Register", "Register") 
    if you don't have an account. 
</p> 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" 
    type="text/javascript"></script> 
<form action= 
"[email protected](Request.QueryString["ReturnUrl"])" 
method="post" id="openid_form"> 
<input type="hidden" name="action" value="verify" /> 
<div> 
    <fieldset> 
     <legend>Login using OpenID</legend> 
     <div class="openid_choice"> 
      <p> 
       Please click your account provider:</p> 
      <div id="openid_btns"> 
      </div> 
     </div> 
     <div id="openid_input_area"> 
      @Html.TextBox("openid_identifier") 
      <input type="submit" value="Log On" /> 
     </div> 
     <noscript> 
      <p> 
       OpenID is service that allows you to log-on to many different websites 
       using a single indentity. Find out <a href="http://openid.net/what/"> 
       more about OpenID</a>and <a href="http://openid.net/get/"> 
       how to get an OpenID enabled account</a>.</p> 
     </noscript> 
     <div> 
      @if (Model != null) 
      { 
       if (String.IsNullOrEmpty(Model.UserName)) 
       { 
       <div class="editor-label"> 
        @Html.LabelFor(model => model.OpenID) 
       </div> 
       <div class="editor-field"> 
        @Html.DisplayFor(model => model.OpenID) 
       </div> 
       <p class="button"> 
        @Html.ActionLink("New User ,Register", "Register", 
             new { OpenID = Model.OpenID }) 
       </p> 
       } 
       else 
       { 
        //user exist 
       <p class="buttonGreen"> 
        <a href="@Url.Action("Index", "Home")">Welcome , @Model.UserName, 
        Continue..." </a> 
       </p> 

       } 
      } 
     </div> 
    </fieldset> 
</div> 
</form> 

@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors 
                and try again.") 
@using (Html.BeginForm()) 
{ 
    <div> 
     <fieldset> 
      <legend>Or Login Normally</legend> 
      <div class="editor-label"> 
       @Html.LabelFor(m => m.UserName) 
      </div> 
      <div class="editor-field"> 
       @Html.TextBoxFor(m => m.UserName) 
       @Html.ValidationMessageFor(m => m.UserName) 
      </div> 
      <div class="editor-label"> 
       @Html.LabelFor(m => m.Password) 
      </div> 
      <div class="editor-field"> 
       @Html.PasswordFor(m => m.Password) 
       @Html.ValidationMessageFor(m => m.Password) 
      </div> 
      <div class="editor-label"> 
       @Html.CheckBoxFor(m => m.RememberMe) 
       @Html.LabelFor(m => m.RememberMe) 
      </div> 
      <p> 
       <input type="submit" value="Log On" /> 
      </p> 
     </fieldset> 
    </div> 
} 

6-現在讓我們來運行該項目,然後點擊[登錄]鏈接,你會得到這樣的頁面:

ws

7轉到控制器> AccountController.cs和使用這些地址:

using DotNetOpenAuth.Messaging; 
using DotNetOpenAuth.OpenId; 
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; 
using DotNetOpenAuth.OpenId.RelyingParty; 
using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; 

這個屬性然後添加到AccountController.cs:

private static OpenIdRelyingParty openid = new OpenIdRelyingParty(); 

然後添加此功能到AccountController。CS:

[ValidateInput(false)] 
public ActionResult Authenticate(string returnUrl) 
{ 
    var response = openid.GetResponse(); 
    if (response == null) 
    { 
     //Let us submit the request to OpenID provider 
     Identifier id; 
     if (Identifier.TryParse(Request.Form["openid_identifier"], out id)) 
     { 
      try 
      { 
       var request = openid.CreateRequest(
             Request.Form["openid_identifier"]); 
       return request.RedirectingResponse.AsActionResult(); 
      } 
      catch (ProtocolException ex) 
      { 
       ViewBag.Message = ex.Message; 
       return View("LogOn"); 
      } 
     } 

     ViewBag.Message = "Invalid identifier"; 
     return View("LogOn"); 
    } 

    //Let us check the response 
    switch (response.Status) 
    { 

     case AuthenticationStatus.Authenticated: 
      LogOnModel lm = new LogOnModel(); 
      lm.OpenID = response.ClaimedIdentifier; 
      // check if user exist 
      MembershipUser user = MembershipService.GetUser(lm.OpenID); 
      if (user != null) 
      { 
       lm.UserName = user.UserName; 
       FormsService.SignIn(user.UserName, false); 
      } 

      return View("LogOn", lm); 

     case AuthenticationStatus.Canceled: 
      ViewBag.Message = "Canceled at provider"; 
      return View("LogOn"); 
     case AuthenticationStatus.Failed: 
      ViewBag.Message = response.Exception.Message; 
      return View("LogOn"); 
    } 

    return new EmptyResult(); 
} 

8 - 現在運行的項目點擊[登錄]鏈接,然後點擊像谷歌

提供商

可能會要求您登錄或請你允許你的信息

訪問

你會得到一個頁面是這樣的:

enter image description here

正如你可以看到它顯示你的OpenID和一個按鈕,表明這是新用戶不打[新用戶,註冊]按鈕,我們需要修改註冊視圖和控制器訪問的OpenID信息之前還沒有註冊,

9-轉到控制器> AccountController.cs通過此更換[ActionResult的寄存器()]:

public ActionResult Register(string OpenID) 
{ 
    ViewBag.PasswordLength = MembershipService.MinPasswordLength; 
    ViewBag.OpenID = OpenID; 
    return View(); 
} 

和修改[ActionResult的寄存器(RegisterModel模型)]使用的OpenID時

創建用戶:

[HttpPost] 
public ActionResult Register(RegisterModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Attempt to register the user 
     MembershipCreateStatus createStatus = 
     MembershipService.CreateUser(model.UserName, model.Password, 
             model.Email,model.OpenID); 

     if (createStatus == MembershipCreateStatus.Success) 
     { 
      FormsService.SignIn(model.UserName, false); 
      return RedirectToAction("Index", "Home"); 
     } 
     else 
     { 
      ModelState.AddModelError("", 
      AccountValidation.ErrorCodeToString(createStatus)); 
     } 
    } 

    // If we got this far, something failed, redisplay form 
    ViewBag.PasswordLength = MembershipService.MinPasswordLength; 
    return View(model); 
} 

10-去查看>帳戶> Register.cshtml,這個替換標記:

@model OpenIDMVC3.Models.RegisterModel 
@{ 
    ViewBag.Title = "Register"; 
} 

<h2>Create a New Account</h2> 
<p> 
    Use the form below to create a new account. 
</p> 
<p> 
    Passwords are required to be a minimum of @ViewBag.PasswordLength 
    characters in length. 
</p> 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" 
    type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" 
    type="text/javascript"></script> 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true, "Account creation was unsuccessful. 
              Please correct the errors and try again.") 
    <div> 
     <fieldset> 
      <legend>Account Information</legend> 
      @if (ViewData["OpenID"] != null) 
      { 
      <div class="editor-label"> 
       @Html.Label("OpenID") 
      </div> 
      <div class="editor-label"> 
       @Html.Label((string)ViewBag.OpenID) 
      </div> 
      } 
      <div class="editor-label"> 
       @Html.LabelFor(m => m.UserName) 
      </div> 
      <div class="editor-field"> 
       @Html.TextBoxFor(m => m.UserName) 
       @Html.ValidationMessageFor(m => m.UserName) 
      </div> 

      <div class="editor-label"> 
       @Html.LabelFor(m => m.Email) 
      </div> 
      <div class="editor-field"> 
       @Html.TextBoxFor(m => m.Email) 
       @Html.ValidationMessageFor(m => m.Email) 
      </div> 

      <div class="editor-label"> 
       @Html.LabelFor(m => m.Password) 
      </div> 
      <div class="editor-field"> 
       @Html.PasswordFor(m => m.Password) 
       @Html.ValidationMessageFor(m => m.Password) 
      </div> 

      <div class="editor-label"> 
       @Html.LabelFor(m => m.ConfirmPassword) 
      </div> 
      <div class="editor-field"> 
       @Html.PasswordFor(m => m.ConfirmPassword) 
       @Html.ValidationMessageFor(m => m.ConfirmPassword) 
      </div> 

      <p> 
       <input type="submit" value="Register" /> 
      </p> 
     </fieldset> 
    </div> 
} 

11-轉到步驟8,讓我們打[新用戶,註冊】按鈕,你會得到這樣的:

enter image description here

12註冊你想你會得到這樣的頁面的任何帳戶:

enter image description here

13-單擊[註銷]並使用相同的OpenID重新登錄,你會得到這樣的頁面:

enter image description here

正如您所看到的歡迎綠色按鈕檢測到此用戶已註冊。

14-按一下綠色按鈕,你會得到一個頁面是這樣的:

enter image description here

恭喜! ,現在你已經將OpenID集成到了你的項目中。

Reference

+0

非常完整的教程...參考鏈接似乎並不指向你可能認爲它。 –

+1

謝謝,但是,如何將其鏈接到自定義提供程序?即我自己的身份驗證提供程序? – tggm