环境信息:

  带有Form base authentication(FBA)、Active Directory Federation Services(ADFS)、以及windows Authentication的混合认证的SharePoint环境。

问题具体描述:

  在该环境中,调用EnsureUser添加一个普通的AD user,sharepoint 会throw "The specified user userLoginName could not be found.",当然此处的user login name是不带有claim(i:0#.w|),具体如下图显示:

查看问题原因过程:

  其实在刚刚看到该问题时,我首先查看了sharepoint log,但是log中并没有发现什么有用的信息,在这之后我测试了对带有claim(i:0#.w|)的user login name进行EnsureUser 操作,发现对于带有claim(i:0#.w|)的user 是可以正常添加到sharepoint 中的,通过这点,我们基本上可以断定问题应该是混合认证导致的,但是仅仅是这样当然是不够的,我们需要分析出问题的根本原因,为什么带有claim的user 能够正常添加到sharepoint环境中,而不带有claim的却会throw exception呢?

  问题分析到这里单单调用SharePoint API已经无法帮助我们了,这时就需要祭出神器:Reflector 来分析EnsureUser 这个方法,查看sharepoint 内部的逻辑,以查找该问题的根本原因,具体的分析过程就不在这里赘述了,无非就是静下心来啃微软的Code。

  这里简单讲解下在EusuerUser时claim对于UserLoginName的意义:

  如果UserLoginName带有claim(i:0#.w|domain\userName):EnsureUser方法内部会根据该claim生成SPClaim对象,该对象指定了provider的类型,因此,SharePoint可以通过SPClaim对象对当前环境中可用的provider进行过滤,只有符合SPClaim.ClaimType的provider,才会尝试获取user信息。

  如果UserLoginName没有claim(domain\userName):由于没有claim,无法创建 SPClaim对象,那么只能根据EnsureUser方法内部传入的SPPrincipalType(EnsureUser方法内部传入的是SPPrincipalType.SecurityGroup|SPPrincipalType.User)来对provider进行过滤,只要支持这两种type的provider都会尝试获取user信息,而通过SPClaim过滤provider显然要比通过SPPrincipalType过滤要精确的多(这里有一点需要注意:对于大批量的EnsureUser,建议使用带有cliam的userLoginName格式,这样可以更精确的定位provider,进而更少的调用provider resolve user,进而提高EnsureUser的效率。

  说了这么多貌似和我们的问题没有什么关系,我们要添加的user就是一个普普通通的ad user,windows authentication对应的provider应该是可以获取到这个user的,但是为什么却会throw exception呢?

  我们认为windows authentication对应的provider可以通过user login name获取到user信息,而SharePoint实际上并没有获取到user信息,既然与我们认为的不一致,那就有必要写程序验证一下到底能不能获取到这个user的信息了,通过之前分析EnsuerUser 方法内部的代码,我找到了SharePoint内部调用provider resolve user的方法,见截图:

该方法为EnsureUser内部调用的方法,而它的作用就是调用provider的Resolve方法来获取user,这样问题就简单了,我们反射模拟下该方法来确认provider能否通过login name取到user就行了,反射模拟的代码比较简单,这里就不做赘述了,直接上结果:

注意绿色部分为provier获取到的user信息,通过结果我们可以发现windows authentication对应的provider实际上已经获取到了相关的user信息,并且返回的user login name已经是带有claim的格式了,既然获取到了user信息为什么EnsureUser 方法会不好使呢?实际上问题到这里就比较明显了,通过结果,我们会发现不仅仅是windows authentication对应的provider获取到了user 信息,ADFS对应的provider也同样的获取到了user的信息(这是ADFS正常的正常逻辑,对于ADFS来说不论查询的user是否存在,都会返回一个user,如果想避免该问题,可以配置LDAP,具体配置方法见传送门:LDAP配置方法),既然我们认定是混合认证导致不带有claim的AD user无法正常添加,那么会不会是因为ADFS也获取到了user信息导致的问题呢?,我们再回头看看EnsureUser方法内部的逻辑,应该不难找到这个方法:

注意截图中的两个红框,第一个红框实际上就是我们刚才反射模拟的方法,该方法把最终获取到的user相关信息的结果保存在entityArray中,而下一个红框实际上是对entityArray的一些特殊处理,通过这个特殊处理我们不难看出只有entityArray.lenth==1时,才会将provider获取到的user信息转换成SPPrincipalInfo对象,而如果不满足红框中的if条件,那么就会执行红框下的if语句(if(info == null) info=user;),但是实际上user是null,这样ResolvePrincipalClaims方法获取到的info对象也是一个unll值,自然也就无从谈起将user添加到SharePoint中了,进而会throw "The specified user userLoginName could not be found."。

总结一下该问题的原因:该问题实际上是由于SharePoint环境中存在多种认证方式,导致在调用API添加user时,SharePoint通过各个provider对于同一个user name获取到了多个user,但是SharePoint并不知道我们到底想将哪个user添加到SharePoint中,因此倒不如哪个user也不添加,进而导致添加user失败。

PS:该问题为本人研究结果,如果有什么错漏之处,欢迎各位大大指正^_^

 

  

SharePoint Claim base authentication EnsureUser 不带claim(i:0#.w|)user Failed的更多相关文章

  1. [SharePoint]SharePoint Claim base Authentication的一个比较好的介绍

    User identity in AD DS is based on a user account. For successful authentication, the user provides ...

  2. SharePoint 2010 Form Authentication (SQL) based on existing database

    SharePoint 2010 表单认证,基于现有数据库的用户信息表 本文主要描写叙述本人配置过程中涉及到的步骤,仅作为參考,不要仅限于此步骤. 另外本文通俗易懂,适合大众口味儿. I. 开启并配置基 ...

  3. Authentication to host '***‘' for user 'root' using method 'mysql_native_password' failed with message: Reading from the stream has failed.

    如下场景: 一个页面中需要用户填入文字信息,并上传图片,上传图片是单独调用上传文件接口的,当用户上传图片后,马上点保存,就会报错. Authentication to host '***‘' for ...

  4. Exception in thread "main" java.lang.UnsupportedClassVersionError: com/google/common/base/Function : Unsupported major.minor version 52.0的解决办法(图文详解)

    不多说,直接上干货! 问题详情 Exception in thread "main" java.lang.UnsupportedClassVersionError: com/goo ...

  5. .NetCore中如何实现权限控制 基于Claim角色、策略、基于Claim功能点处理

    .NetCore中如果实现权限控制的问题,当我们访问到一个Action操作的时候,我们需要进行权限控制 基于claims 角色控制 基于角色控制总觉得范围有点过大,而且控制起来感觉也不是太好,举一个例 ...

  6. Oracle取月份-不带前面的0

    出处:http://www.2cto.com/database/201208/145611.html   今天碰到只要取月份和天数,如果月份前面有0要去掉0.比如说2010-01-08 ,需要的结果是 ...

  7. SharePoint 2016 安装 Cumulative Update for Service Bus 1.0 (KB2799752)报错

    前言 SharePoint 服务器场安装workflow manager 1.0的时候,报下面的错误,搜了很多博客都没有解决.然后,灵机一动,下载了一个英文版的累计更新包,安装成功了. SharePo ...

  8. ({i:0#.w|nt authority\iusr})Sharepoint impersonates the IUSR account and is denied access to resources

    This hotfix makes a new application setting available in ASP.NET 2.0. The new application setting is ...

  9. 开放Fedora10自带的MySQL5.0.67的对外数据库服务

    MySQL5.0.67是Fedora10安装时的可选项目. 测试的笔记本IP为192.168.0.100,作为安装Fedora10和MySQL5.0.67的服务器BlackMachine的IP地址为1 ...

随机推荐

  1. Mybatis环境

    第一步:下载jar包并导入 1.mysql驱动包 2.mybatis环境包 第二步:创建MYSQL数据库 由于这是用于测试,只创建了test-usreinfo数据表 第三步:在src文件夹中创建myb ...

  2. iOS学习15之OC集合

    1.数组类 1> 回顾C语言数组 数组是一个有序的集合, 来存储相同数据类型的元素. 通过下标访问数组中的元素,下标从 0 开始. 2> 数组 数组是一个有序的集合,OC中的数组只能存储对 ...

  3. git基础

    1.新的未跟踪文件 新创建的README文件没有进行任何跟踪 $ git status On branch master Untracked files: (use "git add < ...

  4. Myeclipse怎么连接MySQL数据库?

    1.打开  >>  Myeclipse 2.Window  >>  Open Perspective  >>  Myeclipse Database Explore ...

  5. 前端开发必学技能之一———非关系数据库又像关系数据库的MongoDB快速入门第一步下载与安装

    数据库总的来说,分为两个方向:关系数据库和非关系数据库.我们常见的MySQL.Oracle.SQLSerever以及IBMDB2都是属于关系数据库,这里的关系值得是二维表的结构,但是由于随着web的应 ...

  6. PL/SQL配置Oracle数据库路径

    打开PL/SQL-Tools->Preferences-Orcacle->Connecttion 找到配置路径,打开-product\instantclient_11_2\NETWORK\ ...

  7. 运行nltk示例 Resource u'tokenizers punkt english.pickle' not found解决

    nltk安装完毕后,编写如下示例程序并运行,报Resource u'tokenizers/punkt/english.pickle' not found错误 import nltk sentence ...

  8. Bluemix中国版体验(一)

    很高兴终于拿到了中国版Bluemix的账号!中国版的Bluemix是由世纪互联运营的,这也是世纪互联继Microsoft Azure,Office 365之后运营的又一个国际一线大品牌的云服务. 中国 ...

  9. plain framework 1 1.0.4 更新 稳定版发布

    PF由于各种因素迟迟不能更新,此次更新主要是更新了以往和上个版本出现的内存问题,该版本较为稳定,如果有用到的朋友请更新至此版本. PF 1.0.4 修复1.0.0.3更新后产生的内存问题,可能导致网络 ...

  10. 记一次与a标签相遇的小事

    最近做的一个项目,按钮使用的是a标签做的,样子还不错.不过正是这个a标签把我坑死了,有一个场景是点击a标签去调后台服务,为了防止用户频繁点击按钮提交,在去请求后台服务的时候肯定要先把按钮的事件给禁止掉 ...