环境信息:

  带有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. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  2. 11、项目经理要阅读的书籍 - IT软件人员书籍系列文章

    项目经理是负责软件项目的总体把控的角色.项目经理在项目中是一个管理者的角色,他需要对项目的9大领域进行学习,同时针对项目的范围.进度.沟通和风险进行处理,让项目能够按时保质保量的完成. 项目经理需要学 ...

  3. although 和 although 的区别

    作为连词的时候,although 和 though 是可以互换的.Although 一般被认为更加正式一些.比如,以下的这些句子: Growth in Europe is maintaining mo ...

  4. Hadoop技巧(03):HostName命名带来的问题

    阅读目录 序 HostName 问题 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink ...

  5. sys.dm_os_waiting_tasks 引发的疑问(中)

    上一篇我们说了一下sys.dm_exec_requests 和 sys.dm_os_waiting_tasks 在获取并行等待的时候得不同结果,这一篇我们谈论下我的第二个疑问:为什么一个并行计划(4线 ...

  6. Nginx 访问日志轮询切割

    Nginx 访问日志轮询切割脚本 #!/bin/sh Dateformat=`date +%Y%m%d` Basedir="/application/nginx" Nginxlog ...

  7. FTP概述

    FTP是什么? 早期三大网络应用之一:ftp(40年).http.mail ftp file transfer protocol 文件传输协议 FTP服务概述 C/S模型 客户端-服务器 FTP采用双 ...

  8. USACO . Your Ride Is Here

    Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs often co ...

  9. EL表达式杂项

    1.<%@ page isELIgnored="false" %> 是否忽略EL表达式,如果值为ture,那么  ${..}这样的会直接原样输出,不会进行EL表达式计算 ...

  10. 前端之JavaScript基础

    前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...