文档章节

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

 木宛城主
发布于 2015/03/02 19:42
字数 1451
阅读 6
收藏 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
基于MVC的优点Advantages of an MVC-Based Web Application

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

donny945
2015/07/03
0
0
ASP.NET 配置节架构

ASP.NET 配置节架构包含控制 ASP.NET Web 应用程序行为的元素。如果为属性指定了默认值,则该默认值是在 Machine.config 文件中设置的,该文件的路径是 systemroot/Microsoft.NET/Framework...

晨曦之光
2012/03/09
78
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS 7.* 配置网络

配置静态IP 进入配置文件目录 cd /etc/sysconfig/network-scripts 查找以 ifcfg-eno 开头的文件并编辑它 vi ifcfg-ens32 修改文件中的变量值 BOOTPROTO=staticONBOOT=yesIPADDR=192.168...

阿白
47分钟前
0
0
深入理解OAuth2.0协议

1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间。是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题。豪车一般配备两种钥匙:主钥匙和泊...

xtof
51分钟前
1
0
Linux学习-0920

3.4 usermod命令 3.5 用户密码管理 3.6 mkpasswd命令 一、usermode命令 usermode作用是用来修改用户信息。 方法: usermod 参数 username 示例1:修改用户uid usermod -u 1010 test5 示例2...

wxy丶
今天
1
0
synchronized锁对象的坑

今天本来写点其他东西,碰巧写了一下synchronized,没想到掉坑里面了,大佬别笑。 起初代码大概是这样的: package com.ripplechan.part_1_2_3;import java.util.concurrent.CountDownL...

RippleChan
今天
1
0
XAMPP环境搭建(Apache + MariaDB + PHP + Perl)

operation system:ubuntu-18.04.1 step1:download XAMPP #sudo wget https://www.apachefriends.org/xampp-files/7.2.9/xampp-linux-x64-7.2.9-0-installer.run step2:install XAMPP #sudo ......

硅谷课堂
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部