muugua 发表于 2015-9-25 13:45:24

SharePoint单点登陆(Single Sign On)实战

  
SharePoint Portal Server 2003提供了一个看上去很酷的功能:单点登陆(Single Sign On)。
SPS可以为网站用户记录其在其他应用系统中的登陆凭据,而我们的程序(WebPart)可以通过获取并利用这些凭据代替用户登陆第三方应用系统,并输出所需要展示的数据。
其工作原理大致如下:
1、用户访问网站上的单点登陆WebPart
2、WebPart通过Single Sign On的对象模型从SSO数据库中查找当前用户的凭据
3、如果没有此凭据,则将用户导引至输入凭据的页面
4、如果有此凭据,则通过此凭据登陆第三方应用系统,获取相关业务数据

有关Single Sign On的管理和使用,可以参考kaneboy的Webcast,并且有相关的源代码下载。

这篇文章中主要介绍的内容是上述工作原理的第三步:用户输入凭据的页面。
如果使用默认的输入页面(用如下代码获得URL):

SingleSignonLocator.GetCredentialEntryUrl("FormSSO")   
用户将在这样的页面中输入登陆凭据:


这个页面是一个典型的sharepoint的_layouts目录.NET应用页面。
就个人而言,我很喜欢这样的页面风格,但是我们还是会面对修改这个页面的需求,即我们需要用自己开发的页面引导用户输入其应用凭据。

那么,如何自己编写实现此功能的页面呢?接下来是一个实例:

1、打开vs2003,在http://localhost/_layouts/SSOSample下创建一个ASP.NET的web应用程序。(当然你要记得把“Localhost”换成你的SharePoint站点地址)
2、创建一个新的用户控件
3、在用户控件中拖入几个必需的web控件:

如上图,两个TextBox,一个按钮,以及一个显示错误信息的Label。
同时,为了向那些已经拥有凭据的用户隐藏输入框,我们把前3个控件包含在一个Panel中,并另这个Panel默认隐藏。
4、编写“保存”按钮的响应函数:


      private void btnSave_Click(object sender, System.EventArgs e)
      {
            if (this.tbUserName.Text == null || this.tbUserName.Text =="")
            {
                this.lbOutput.Text = "请输入用户名";
                return;
            }
            if (this.tbPassword.Text == null || this.tbPassword.Text =="")
            {
                this.lbOutput.Text = "请输入登陆密码";
                return;
            }
            string[]   rgSetCredentialData = new string;
            rgSetCredentialData = this.tbUserName.Text;
            rgSetCredentialData = this.tbPassword.Text;
            try
            {
                Credentials.SetCredentials(1, "SSOTEST", rgSetCredentialData);
            }
            catch(SingleSignonException esso)
            {
                this.lbOutput.Text = esso.Message + "<br>" + esso.StackTrace;
            }
            this.Page.Response.Redirect(this.Page.Request.Url.ToString());
      }
为了演示,我在Page_Load函数中加入如下代码,使得已经填写SSO凭据的用户可以浏览到自己凭据内容:

      private void Page_Load(object sender, System.EventArgs e)
      {
            // 在此处放置用户代码以初始化页面
            try
            {
                String[] asCredData = null;

                Credentials.GetCredentials(1, "SSOTEST", ref asCredData);

                String sUsername = asCredData;
                String sPassword = asCredData;

                this.lbOutput.Text = sUsername + "<br>" + sPassword;

            }
            catch (SingleSignonException ex)
            {
                if (SSOReturnCodes.SSO_E_CREDS_NOT_FOUND == ex.LastErrorCode)
                {
                  if (!this.IsPostBack)
                  {
                        this.tbPassword.Text = "";
                        this.tbUserName.Text = "";
                        this.pnlSSOPart.Visible = true;
                  }
                  else
                  {
                        this.lbOutput.Text = "请重新填写您的帐户信息";
                  }
                }
            }

      }
5、一切并没有到此结束,如果直接编译运行,我们在点击按钮的时候会收到这样的出错信息:

at Microsoft.SharePoint.Portal.SingleSignon.SSOCanaryChecker.b() at Microsoft.SharePoint.Portal.SingleSignon.SSOCanaryChecker.b() at Microsoft.SharePoint.Portal.SingleSignon.Credentials.SetCredentials(UInt32 ui32Flags, String strApplicationName, Object[] Args)

这是因为页面安全性的问题。我们需要在页面中引入SharePoint的FormDigest控件和SSOFormDigest控件:
即在用户控件的ascx文件中加入:

<%@ Register TagPrefix="cc2" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="cc1" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<cc2:formdigest id="FormDigest1" runat="server"></cc2:formdigest>
<cc1:ssoformdigest id="SSOFormDigest1" runat="server"></cc1:ssoformdigest>
当然我们也可以在工具栏中直接添加这两个控件,通过对用户控件进行拖放操作达到同样的目的。

这个解决办法,尤其是引入SSOFormDigest控件,我是从以下文章找到的:
http://geekswithblogs.net/tariq/archive/2004/09/10/10961.aspx
当然,我是从GOOGLE中搜索得到这一文章的。
插句题外话,我非常赞同熊明峰同志的观点:在使用GOOGLE中一定要使用恰当的搜索关键词,才能获得最有效率的搜索结果,所以我希望大家都能分享自己搜索到可用信息时使用的关键词,来提高自己的搜索技能。也许并不遥远的以后,选择关键词的能力将成为人类重要技能之一。
我使用的关键词:sharepoint SetCredentials


6、我们的用户SSO凭据存储功能基本就完成了:
一个没有凭据的用户登陆此页面时,需要填写新的用户凭据:

一旦保存成功,用户再次登陆的时候,SPS就能直接返回其对应的用户凭据内容:



好。接下来你就可以躲到写字楼的安全通道抽支烟,把剩下的工作丢给美工了。
至少我是这么干的。
页: [1]
查看完整版本: SharePoint单点登陆(Single Sign On)实战