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 ...
随机推荐
- React Native APP结构探索
APP结构探索 我在Github上找到了一个有登陆界面,能从网上获取新闻信息的开源APP,想来研究一下APP的结构. 附上原网址:我的第一个React Native App 具体来讲,就是研究一个复杂 ...
- Atitit linux获取项目运行环境版本
Atitit linux获取项目运行环境版本 1.1. Nginx版本1 1.2. Php版本1 1.3. Mysql版本2 1.4. Redis版本2 1.1. Nginx版本 [root@iZ25 ...
- spring加载配置文件
spring加载配置文件 1.把applicationContext.xml直接放在WEB-INF/classes下,spring会采用默认的加载方式2.采用在web.xml中配置ContextLoa ...
- SSIS 实例——将SQL获取的信息传递到Email中
最近在为公司财务开发一个邮件通知时遇到了一个技术问题.原来我设计SSIS的是每天将ERP系统支付数据导出到财务支付平台后 Email 通知财务,然后财务到支付平台上进行支付操作.由于那个时候开发时间很 ...
- Couchbase 环境搭建与使用(C#)
Couchbase Couchbase Server (前身是 Membase) 是一个分布式的面向文档的 NoSQL 数据库管理系统,该系统联合了 CouchDB 的简单和可靠以及 Memcache ...
- Windows7 忘记密码的解决办法
由于无法使用管理员帐号进入Windows 7,辅助工具比较大,已经回不到xp时代的pe一键删除密码了,不过用Windows 7的system账户运行cmd命令可以强制修改账户密码!就拿xp+Windo ...
- [转]An introduction to OAuth 2.0 using Facebook in ASP.NET Core
本文转自:http://andrewlock.net/an-introduction-to-oauth-2-using-facebook-in-asp-net-core/ This is the ne ...
- Ubuntu 一直掉线 以及连不上网 解决办法
新装了一个Ubuntu 系统16.04才使用的时候一切顺利 但是过了两三天 就会出现 频繁掉线的情况 于是上网找大神们的解决办法 把文件 /etc/ppp/options 里面的一个数值改大一点 l ...
- python下如何安装biopython
本来是自学python,后来又了解到有biopython这个包,将想安装下来,结果折腾了我一上午...终于安装成了,哈哈哈,功夫不负有心啊 过程如下: 1.首先去http://biopython.or ...
- Linux 信号量详解一
信号量主要用于进程间(不是线程)的互斥,通过sem_p()函数加锁使用资源,sem_v函数解锁释放资源,在加锁期间,CPU从硬件级别关闭中断,防止pv操作被打断. semget函数 int semge ...