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:该问题为本人研究结果,如果有什么错漏之处,欢迎各位大大指正^_^

 

  

时间: 2024-08-11 03:36:03

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

Oracle取月份-不带前面的0

出处:http://www.2cto.com/database/201208/145611.html 今天碰到只要取月份和天数,如果月份前面有0要去掉0.比如说2010-01-08 ,需要的结果是1-8. 引出了一系列的sql语句 第一: 利用to_number的函数转换自动截0 select to_number(to_char(sysdate,'mm'))||'-'||to_number(to_char(sysdate,'dd')) from dual; 第二: 利用ltrim函数加固定参数去

({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 'aspnet:AllowAnonymousImpersonation'. You can enable this setting by adding the following section to the Web.config file: <appSettings> <add key=

全程真实数据对接 带你从0开发前后端分离的企业级上线项目

<ignore_js_op> 第1章 课程介绍(2018配套教程:电商前端+电商后端+电商权限管理系统课程)本章中会先让大家了解课程整体情况,然后手把手带大家做一些开发前的准备工作.后台管理系统测试账号和密码(切勿修改,导致其他同学体验不了)        账号:admin 密码:admin (Java一期课程ID:96,Java二期进阶课程ID:162,权限系统课程:ID:149,http://coding.imooc.com/class/XXX.html ,访问时将前面网站中的XXX换成.

12-带内管理、带外管理 //0.8.6(GNS3版本)

带内管理.带外管理区别:流量在一根线上走就是带内管理,有Console线就是带外管理![]一.实验拓扑:二.实验要求:1.R1.R2.R3运行EIGRP 90协议,并配置各自的Loopback,用来测试:2.R1.R2.R3分别各自创建远程Telnet登录,并调用本地数据库验证:Login local3.验证:查看.清除.挂起Telnet连接:4.用电脑本地的CMD命令远程登录路由器,并验证上述命令.三.命令部署:1.基本命令部署:R1(config)#username aa password

SharePoint 2010升级到sharePoint 2013后,人员失去对网站的权限的原因及解决方法。The reason and solution for permission lost after the upgrading

昨天碰到了一个问题,一个网站在从SharePoint 2010升级到SharePoint 2013后,人员都不能登录了,必须重加赋权,人员才能登录,这样非常麻烦. 原因:是认证方式的问题.在SharePoint 2010中,通过管理中心新建web application的时候,就会发现提供了两种不同的认证方式,第一种是classic auth(也就是我们通俗的称为windows 认证,其实这种叫法也不全面),另一种是claim base auth. 而当时claim base的认证方式微软还没有

LAMP安装(一)关于Apache的源码安装

什么是LAMP      LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写: Linux,操作系统 Apache,网页服务器 MariaDB或MySQL,数据库管理系统(或者数据库服务器) PHP.Perl或Python,脚本语言 LAMP框架我们需要的源码包如下: Apache=http://httpd.apache.org/                                                      httpd主程序包 MySQL=h

linux命令:编译安装httpd、mysql、php等LAMP环境

Httpd 2.4新特性: 1.MPM可于运行时装载: --enable-mpms-shared=all --with-mpm=event  编译安装是指定MPM运行模块为event 2.Event MPM 支持event新的多路处理模块 3.异步读写 4.在每模块及每目录上指定日志级别 5.每请求配置: <If>,<ElseIf>,<Else>; 6.增强的表达式分析器: 7.毫秒级的Keepalive Timeout; 8.基于域名的虚拟主机不再需要NameVirt

BZOJ2115:[WC2011]Xor——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=2115 https://www.luogu.org/problemnew/show/P4151 这道题当年还是新题,现在都成线性基套路题了. 参考:https://blog.sengxian.com/algorithms/linear-basis 一个1~n路径值可以拆成一条1~n的路径值^几个环(因为去到环和回来的路的值被异或回去了). 于是就变成了处理出所有环的异或值和所有1~n的无环路的异或

Sharepoint claim认证的login name

当SharePoint网站开启了Claims认证后,取回来的user的loginname是一个奇怪的字符串,这个到底是什么意思那? 这篇文章详细解释了: https://blogs.msdn.microsoft.com/svarukala/2014/03/26/saml-claims-user-id-format/ 拷贝如下: SAML Claims User Id Format I was working with a customer and shared this information