文档章节

SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用

 木宛城主
发布于 2015/03/02 19:38
字数 1451
阅读 4
收藏 0

 

由于项目的需要,登录SharePoint Application的用户将从一个统一平台中获取,而不是从Domain中获取,所以需要对SharePoint Application的身份验证(Claims Authentication Types)进行更改,即采用更加灵活的混合模式登录:Windows Authentication和Forms Based Authentication。故本篇博客将着重笔墨去介绍SharePoint 2013自定义Providers在基于表单的身份验(Forms-Based-Authentication)中的应用。

更改身份验证

首先需要了解的一点事,怎样去更改指定的Web Application 的身份验证。进入SharePoint 2013 Central Administration-àApplication Management-àManage Web Applications-àAuthentication Providers,即如下所示:

如截图所示那样,启用了FBA之后,需要我们提供自定义的Menbership Provider和Role Provider。

创建Membership Provider和Role Provider

这儿我选择创建一个Class Library,当然你也可以直接创建一个SharePoint 2013 Empty Project,注意不管是哪种,最终都需要把Assembly 注册/安装 到GAC里

  • 如果是创建了SharePoint Project,要安装Assembly到GAC,直接部署就行。
  • 如果是创建了Class Library,需要有两个步骤1).Sign the assembly(右键项目-àProperty-àSigning),2)gacutil /i "<assembly path/assembly name.dll>",如下所示(使用VS Command Tool):

获取Strong Name Key File

安装Assembly到GAC

对于.NET 4.0以上的Assembly,GAC位于C:\Windows\Microsoft.NET\assembly。.NET 3.5 GAC在C:\Windows\assembly,所以别找错地方。Assembly成功注册到GAC后,最好IISReset下。

接着,创建相关的Provider,分别继承MembershipProviderRoleProvider即可。

  •  自定义MembershipProvider,主要代码如下:
