博客地址 http://blog.csdn.net/foxdave
SharePoint 2010 表單認證,基于現有數據庫的用戶信息表
本文主要描述本人配置過程中涉及到的步驟,僅作為參考,不要僅限于此步驟。
另外本文通俗易懂,適合大眾口味兒。
?
I. 開啟并配置基于聲明的身份驗證
打開SharePoint 2010 Management Shell,依次執行以下語句
$app = Get-SPWebApplication "<your webapp url>"
$app.UseClaimsAuthentication = "true"
$app.Update()
進入管理中心->應用程序管理->管理Web應用程序,選中上面的webapp,點擊身份驗證提供程序,點擊默認鏈接彈出驗證配置窗口。
勾選“啟用基于窗體的身份驗證(FBA)”,填入名稱,這里用mp和rp舉例,之后會用到;登錄頁URL這里,可以默認也可以自定義,這里我選擇了自定義,是自己寫的一個登錄頁。
點擊保存完成第一步驟。
?
II. WebConfig配置
需要配置mp和rp的位置有三個,分別是管理中心、webapp端口對應的IIS目錄,以及{SharePoint Root}\WebServices\SecurityToken目錄下的web.config文件
需要添加的內容如下
<membership defaultProvider="i"><providers><!--將以下節點添加到指定位置--><add name="mp" type="<assembly>" />
</providers></membership>
<roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false"><providers><!--將以下節點添加到指定位置--><add name="rp" type="<assembly>" /></providers></roleManager>
<connectionStrings><add connectionString="<connStr>" name="Conn" />
</connectionStrings>
其中assembly為自定義Provider的dll的描述,后面會提到;connStr為數據庫連接串。
?
III. 自定義MembershipProvider
大致的思路是寫兩個sealed類,mp繼承MembershipProvider,rp繼承RoleProvider,我的環境中沒有用到角色,所以rp只做了繼承,注釋掉了
rp代碼
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web.Security;namespace Providers
{public sealed class rp : RoleProvider{private bool mWriteExceptionsToEventLog = false;public bool WriteExceptionsToEventLog{get{return mWriteExceptionsToEventLog;}set{mWriteExceptionsToEventLog = value;}}public override void Initialize(string name, NameValueCollection config){base.Initialize(name, config);}private string pApplicationName = "";public override string ApplicationName{get{return pApplicationName;}set{pApplicationName = value;}}public override void AddUsersToRoles(string[] usernames, string[] rolenames){throw new NotImplementedException();}public override void CreateRole(string rolename){throw new NotImplementedException();}public override bool DeleteRole(string rolename, bool throwOnPopulatedRole){throw new NotImplementedException();}public override string[] GetAllRoles(){return null;}public override string[] GetRolesForUser(string username){return null;}public override string[] GetUsersInRole(string rolename){return null;}public override bool IsUserInRole(string username, string rolename){return false;}public override void RemoveUsersFromRoles(string[] usernames, string[] rolenames){throw new NotImplementedException();}public override bool RoleExists(string rolename){return false;}public override string[] FindUsersInRole(string rolename, string usernameToMatch){return null;}private static List<string> GetAllUsers(){return null;}private static List<string> FindAllRoles(){return null;}private List<string> FindRolesForUser(string username){return null;}}
}
mp最少實現以下四個方法,完成在SharePoint上查找添加用戶以及登錄邏輯的自定義處理。
GetAllUsers、GetUser、ValidateUser、FindUsersByName
我這里大致的做法就是用Webconfig中添加的數據庫連接串去操作現有數據庫的用戶表,嘗試用Entities但是好像行不通
mp核心代碼
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords){MembershipUserCollection spusers = new MembershipUserCollection();List<MIPUser> users = GetAllUsers();foreach (MIPUser user in spusers){MembershipUser spuser = new MembershipUser(this.Name,user.LoginName,user.LoginName,user.LoginName + "@contoso.com","","",true,false,DateTime.Today,DateTime.Today,DateTime.Today,DateTime.Today,DateTime.Today);spusers.Add(spuser);}totalRecords = spusers.Count;return spusers;}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline){MembershipUser spuser = null;List<MIPUser> users = GetAllUsers();var query = users.Where(u => u.LoginName.IndexOf(providerUserKey.ToString(), StringComparison.CurrentCultureIgnoreCase) >= 0 ||u.DisplayName.IndexOf(providerUserKey.ToString(), StringComparison.CurrentCultureIgnoreCase) >= 0).Select(u => u);if (query.Count() != 0){var user = query.First();spuser = new MembershipUser(this.Name,user.LoginName,user.LoginName,user.LoginName + "@contoso.com","","",true,false,DateTime.Today,DateTime.Today,DateTime.Today,DateTime.Today,DateTime.Today);return spuser;}else{return null;}}
public override MembershipUser GetUser(string username, bool userIsOnline){MembershipUser spuser = null;List<MIPUser> users = GetAllUsers();var query = users.Where(u => u.LoginName.Equals(username, StringComparison.CurrentCultureIgnoreCase) ||u.DisplayName.Equals(username, StringComparison.CurrentCultureIgnoreCase)).Select(u => u);if (query.Count() != 0){var user = query.First();spuser = new MembershipUser(this.Name,user.LoginName,user.LoginName,user.LoginName + "@contoso.com","","",true,false,DateTime.Today,DateTime.Today,DateTime.Today,DateTime.Today,DateTime.Today);return spuser;}else{return null;}}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords){MembershipUserCollection spusers = new MembershipUserCollection();List<MIPUser> users = GetAllUsers();var query = users.Where(u => u.LoginName.IndexOf(usernameToMatch, StringComparison.CurrentCultureIgnoreCase) >= 0 ||u.DisplayName.IndexOf(usernameToMatch, StringComparison.CurrentCultureIgnoreCase) >= 0).Select(name => name);foreach (var user in query){MembershipUser spuser = new MembershipUser(this.Name,user.LoginName,user.LoginName,user.LoginName + "@contoso.com","","",true,false,DateTime.Today,DateTime.Today,DateTime.Today,DateTime.Today,DateTime.Today);spusers.Add(spuser);}totalRecords = query.Count();return spusers;}
寫好后將dll添加強命名,部署到GAC。?
IV. 番外-自定義登錄頁
自定義登錄頁,沒什么難度,直接貼代碼了
ASPX
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %><%@ Page Language="C#" AutoEventWireup="true" CodeBehind="login.aspx.cs" Inherits="Authentication.login" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title></title><script language="javascript" for="document" event="onkeydown">if (event.keyCode == 13) {document.getElementById("<%=btnLogin.ClientID %>").click();}</script><script language="javascript" type="text/javascript">function login() {if (document.getElementById("<%=txtUserName.ClientID %>").value == "") {alert('請輸入用戶名');return;}if (document.getElementById("<%=txtPassword.ClientID %>").value == "") {alert('請輸入密碼');return;}document.getElementById("<%=btnLogin.ClientID %>").click();}</script>
</head>
<body><form action="" id="form" runat="server"><table border="0" cellspacing="0" cellpadding="0" class="login_table"><tr><td class="login_td" align="center"><div class="logan_contai"><div class="login_box" style="height: 488px;"><div class="login_top"><div class="login_top_wel">歡迎使用</div><div class="login_top_nav"></div></div><div class="login_main png"><asp:Literal ID="ltError" runat="server"></asp:Literal><div class="login_txt_box"><ul><li><div class="login_name">用戶名</div><div class="login_inpbox"><asp:TextBox ID="txtUserName" runat="server" CssClass="login_input" οnfοcus="this.className='login_input_hov'"MaxLength="100" οnblur="this.className='login_input'"></asp:TextBox><div class="login_wrong"></div></div></li><li><div class="login_name">密 碼</div><div class="login_inpbox"><asp:TextBox ID="txtPassword" runat="server" TextMode="Password" CssClass="login_input"οnfοcus="this.className='login_input_hov'" MaxLength="100" οnblur="this.className='login_input'"></asp:TextBox></div><div class="login_wrong"></div></li><li><div class="login_btn" style="width: 191px; padding: 9px 0 0 155px;"><a href="#" title="" οnclick="login()">登 錄</a></div><div style="display: none;"><asp:Button CssClass="login_btn" Width="191px" ID="btnLogin" runat="server" Text="登錄"OnClick="btnLogin_Click" Style="padding: 9px 0 0 155px" /></div></li></ul></div></div><div class="login_foot png"></div></div></div></td></tr></table></form>
</body>
</html>
CS
using System;
using System.Web.UI;
using Microsoft.SharePoint.IdentityModel;namespace Authentication
{public partial class login : Page{protected void Page_Load(object sender, EventArgs e) { }protected void btnLogin_Click(object sender, EventArgs e){Login(this.txtUserName.Text, this.txtPassword.Text);}private void Login(string username, string passwrod){try{bool status = SPClaimsUtility.AuthenticateFormsUser(Request.Url, username, passwrod);if (!status){ltError.Text = "用戶名或密碼錯誤,請重新輸入!";}else{if (Request.QueryString["ReturnUrl"] != null && Request.QueryString["ReturnUrl"] != ""){Response.Redirect(Request.QueryString["ReturnUrl"]);}else if (Request.QueryString["Source"] != null && Request.QueryString["Source"] != ""){Response.Redirect(Request.QueryString["Source"]);}else{Response.Redirect("~/");}}}catch (Exception ex){ltError.Text = "系統錯誤:<br />";ltError.Text = ex.Message;}}}
}
?
以上就是大致的步驟。PS:在搜索添加SharePoint用戶的時候,無法顯示成名稱,只能顯示登錄名,還不知道如何解決。
參考資料