在SharePoint 2007时代我们可以通过Microsoft Single Sign-on Service来实现单点登录,但到了SharePoint 2010中不再有Single Sign-on这个服务了,取而代之的则是Secure Store Service简称SSS。与以前的SSO一样,SSS也提供了一个数据库实例来保存用于访问某些外部应用程序或外部数据源的用户凭据信息,所不同的是我们不仅可以使用SSS中保存的凭据信息来实现单点登录,同时BDC、Excel Service等服务应用程序现在也可使用SSS中保存的凭据来访问外部数据源。接下来的内容中小弟我将对如何使用SSS实现单点登录进行详细的说明。
与2007相同的是在SP 2010中要实现单点登录依然需要我们写代码来实现,不过在这之前还需要对场中的SSS服务进行初始配置。
对SSS进行初始配置
首先进入SharePoint 2010管理中心,在应用程序管理页面选择管理服务应用程序。
在服务应用程序页面,选择Secure Store Service,然后点击上方Ribbon区中的管理。
在初次进入SSS管理页面时,系统将提示我们“在创建新的安全存储目标应用程序之前,必须首先在功能区中为此 Secure Store Service 应用程序生成新密钥。”
该密钥将对我们存储在SSS数据库中的凭据信息进行加密和解密。
点击Ribbon区内的生成新密钥,在弹出窗口中为该密钥设置通行短语。
密钥生成后,SSS的初始配置便算是告一段落了。
创建目标应用程序
如果大家在SharePoint 2007中曾经使用过SSO的话应该对这部分的内容比较熟悉,关于创建目标应用程序的操作与2007相比并无很大区别。
首先还是进入我们的SSS实例的管理页面,在Ribbon区里的管理目标应用程序组中单击新建按钮进入创建新的安全存储目标应用程序页面。
我们需要设置目标应用程序的ID、显示名称、联系人电子邮件、目标应用程序类型这四个主要属性,其中比较重要的属性是目标应用程序ID和目标应用程序类型。ID是SSS用于识别此目标应用程序的唯一标识,目标应用程序类型主要分为个人和组两大类,如果选择个人则可以启用一个目标应用程序页,该页面将用于用户自行添加该目标应用程序的个人凭据。
因为在本例中要做的是用户与其个人邮箱间的映射,所以这里选择个人就好了,然后点击下一步。下面要做的就是设置将凭据提交到外部数据源时所要用到的字段了,默认情况下是用户名和密码两个字段。其中的已屏蔽选项表示当用户在输入该字段的值时将以屏蔽字符代替用户的输入字符,例如 *号。在本例中保持默认值就可以了。
最后还需要为此目标应用程序设置一个管理员。
OK,到了这里所有的配置工作就结束了,由于在SharePoint 2010中微软仍然没有提供一个可以out-of-box的WebPart,所以像07中一样,要实现单点登录的话还需要我们自己来开发一个WebPart。
创建单点登录WebPart
由于在SharePoint 2010中微软用SSS取代了以前的SSO,所以在2007中实现单点登录时所用的代码现在已经不能用了,需要用SP 2010中新的对象模型来完成这一功能。
使用VS2010创建一个空白SharePoint项目,然后添加一个可视Web部件。
接着在此项目中添加Microsoft.BussinessData和Microsoft.Office.SecureStoreService的引用。这里呢可能会出现一个问题,因为在Microsoft SharedWeb Server Extensions14ISAPI这个目录下只有Microsoft.Office.SecureStoreService.Server.Security这个dll,需要我们自己到GAC中将Microsoft.Office.SecureStoreService这个dll拷贝出来才行,可以参看http://support.microsoft.com/kb/982263。Microsoft.BussinessData可以在Microsoft SharedWeb Server Extensions14ISAPI目录下找到。
通过下面这段代码可获得当前用户存储在SSS中的目标应用程序凭据。
1 protected void Button1_Click(object sender, EventArgs e)
2 {
3 string m_userName = string.Empty;
4 string m_password = string.Empty;
5 string m_html = string.Empty;
6 string m_appId = "163Mail";
7 SecureStoreProvider m_provider = new SecureStoreProvider();
8 SPSite m_site = SPContext.Current.Site;
9 SPServiceContext m_serviceContext = SPServiceContext.GetContext(m_site);
10 m_provider.Context = m_serviceContext;
11 try
12 {
13 SecureStoreCredentialCollection m_sscc = m_provider.GetCredentials(m_appId);
14 foreach (SecureStoreCredential ssc in m_sscc)
15 {
16 switch (ssc.CredentialType)
17 {
18 case SecureStoreCredentialType.Generic:
19 break;
20 case SecureStoreCredentialType.Key:
21 break;
22 case SecureStoreCredentialType.Password:
23 m_password = ToClrString(ssc.Credential);
24 break;
25 case SecureStoreCredentialType.Pin:
26 break;
27 case SecureStoreCredentialType.UserName:
28 m_userName = ToClrString(ssc.Credential);
29 break;
30 case SecureStoreCredentialType.WindowsPassword:
31 break;
32 case SecureStoreCredentialType.WindowsUserName:
33 break;
34 default:
35 break;
36 }
37 }
38 m_html += "<script>";
39 m_html += string.Format("window.location.href='http://reg.163.com/login.jsp?url=&type=1&product=&savelogin=&outfoxer=&domains=&syscheckcode=4ecd8fe3803494cff0df5414f321fd5f9afa4c78&username={0}%40163.com&password={1}&Submit='", m_userName, m_password);
40 m_html += "</script>";
41 Response.Write(m_html);
42 }
43 catch (Exception ex)
44 {
45 Response.Write("<script>window.location.href= '/_layouts/SecureStoreSetCredentials.aspx?TargetAppId=" + m_appId + "';</script>");
46 }
47 }
完成后将WebPart部署到网站中,OK,结束~~~
下面是本示例的完整代码,比较简单也没写注释,大伙凑乎着看吧。
1 using System;
2 using System.Security;
3 using System.Web.UI;
4 using System.Web.UI.WebControls;
5 using System.Web.UI.WebControls.WebParts;
6 using Microsoft.SharePoint;
7 using Microsoft.Office.SecureStoreService.Server;
8 using Microsoft.BusinessData.Infrastructure.SecureStore;
9 namespace SP2010SingleSignOnWebPart.SingleSignOnWebPart
10 {
11 public partial class SingleSignOnWebPartUserControl : UserControl
12 {
13 protected void Button1_Click(object sender, EventArgs e)
14 {
15 string m_userName = string.Empty;
16 string m_password = string.Empty;
17 string m_html = string.Empty;
18 string m_appId = "163Mail";
19 SecureStoreProvider m_provider = new SecureStoreProvider();
20 SPSite m_site = SPContext.Current.Site;
21 SPServiceContext m_serviceContext = SPServiceContext.GetContext(m_site);
22 m_provider.Context = m_serviceContext;
23 try
24 {
25 SecureStoreCredentialCollection m_sscc = m_provider.GetCredentials(m_appId);
26 foreach (SecureStoreCredential ssc in m_sscc)
27 {
28 switch (ssc.CredentialType)
29 {
30 case SecureStoreCredentialType.Generic:
31 break;
32 case SecureStoreCredentialType.Key:
33 break;
34 case SecureStoreCredentialType.Password:
35 m_password = ToClrString(ssc.Credential);
36 break;
37 case SecureStoreCredentialType.Pin:
38 break;
39 case SecureStoreCredentialType.UserName:
40 m_userName = ToClrString(ssc.Credential);
41 break;
42 case SecureStoreCredentialType.WindowsPassword:
43 break;
44 case SecureStoreCredentialType.WindowsUserName:
45 break;
46 default:
47 break;
48 }
49 }
50 m_html += "<script>";
51 m_html += string.Format("window.location.href='http://reg.163.com/login.jsp?url=&type=1&product=&savelogin=&outfoxer=&domains=&syscheckcode=4ecd8fe3803494cff0df5414f321fd5f9afa4c78&username={0}%40163.com&password={1}&Submit='", m_userName, m_password);
52 m_html += "</script>";
53 Response.Write(m_html);
54 }
55 catch (Exception ex)
56 {
57 Response.Write("<script>window.location.href= '/_layouts/SecureStoreSetCredentials.aspx?TargetAppId=" + m_appId + "';</script>");
58 }
59 }
60 internal string ToClrString(SecureString p_string)
61 {
62 var m_ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(p_string);
63 try
64 {
65 return System.Runtime.InteropServices.Marshal.PtrToStringBSTR(m_ptr);
66 }
67 finally
68 {
69 System.Runtime.InteropServices.Marshal.FreeBSTR(m_ptr);
70 }
71 }
72 }
73 }