zoukankan      html  css  js  c++  java
  • [FBA]SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用

    //http://tech.ddvip.com/2014-05/1401197453210723.html

    由于项目的需要,登录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:WindowsMicrosoft.NETassembly。.NET 3.5 GAC在C:Windowsassembly,所以别找错地方。Assembly成功注册到GAC后,最好IISReset下。

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

    • 自定义MembershipProvider,主要代码如下:

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    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,如下所示:

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    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();
           }<br>}
    • 自定义的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节点,将以下代码复制进:

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <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,

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <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,

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <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(原始版本,从未更新过)。如果解决的话,劳烦各位朋友告诉我一下。点击代码下载

  • 相关阅读:
    OpenJDK源码研究笔记(十二):JDBC中的元数据,数据库元数据(DatabaseMetaData),参数元数据(ParameterMetaData),结果集元数据(ResultSetMetaDa
    Java实现 LeetCode 257 二叉树的所有路径
    Java实现 LeetCode 257 二叉树的所有路径
    Java实现 LeetCode 257 二叉树的所有路径
    Java实现 LeetCode 242 有效的字母异位词
    Java实现 LeetCode 242 有效的字母异位词
    Java实现 LeetCode 242 有效的字母异位词
    Java实现 LeetCode 241 为运算表达式设计优先级
    Java实现 LeetCode 241 为运算表达式设计优先级
    Java实现 LeetCode 241 为运算表达式设计优先级
  • 原文地址:https://www.cnblogs.com/TNSSTAR/p/3982036.html
Copyright © 2011-2022 走看看