SharePoint Claim base authentication EnsureUser 不带claim(i:0#.w|)user Failed
环境信息:
带有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的更多相关文章
- [SharePoint]SharePoint Claim base Authentication的一个比较好的介绍
User identity in AD DS is based on a user account. For successful authentication, the user provides ...
- SharePoint 2010 Form Authentication (SQL) based on existing database
SharePoint 2010 表单认证,基于现有数据库的用户信息表 本文主要描写叙述本人配置过程中涉及到的步骤,仅作为參考,不要仅限于此步骤. 另外本文通俗易懂,适合大众口味儿. I. 开启并配置基 ...
- Authentication to host '***‘' for user 'root' using method 'mysql_native_password' failed with message: Reading from the stream has failed.
如下场景: 一个页面中需要用户填入文字信息,并上传图片,上传图片是单独调用上传文件接口的,当用户上传图片后,马上点保存,就会报错. Authentication to host '***‘' for ...
- 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 ...
- .NetCore中如何实现权限控制 基于Claim角色、策略、基于Claim功能点处理
.NetCore中如果实现权限控制的问题,当我们访问到一个Action操作的时候,我们需要进行权限控制 基于claims 角色控制 基于角色控制总觉得范围有点过大,而且控制起来感觉也不是太好,举一个例 ...
- Oracle取月份-不带前面的0
出处:http://www.2cto.com/database/201208/145611.html 今天碰到只要取月份和天数,如果月份前面有0要去掉0.比如说2010-01-08 ,需要的结果是 ...
- SharePoint 2016 安装 Cumulative Update for Service Bus 1.0 (KB2799752)报错
前言 SharePoint 服务器场安装workflow manager 1.0的时候,报下面的错误,搜了很多博客都没有解决.然后,灵机一动,下载了一个英文版的累计更新包,安装成功了. SharePo ...
- ({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 ...
- 开放Fedora10自带的MySQL5.0.67的对外数据库服务
MySQL5.0.67是Fedora10安装时的可选项目. 测试的笔记本IP为192.168.0.100,作为安装Fedora10和MySQL5.0.67的服务器BlackMachine的IP地址为1 ...
随机推荐
- iOS 如何使用Safari浏览器打开app
1.首先在info.plist添加一个键值对,如下图 或 2.在appdelegate.m文件如下方法写代码 -(BOOL)application:(UIApplication*)app openUR ...
- Android中隐藏顶部状态栏的那些坑——Android开发之路3
Android中隐藏顶部状态栏的那些坑 先看看常规的隐藏状态栏的方法: 方法一: @Override protected void onCreate(Bundle savedInstanceState ...
- 关于sql中in 和 exists 的效率问题,in真的效率低吗
原文: http://www.cnblogs.com/AdamLee/p/5054674.html 在网上看到很多关于sql中使用in效率低的问题,于是自己做了测试来验证是否是众人说的那样. 群众: ...
- Windows Server 2012 虚拟化实战:SCVMM的安装和部署
本篇大概介绍一下在Windows Server 2012 R2上安装和部署SCVMM的过程及其注意事项.下图是我们数据中心SCVMM的基本架构,其中 SCVMM Database 是用于存储了所有配置 ...
- Linux 关于Transparent Hugepages的介绍
透明大页介绍 Transparent Huge Pages的一些官方介绍资料: Transparent Huge Pages (THP) are enabled by default in RHEL ...
- springMVC异常&&重定向&&转发
SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...
- Appium+python的一个简单完整的用例
最近一直在忙,终于有时间来整理一下,传一个简单的用例,运行之后可以看到用例的报告,希望对大家有帮助. HTMLTestRunner这个包网上有很多,大家可以自己下载. 1 import unittes ...
- 《Google软件测试之道》基础
<Google软件测试之道>,一直听朋友讲起这本书,出于琐事太多,一直没机会拜读,最近部门架构觉得我们IT部门的技术太low,就给我们挑选了一些书籍,让我们多看看... 个人的一种学习习惯 ...
- 启用SQLite的Data Provider 运行WECOMPANYSITE时遇到ERROR CREATING CONTEXT 'SPRING.ROOT': ERROR THROWN BY A DEPENDENCY OF OBJECT 'SYSTEM.DATA.SQLITE'
从网上下载的源码WeCompanySite,运行时报错 Error creating context 'spring.root': Error thrown by a dependency of ob ...
- 数据库 数据库SQL语句二
单行函数 --操作数据对象 --接受参数返回一个结果 --只对一行进行变换 --每行返回一个结果 --可以转换数据类型 --可以嵌套 --参数可以是一列或一个值 字符函数 SQL> select ...