public class FBA_CustomRoleProvider : MembershipProvider
    {
        #region 重写的方法

        private MembershipUserCollection employees;
        private void generateUsers()
        {

            employees = new MembershipUserCollection();
            employees.Add(new MembershipUser(this.Name, "Jack Chen", "JackChen", "Jack@Chen.com", "What your Name?", "I am Jack", true, false, DateTime.Today, DateTime.Today, DateTime.Today, DateTime.Today, DateTime.Today));
            employees.Add(new MembershipUser(this.Name, "Bruce Li", "BruceLi", "BruceLi@Li.com", "How are u?", "How old are u", true, false, DateTime.Today, DateTime.Today, DateTime.Today, DateTime.Today, DateTime.Today));
            employees.Add(new MembershipUser(this.Name, "Eyes Wang", "EyesWang", "EyesWang@Mintcode.com", "What the hell?", "what the fuck", true, false, DateTime.Today, DateTime.Today, DateTime.Today, DateTime.Today, DateTime.Today));

        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            if (employees == null) generateUsers();
            MembershipUserCollection returnFoundUsers = new MembershipUserCollection();

            (employees.Cast<MembershipUser>().

                Where(membershipUser => membershipUser.UserName.ToLowerInvariant().Contains(usernameToMatch.ToLowerInvariant())))

                .ToList().ForEach(returnFoundUsers.Add);

            totalRecords = returnFoundUsers.Count;
            return returnFoundUsers;
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {

            if (employees == null) generateUsers();
            totalRecords = employees.Count;
            return employees;
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {

            if (employees == null) generateUsers();
            IEnumerable<MembershipUser> usersFound = employees.Cast<MembershipUser>().Where(membershipUser => membershipUser.UserName == username);
            return usersFound.FirstOrDefault();
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {

            if (employees == null) generateUsers();

            IEnumerable<MembershipUser> usersFound = employees.Cast<MembershipUser>().Where(membershipUser => membershipUser.ProviderUserKey.ToString() == providerUserKey.ToString());

            return usersFound.FirstOrDefault();
        }

        public override string GetUserNameByEmail(string email)
        {
            if (employees == null) generateUsers();

            IEnumerable<MembershipUser> usersFound = employees.Cast<MembershipUser>().Where(membershipUser => membershipUser.Email.ToLowerInvariant() == email.ToLowerInvariant());

            MembershipUser user = usersFound.FirstOrDefault();


            if (user != null)

                return user.UserName;

            else

                return null;
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {

            if (employees == null) generateUsers();
            MembershipUserCollection returnFoundUsers = new MembershipUserCollection();

            (employees.Cast<MembershipUser>().

             Where(membershipUser => membershipUser.Email.ToLowerInvariant().Contains(emailToMatch.ToLowerInvariant())))

                .ToList().ForEach(returnFoundUsers.Add);

            totalRecords = returnFoundUsers.Count;

            return returnFoundUsers;

        }

        public override bool ValidateUser(string username, string password)
        {
            //return true;
            if (employees == null) generateUsers();

            IEnumerable<MembershipUser> usersFound = employees.Cast<MembershipUser>().Where(membershipUser => membershipUser.UserName == username);
            MembershipUser user = usersFound.FirstOrDefault();

            if (user != null)
            {

                if (string.IsNullOrEmpty(password))
                {

                    return false;

                }

                else
                {

                    return true;

                }

            }

            else

                return false;
        }
        #endregion
}
  • 自定义Role Provider,如下所示:
public class FBA_CustomMembershipProvider:RoleProvider
    {
       public override string ApplicationName { get; set; }

        //所有角色
        private string[] m_AllRoles = { "Developer", "Administrator", "Designer", "Architect ", "UI" };
    
        private string[,] m_RolesForUser = new string[,] {

            {"Eyes Wang", "Developer"},

            {"Bruce Li","Administrator"},

            {"Jack Chen","Designer,Architect"},

        };
                
        /// <summary>
        /// 获取全部角色
        /// </summary>
        /// <returns></returns>
        public override string[] GetAllRoles()
        {

            return m_AllRoles;

        }
        
        /// <summary>
        /// 根据User得到其相关的角色
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public override string[] GetRolesForUser(string username)

        {
            List<string> roles = new List<string>();
            for (int i = 0; i <= m_RolesForUser.GetUpperBound(0); i++)
            {

                if (m_RolesForUser[i, 0] == username)
                {
                    roles = m_RolesForUser[i, 1].Split(',').ToList<string>();
                }

            }
            return roles.ToArray();
        }

            /// <summary>
            /// 根据角色获取其绑定的用户
            /// </summary>
            /// <param name="rolename"></param>
            /// <returns></returns>
          public override string[] GetUsersInRole(string rolename)
          {

              List<string> users = new List<string>();
              for (int i = 0; i <= m_RolesForUser.GetUpperBound(0); i++)
               {
                   List<string> userRoles = m_RolesForUser[i, 1].Split(',').ToList<string>();
                   if (userRoles.Where(userRole => userRole == rolename).Count() > 0)
                  {

                     users.Add(m_RolesForUser[i, 0]);
                  }

              }
              return users.ToArray();
           }


         public override bool IsUserInRole(string username, string rolename)
         {

              List<string> usersForRole = GetUsersInRole(rolename).ToList();
              if (usersForRole.Where(userName => userName == username).Count() > 0)
              {
                  return true;
              }

              else
              {
                  return false;
              }

         }

        public override bool RoleExists(string rolename)
        {

             bool roleExsists = m_AllRoles.ToList().Where(roleName => roleName == rolename).Count() > 0;
             return roleExsists;
        }

        public override string[] FindUsersInRole(string rolename, string usernameToMatch)
        {

            List<string> users = GetUsersInRole(rolename).ToList<string>();
            List<string> foundUsers = users.Where(userName => userName.ToLowerInvariant().Contains(usernameToMatch.ToLowerInvariant())).ToList<string>();
            return foundUsers.ToArray();
       }
}
  • 自定义的Provider成功安装到GAC之后,接着修改web.config。注意需要修改3个地方,Web Application Config、SharePoint Central Administration Config、SecurityTokenServiceApplication,其路径如果记不住的话,打开IIS,浏览即可,即如下所示:

修改Web Config

Web Config需要Assembly的Public Key Token,可以使用VS Command Tool来获取:

  • 首先修改Web Application的Web Config,找到其Membership节点,将以下代码复制进:
<membership defaultProvider="i">
      <providers>
        <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="CustomMembershipProvider" type="Eyes.CustomProvider.FBA_CustomRoleProvider,Eyes.CustomProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c4a0ffa664cbc06c" />
      </providers>
    </membership>
    <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
      <providers>
        <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="CustomRoleProvider" type="Eyes.CustomProvider.FBA_CustomMembershipProvider,Eyes.CustomProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c4a0ffa664cbc06c" />
      </providers>
    </roleManager>
  • 接着修改SharePoint Central Administration的Web Config,
<membership defaultProvider="i">
      <providers>
        <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="CustomMembershipProvider" type="Eyes.CustomProvider.FBA_CustomRoleProvider,Eyes.CustomProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c4a0ffa664cbc06c" />
      </providers>
    </membership>
    <roleManager>
      <providers>
        <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="CustomRoleProvider" type="Eyes.CustomProvider.FBA_CustomMembershipProvider,Eyes.CustomProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c4a0ffa664cbc06c" />
      </providers>
    </roleManager>
  • 然后修改SecurityTokenSeriveApplication的Web Config,
<system.web>
     <membership defaultProvider="i">
      <providers>
        <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="CustomMembershipProvider" type="Eyes.CustomProvider.FBA_CustomRoleProvider,Eyes.CustomProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c4a0ffa664cbc06c" />
      </providers>
    </membership>
    <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
      <providers>
        <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="CustomRoleProvider" type="Eyes.CustomProvider.FBA_CustomMembershipProvider,Eyes.CustomProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c4a0ffa664cbc06c" />
      </providers>
    </roleManager>
  </system.web>
  • 最后将Web Application的Authentication Type修改为混合模式,如下所示

分配用户并测试

成功为Web Application创建了自定义的Provider之后,接着就是测试是否成功。如添加访问用户,可以如下图操作所示:

搜索用户,如下图所示:

访问Site,提示混合登录模式,如下图所示:

登录成功后显示信息:

小结

当以Windows Authentication注销时,会发生错误(查阅日志后报错信息encodeValue不能为空)。我猜是没清理Session,查了很多资料,发现这是个别现象。不知道最新的SharePoint 2013 Updates有没有解决这个问题。我的版本是SharePoint 2013 Server(原始版本,从未更新过)。如果解决的话,劳烦各位朋友告诉我一下。点击代码下载

 

© 著作权归作者所有

共有 人打赏支持
粉丝 2
博文 222
码字总数 199010
作品 0
黄浦
私信 提问
《Pro ASP.NET MVC 3 Framework》学习笔记之三十四 【验证与授权】

使用windows验证(Using Windows Authentication) 在软件术语里面,验证的意思是测定身份。这个跟授权是完全分开的,授权是让合适的人做合适的事情,授权通常在验证之后发生。ASP.NET的验证功...

mszhangxuefei
2012/06/15
0
0
Video : 将使用AD认证的SharePoint网站配置为表单方式登录

SharePoint网站默认是使用Active Directory集成认证,但如果是用于Internet场景,那么由于难以为访问用户建立AD帐号,解决方法通常是将SharePoint网站配置成使用Forms认证,在一个自定义的数...

余二五
2017/11/22
0
0
sharepoint2010 升级到 sharepoint2013注意事项

将一个SharePoint 2010站点集升级到SharePoint 2013具体步骤如下: 1) 先将你的SharePoint 2010原先的一些解决方案(wsp)安装到SharePoint 2013上。当然有些wsp你需要升级,这个我会在后期介绍...

yuxye
2015/12/19
0
0
在ASP.NET中如何用C#.NET实现基于表单的验证

这篇文章引用到了Microsoft .NET类库中的以下名空间: System.Data.SqlClient System.Web.Security ------------------------------- 任务: 摘要: 1.要求...

晨曦之光
2012/03/09
458
0
基于MVC的优点Advantages of an MVC-Based Web Application

ASP.NET MVC 框架具有以下优点: 它很容易通过将应用程序划分为模型、 视图和控制器管理的复杂性。 它不使用视图状态或基于服务器的窗体。这使得 MVC 框架特别适合开发人员想要完全控制应用程...

donny945
2015/07/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

【Flutter教程】从零构建电商应用(一)

在这个系列中,我们将学习如何使用google的移动开发框架flutter创建一个电商应用。本文是flutter框架系列教程的第一部分,将学习如何安装Flutter开发环境并创建第一个Flutter应用,并学习Flu...

笔阁
18分钟前
5
0
什么是以太坊DAO?(三)

Decentralized Autonomous Organization,简称DAO,以太坊中重要的概念。一般翻译为去中心化的自治组织。 投票支付合约的所有费用和行动需要时间,并要求用户始终保持活跃,知情和专注。另一...

geek12345
20分钟前
2
0
一个本科学生对Linux的认知

一个本科学生对Linux的认知 我是一名大三的普通一本大学的软件工程的一名学生,学校开设了一些关于系统开发的课程,纸上得来终觉浅,学校的课程课时较短,想要在56个课时之内学会一些公司需要...

linuxCool
今天
3
0
CentOS 安装Tomcat

Tomcat 介绍 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。 Java 程序写的网站用tomcat+jdk来运...

野雪球
今天
1
0
OSChina 周四乱弹 —— 每天都迟到是种什么样的体验

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @开源中国首席机器人 :《Too Good At Goodbyes (Acoustic) - Sam Smith - 单曲》 《Too Good At Goodbyes (Acoustic) - Sam Smith - 单曲》 ...

小小编辑
今天
798
13

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部