文档章节

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

 木宛城主
发布于 2015/03/02 19:38
字数 1451
阅读 3
收藏 0
点赞 0
评论 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

Video : 将使用AD认证的SharePoint网站配置为表单方式登录

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

余二五 ⋅ 2017/11/22 ⋅ 0

sharepoint2010 升级到 sharepoint2013注意事项

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

yuxye ⋅ 2015/12/19 ⋅ 0

基于MVC的优点Advantages of an MVC-Based Web Application

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

donny945 ⋅ 2015/07/03 ⋅ 0

ASP.NET 配置节架构

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

晨曦之光 ⋅ 2012/03/09 ⋅ 0

Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block

开发人员经常编写需要安全功能的应用程序。这些应用程序通常需要执行一系列不同的安全操作,而且它们还经常与不同的基础安全提供程序(如 Microsoft Active Directory 目录服务、授权管理器、...

老朱教授 ⋅ 2017/10/08 ⋅ 0

在ASP.NET中如何用C#.NET实现基于表单的验证

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

晨曦之光 ⋅ 2012/03/09 ⋅ 0

web.config文件详解

(一).Web.Config是以XML文件规范存储,配置文件分为以下格式 1.配置节处理程序声明 特点: 位于配置文件的顶部,包含在标志中。 2.特定应用程序配置 特点: 位于中。 可以定义应用程序的全局常...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

[本周] 就来说说Asp.net 身份验证、授权

[本周]如约而至;时间是争取来的,这回的[本周]是把若干零碎的时间利用起来成文的,完成对Asp.net身份验证、访问授权等内容的梳理,可能漏掉的东西会比较多,漏掉的还是希望大家来补充。顺便说...

唐玄奘 ⋅ 2017/12/03 ⋅ 0

Spring Security Kerberos 1.0.0.RC2 发布

Spring Security Kerberos 1.0.0.RC2 发布,此版本主要改进如下: 增加支持 LdapContextSource 包的二次使用具有更好的管理属性 spring-security-kerberos-web 现在包含所有 Web 的相关属性(...

oschina ⋅ 2015/04/03 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

win10怎么彻底关闭自动更新

win10自带的更新每天都很多,每一次下载都要占用大量网络,而且安装要等得时间也蛮久的。 工具/原料 Win10 方法/步骤 单击左下角开始菜单点击设置图标进入设置界面 在设置窗口中输入“服务”...

阿K1225 ⋅ 57分钟前 ⋅ 0

Elasticsearch 6.3.0 SQL功能使用案例分享

The best elasticsearch highlevel java rest api-----bboss Elasticsearch 6.3.0 官方新推出的SQL检索插件非常不错,本文一个实际案例来介绍其使用方法。 1.代码中的sql检索 @Testpu...

bboss ⋅ 今天 ⋅ 0

informix数据库在linux中的安装以及用java/c/c++访问

一、安装前准备 安装JDK(略) 到IBM官网上下载informix软件:iif.12.10.FC9DE.linux-x86_64.tar放在某个大家都可以访问的目录比如:/mypkg,并解压到该目录下。 我也放到了百度云和天翼云上...

wangxuwei ⋅ 今天 ⋅ 0

PHP语言系统ZBLOG或许无法重现月光博客的闪耀历史[图]

最近在写博客,希望通过自己努力打造一个优秀的教育类主题博客,名动江湖,但是问题来了,现在写博客还有前途吗?面对强大的自媒体站点围剿,还有信心和可能型吗? 至于程序部分,我选择了P...

原创小博客 ⋅ 今天 ⋅ 0

IntelliJ IDEA 2018.1新特性

工欲善其事必先利其器,如果有一款IDE可以让你更高效地专注于开发以及源码阅读,为什么不试一试? 本文转载自:netty技术内幕 3月27日,jetbrains正式发布期待已久的IntelliJ IDEA 2018.1,再...

Romane ⋅ 今天 ⋅ 0

浅谈设计模式之工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻...

佛系程序猿灬 ⋅ 今天 ⋅ 0

Dockerfile基础命令总结

FROM 指定使用的基础base image FROM scratch # 制作base image ,不使用任何基础imageFROM centos # 使用base imageFROM ubuntu:14.04 尽量使用官方的base image,为了安全 LABEL 描述作...

ExtreU ⋅ 昨天 ⋅ 0

存储,对比私有云和公有云的不同

导读 说起公共存储,很难不与后网络公司时代的选择性外包联系起来,但尽管如此,它还是具备着简单和固有的可用性。公共存储的名字听起来也缺乏专有性,很像是把东西直接堆放在那里而不会得到...

问题终结者 ⋅ 昨天 ⋅ 0

C++难点解析之const修饰符

C++难点解析之const修饰符 c++ 相比于其他编程语言,可能是最为难掌握,概念最为复杂的。结合自己平时的C++使用经验,这里将会列举出一些常见的难点并给出相应的解释。 const修饰符 const在c...

jackie8tao ⋅ 昨天 ⋅ 0

聊聊spring cloud netflix的HystrixCommands

序 本文主要研究一下spring cloud netflix的HystrixCommands。 maven <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-clo......

go4it ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部