关于如何在Android、Java等非微软平台上建立高信任的SharePoint应用程序
关于如何在非微软平台上建立高信任的SharePoint应用程序
原文 :http://blogs.msdn.com/b/kaevans/archive/2014/07/14/high-trust-sharepoint-apps-on-non-microsoft-platforms.aspx
1.前言
当你去建立一个SharePoint 2013应用程序时,Visual Studio 2013,会让你选择:
1、使用Azure ACS
2、使用一个证书
这个选项就意味着在问,目标 SharePoint 服务器场如何定义信任设置,并把相关设置保存在Web.config文件中。要么你使用低信任ACS设置“client ID”和"client secret"或是使用高信任来设置"client ID" 、"证书路径"和“证书密码”。
2.理解OAuth和信任
通过这个PodCast, Office 365 Developer Podcast: Episode 002 with Radi Atanassov, Radi 详述了SharePoint 使用OAuth ,并且把它形象地称为 “三角验证” ,当把应用设置成使用Azure ACS的时候,应用需要去与ACS通信,提供一个“Refresh Token”,并且获得一个Access Token, “Refresh Token” 是应用程序从SharePoint 的服务器取得的,但这个"Refresh Token" 也是Azure ACS 之前发给SharePoint的。在这个模式下, 应用程序和SharePoint服务器, 不直接相信对方,而是通过Azure ACS 建立两两信任关系, 所以我们叫这“低信任”. 如果要更进一步理解这种“OAuth舞步”, 去这个URL 看我们的2013 session, Understanding Authentication and Permissions with Apps for SharePoint and Office,
低信任模型既可以被Office 365使用也可以被独立的SharePoint 2013服务器使用。
可残酷的现实,总是发生!很多客户根本没有办法去设置企业内部的SharePoint 2013与Azure ACS通信,因为Azure ACS是微软的服务器,(企业内部的SharePoint 2013不允许连接外网,就算SharePoint 2013可以连外网有些国家也有防火墙不允许访问国外某些网站)。很好!产品团队于是可以不选择Azure ACS,作为专业人士的我们也要清楚,对于OAuth 2.0来说,Azure ACS实现了S2S协议那可是微软王国标准的OAuth 2.0作法,那是有国际范的。在“高信任”的认证方案里, 因为我们考虑到SharePoint 服务器与APP 是2个非常铁的哥们,不需要第三方去保证什么。APP 使用X.509证书去给“TOKEN”签名,然后SharePoint 再对这个签字进行信任。
“高信任”,并不代表“高授权”,不是说APP可以直接去删除或是干掉服务器里的东西,“授权”还是通过使用APP的这个人来决定的。 只不过APP可以操纵OAuth2 access token创建的过程,不需要微软的ACS服务器来搞定。SharePoint 场的管理员使用公钥注册一个“信任的安全TOKEN颁发者” SPTrustedSecurityTokenIssuer, 然后App 使用这个证书的私钥 签名,正因为私钥的特性,所以 SharePoint 会信任这个APP。可喜的是独立的服务器可以选择2者,而Office 365的APP是没有办法使用“高信任” 模式的, 因为作为一个微软开发者的你,黑不到OFFICE 365的服务器里去创建证书!.
再说了:人家微软的Office 365不信任微软的ACS服务,难道信任你的APP不成。
3.低信任APP与非微软平台
如果你开发基于Office 365的程序上,哥劝你就直接使用“低信任APP”,这也简单,对于APP开发者的你也不管签名发证书的事情,在网页上申请Client ID和 Client Secret后,在你的代码里就是写几个程序保存一Token之类,就行了。网上这种文章,多如牛毛,例如:1. Todd Baginski 对于Node.js 上开发SharePoint 作了非常精彩的演讲。也发布了示例PHP操纵SharePoint 2013 SharePoint 2013: Perform operations on SharePoint Document Library from PHP site. 在这个模型里,要用到 JWT library 库去解析 由 SharePoint 发给你的context token ,过程就是得到 ACS URL, 把Refresh token 提交去得到access token.2. 同样,对于你自主的SharePoint网站创建一个低信任APP也是很有可能的,下面的文章真是大拿之作:如何使用Office 365去验证一个自主SharePoint 网站的提供商承APP。
在这个模型里,你创建一个Office365的tenant,然后创建一个信任从你的服务器到Office 365的服务器,你不需要对于Office 365做任何配置,你只是需要它去读取Azure ACS给你预备的命名空间。一但配置好,无论它是不是微软平台,你就可以使用Client ID和Client Secret. 在自主的SharePoint服务场配置完毕后,你不需要担心管理X.509证书或是证书颁发者的问题,你也不需要担心开发人员有X.509密码,可能引起的安全问题,看了这篇文章,你就有点怀疑我们为啥非要搞出一个“高信任”模式呢??
-
创建一个ACS代理(在你的独立SharePoint 服务器场)
-
安装你的SharePoint的签字证书到你Office 365的tenancy.
-
把合格的域名加入到你SharePoint 2013场(这个场你想去运行APP),在你的Office 365 tenancy服务的princels名称.
-
在你的服务器场,创建一个APP管理代理。
无论你用什么样的技术建立APP,Visual Studio 、ASP.NET MVC running on IIS 或是 Azure Web Sites,或是使用Eclipse 或是 Tomcat (Apache and Linux), 这个注册的步骤,是完全一样的,如下的命令必须由管理员在控制台的界面中完成,主要的目的就是完成X.509证书的信任配置:
- #Tell SharePoint to trust the certificate
- $publicCertPath = "C:\HighTrust.cer"
- $certificate = Get-PfxCertificate $publicCertPath
- New-SPTrustedRootAuthority -Name "HighTrust" -Certificate $certificate
- #Get the tenant ID. For on-premises default installations,
- #this will be the same as the SharePoint farm ID
- $spweb = Get-SPWeb "https://mysite.contoso.com"
- $realm = Get-SPAuthenticationRealm -ServiceContext $spweb.Site
- #Specify the issuer ID
- $issuerID = "b77a601b-3133-4567-bb37-f147f61dd332"
- $fullIssuerIdentifier = $issuerId + '@' + $realm
- #Create a trusted security token issuer based on the certificate
- New-SPTrustedSecurityTokenIssuer -Name "Contoso S2S HighTrust Apps" -Certificate $certificate -RegisteredIssuerName $fullIssuerIdentifier IsTrustBroker
- #IISRESET is needed, otherwise settings won't be applied for 24 hours
- iisreset
完全的配置步骤,可以参考如下的文章:
“How to: Create high-trust apps for SharePoint 2013 (advanced topic)”. 这个APP将会使用证书,证书密码和颁发的ID去得到一个ACCESS TOKEN, Visual Studio提供了这样的工具去完成这个。
可悲呀! 非微软的程序,必须要去管理这些值,以去得到Access Token。
4. JWT Tokens
SharePoint 使用JWT tokens 来进行OAuth认证。可别让这个英文“token” 吓坏你这个好基友了,你就把这个东东当成非常非常非常(此处省略127字) 复杂的加密方式. JWT tokens 是 JSON 对象, 这意味着它就是name-value pairs这种形式,感兴趣你可以读读 The JWT specification draft 。
给SharePoint 的 access token 再介绍一次好了!再说一次! 她就是JWT token,
如何你还想了解它, 可以读读这个哦! “Creating a Fiddler Extension for SharePoint 2013 App Tokens”.
上面可以看到其明文就是一对对键-值,它有12小时的有效期,取得后你就可以“为所欲为”哦。。。。。。具体内容 如下表所示:
aud | Audience. The value is 00000003-0000-0ff1-ce00-00000000/<hostname>@<realm*> . The hostname is the FQDN of the web application root or the host-header site collection root. The realm is the GUID that represents the SharePoint tenant. |
iss | Issuer. <IssuerID>@<realm*>. The issuer ID is obtained when you register the SPTrustedIdentityTokenIssuer. The realm is the GUID that represents the SharePoint tenant. |
nbf | Not before. The Unix epoch time upon which the token started being valid. |
exp | Expires. The Unix epoch time upon which the token expires. |
nameid | The identifier for the user (more info below) |
nii | The identity provider used to rehydrate the user. One of the values: urn:office:idp:activedirectory urn:office:idp:forms:membershipprovidername trusted:samlprovidername (as noted in Steve Peschka’s example below, this is what is actually configured as opposed to the documentation) |
actortoken | The token for the application. |
* 现实又是可爱的,当你安装了SharePoint 2013, 只有一个tenant ID, realm与SharePoint farm ID又一样,可以通过PowerShell的命令:
Get -SPFarm | select ID 得到。
下面我们再搞定:actortoken. 这与outer token相反,actortoken 标识的是APP.
aud | Audience. The value is 00000003-0000-0ff1-ce00-00000000/<hostname>@<realm*> . The hostname is the FQDN of the web application root or the host-header site collection root. The realm is the GUID that represents the SharePoint tenant. |
iss | Issuer. <IssuerID>@<realm*>. The issuer ID is obtained when you register the SPTrustedIdentityTokenIssuer. The realm is the GUID that represents the SharePoint tenant. |
nbf | Not before. The Unix epoch time upon which the token started being valid. |
exp | Expires. The Unix epoch time upon which the token expires. |
nameid | Identifier for the app. <Client ID>@<realm>. The client ID uniquely identifies your app, this is provided by using AppRegNew.aspx or provided when registering an app in the Office Marketplace. |
Inner token, outer token…太奇怪了,哥就不翻译了,以免又错了, 看例子! 我们我假定使用这些值,这样容易理解一点,同样我们上例中的示例值,也是一样的:
SharePoint site | mysite.contoso.com |
SharePoint realm ID | 6305dc22-8cb8-4da3-8e76-8d0bbc0499a5 |
SPTrustedSecurityTokenIssuer issuer ID | b77a601b-3133-4567-bb37-f147f61dd332 |
Client ID | 06d847ca-011f-4965-ac1f-5ad14740ad89 |
最后, 解码TOKEN的代码我们使用了上例的示例值:
- {
- aud: 00000003-0000-0ff1-ce00-000000000000/mysite.contoso.com@6305dc22-8cb8-4da3-8e76-8d0bbc0499a5,
- iss: b77a601b-3133-4567-bb37-f147f61dd332@6305dc22-8cb8-4da3-8e76-8d0bbc0499a5,
- nameid: s-1-5-21-3304015898-3601453682-3711364722-500,
- nii: urn:office:idp:activedirectory,
- nbf: 1320176785,
- exp: 1320219985,
- actortoken:
- {
- aud: 00000003-0000-0ff1-ce00-000000000000/mysite.contoso.com@6305dc22-8cb8-4da3-8e76-8d0bbc0499a5,
- iss: b77a601b-3133-4567-bb37-f147f61dd332@6305dc22-8cb8-4da3-8e76-8d0bbc0499a5,
- nameid: 06d847ca-011f-4965-ac1f-5ad14740ad89@6305dc22-8cb8-4da3-8e76-8d0bbc0499a5,
- nbf: 1320176785,
- exp: 1320219985,
- trustedfordelegation: true
- }
- }
看看你就会明白,拆开内容里面没有多少变量。
ACS模式的 S2S 协议号称是标准的 OAuth 2.0 模型,你也可以参考学习下: [MS-SPS2SAUTH]: OAuth 2.0 Authentication Protocol: SharePoint Profile.
5."高信任"APP 与非微软平台
好吧,兄弟是我误导你了,你如果这样还在坚持使用“高信任”APP,有些事情我还得和你交待清楚。 如果你不在微软平台下开发这种APP,你会发现找遍MSDN你都没有没有办法找到一个不使用TokenHelper.cs,的例子。而文件中的类,有巨长的代码,你根本无法把这个东东改造成非微软的一平台的代码。
TokenHelper.cs,真正的作用在于帮助你去解码和加密Jwt TOKEN。
当你创建一个新的APP,如果你使用Visual Studio ,它会自动很容易地自动化地帮你填上所有相关的 OAuth 对象和值的什么的。
这个类就是TokenHelper.cs,它即有方法可以让你通过Azure ACS 来使用“低信任” apps,也有方法去实现“高信任”
- public static string GetS2SAccessTokenWithWindowsIdentity(
- Uri targetApplicationUri,
- WindowsIdentity identity)
- {
- string realm = string.IsNullOrEmpty(Realm) ? GetRealmFromTargetUrl(targetApplicationUri) : Realm;
- JsonWebTokenClaim[] claims = identity != null ? GetClaimsWithWindowsIdentity(identity) : null;
- return GetS2SAccessTokenWithClaims(targetApplicationUri.Authority, realm, claims);
- }
- private static JsonWebTokenClaim[] GetClaimsWithWindowsIdentity(WindowsIdentity identity)
- {
- JsonWebTokenClaim[] claims = new JsonWebTokenClaim[]
- {
- new JsonWebTokenClaim(NameIdentifierClaimType, identity.User.Value.ToLower()),
- new JsonWebTokenClaim("nii", "urn:office:idp:activedirectory")
- };
- return claims;
- }
代码所做的,无非就是加了2个claim ,第1个叫nameid,它的值是sid,第2个叫nil, 告诉SharePoint如何去把nameid值映射到一个identity provider,在这个情况下,nil值就是“urn:office:idp:activedirectory”. 参数“nameid” 和“nii” 对SharePoint是特定的, 你可以把这2个声明(claim)加到 the JWT token.
6.值从哪来
TokenHelper.cs 是Visual Studio生成的,如果你使用其它的平台,你就必须改造. 值到哪里去的问题我们上一节已经搞定,现在我们就搞定值从哪里来的问题。
issuerid
当你创建注册SPTrustedSecurityTokenIssuer时,issuer ID就生成了,这是 GUID 全部小写.
Client ID
你通过 AppRegNew.aspx 注册APP时填的或是自动生成的。
realm
访问SharePoint 网站的如下url: “/_vti_bin/client.svc” ,在访问的时候加上这个的HTTP head: "Authorization: Bearer ". 参考TokenHelper.cs中的方式:
- public static string GetRealmFromTargetUrl(Uri targetApplicationUri)
- {
- WebRequest request = WebRequest.Create(targetApplicationUri + "/_vti_bin/client.svc");
- request.Headers.Add("Authorization: Bearer ");
- try
- {
- using (request.GetResponse())
- {
- }
- }
- catch (WebException e)
- {
- if (e.Response == null)
- {
- return null;
- }
- string bearerResponseHeader = e.Response.Headers["WWW-Authenticate"];
- if (string.IsNullOrEmpty(bearerResponseHeader))
- {
- return null;
- }
- const string bearer = "Bearer realm=\"";
- int bearerIndex = bearerResponseHeader.IndexOf(bearer, StringComparison.Ordinal);
- if (bearerIndex < 0)
- {
- return null;
- }
- int realmIndex = bearerIndex + bearer.Length;
- if (bearerResponseHeader.Length >= realmIndex + 36)
- {
- string targetRealm = bearerResponseHeader.Substring(realmIndex, 36);
- Guid realmGuid;
- if (Guid.TryParse(targetRealm, out realmGuid))
- {
- return targetRealm;
- }
- }
- }
- return null;
- }
上述代码很简单,转成你的平台的代码就行了,对于O365来说,它设计就是给很多云用户使用的,realm对每一个云用户是不同的。
有点意思: 如果你在“低信任”APP那节,配置了你的服务器与O365服务器之间的信任的话,realm的值是变化的哦。
nameid and niia
当配置“高信任” apps, MSDN 文档声明Web Application 必须使用 Windows Authentication. 记住在你的APP和SharePoint之间唯一的安全的通信就是JWT token在认证的头“Bearer ”,这是通过SSl传送的。当在TokenHelper中的代码使用WindowsIdentity所做的唯一事情就是得到SID,没有别的目标。所以,唯一的理由APP的Web Application要求使用Windows 验证方式,就是因为如何让TokenHelper.cs使用WindowsIdentity 对象得到用户的SID. 你可以改变TokenHelper.cs具体做法使用其它方法得到用户的SID.
前一节 “JWT Tokens” 介绍了nameid (outer token) 它的值是 SID, 从一个 WindowsIdentity 对象得到. 作为非微软技术大拿的兄弟你怎样去做,得到使用者的SID 呢?
1. 使用LDAP 这个模型去从Active Directory得到信息.
一个哥们用PHP搞定他了,您可以看看: PHP - Get users SID from Active Directory via LDAP.
2. 如果这个用户并不是AD中的怎么办? 我们可以使用 ADFS 或是 Ping 或是 其它一些 SAML provider, 我特别喜欢这个方式,你可以跟随我的做法,这用到 FBA 、SAML claims Steve Peschka 有文章, Using SharePoint Apps with SAML and FBA Sites in SharePoint 2013,这是使用 SAML or FBA 用户的话,这个方法怎么写。- private static JsonWebTokenClaim[] GetClaimsWithClaimsIdentity(
- System.Security.Principal.IPrincipal UserPrincipal,
- IdentityClaimType SamlIdentityClaimType, TokenHelper.ClaimsUserIdClaim id,
- ClaimProviderType IdentityClaimProviderType)
- {
- //if an identity claim was not found, then exit
- if (string.IsNullOrEmpty(id.ClaimsIdClaimValue))
- return null;
- Hashtable claimSet = new Hashtable();
- //you always need nii claim, so add that
- claimSet.Add("nii", "temp");
- //set up the nii claim and then add the smtp or sip claim separately
- if (IdentityClaimProviderType == ClaimProviderType.SAML)
- claimSet["nii"] = "trusted:" + TrustedProviderName.ToLower(); //was urn:office:idp:trusted:, but this does not seem to align with what SPIdentityClaimMapper uses
- else
- claimSet["nii"] = "urn:office:idp:forms:" + MembershipProviderName.ToLower();
- //plug in UPN claim if we're using that
- if (id.ClaimsIdClaimType == CLAIMS_ID_TYPE_UPN)
- claimSet.Add("upn", id.ClaimsIdClaimValue.ToLower());
- //now create the JsonWebTokenClaim array
- List<JsonWebTokenClaim> claimList = new List<JsonWebTokenClaim>();
- foreach (string key in claimSet.Keys)
- {
- claimList.Add(new JsonWebTokenClaim(key, (string)claimSet[key]));
- }
- return claimList.ToArray();
- }
上例中,它加入了 nameid 和nii 2个声明, nameid 被映射到了 UPN, email, 或是SIP. 在文章中,它解释也这3个属性的详细作用. 如何你的SharePoint 服务器使用 FBA 或是 SAML 来声明用户, 这个资源对你将非常有用! 最重要的是,这会加深你对“高信任”模式APP中如何使用用户配置文件服务的重要理解。 User Profile Service Application也很重要哦,兄弟你有兴趣多多研究下面2篇吧!
SharePoint 2013 User Profile Sync for Claims Users
OAuth and the Rehydrated User in SharePoint 2013 – How’d They do That and What do I Need to Know
正因为我们的APP运行在各种不用的平台上,甚至使用不用的验证架构所有很难保证用户都是使用AD的,既然SharePoint可以使用不同的用户那么你的程序也应该兼容,不是嘛?
7. X.509证书
当你创建一个“高信任”APP,如果你使用Visual Studio ,你必须提供一个路径去生成一个证书和证书密码,X.509 证书用于对Access Token进行签名。这个签名就像Oauth2的客户密码(client secret)的作用一样,在很高级别Json对象序列化成一个字串,这个字串是base64 Url编码的,然后再应用签名。 同样的步骤,在我们使用ACS 验证方式时也发生,不过这时用于签名的是client secret,所以你应该可以找到一个库用来形成JWT token然后还能进行签名的操作(当然是X.509)。
Visual Stdio 程序会在创建APP时,自动地引用 Microsoft.IdentityModel.Extensions. 我使用反编工具Telerik JustDecompile 反编了 Microsoft.IdentityModel.Extensions 我使用Visual Studio 2013 创建使用证书的SharePoint APP 的项目, 移除Microsoft.IdentityModel.Extensions, 添加上我自己的 Microsoft.IdentityModel.Extensions项目. 下面就 JWT token 创建和签名再进行一点扩展.步骤似乎是这样:
- JWT token 有2个部分:头、正文. 头指示了它的类型 (JWT) 和算法, 正文就像我们之前说的 access token那样 之间用点分隔 “.”
- 头被编码成JSON, 编码方式:base64UrlEncoded.
- 正文被编码成JSON, 编码方式:base64UrlEncoded.
- 2个base64UrlEncoded 值使用点连接 “.”
- 结果使用 X.509 证书,使用RSA SHA256 签名算法,和SHA256 数字算法.
- 上一步结果继续进行base64URLEncoded编码
- 第 4 步结果排在第6步结果前, 用点连接 “.”
这有点代码,让你可以理解这个过程:
- IDictionary<string, string> headerClaims = jwt.CreateHeaderClaims();
- IDictionary<string, string> payloadClaims = jwt.CreatePayloadClaims();
- string encodedHeader = Base64UrlEncoder.Encode(headerClaims.EncodeToJson());
- string encodedBody = Base64UrlEncoder.Encode(payloadClaims.EncodeToJson());
- string formattedClaims = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", encodedHeader, encodedBody);
- string encodedSignature = this.Sign(formattedClaims, jwt.SigningCredentials);
- return string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}", encodedHeader, encodedBody, encodedSignature);
这边的“jwt.SigningCredentials” 是什么? 你看看 TokenHelper.cs,就知道这就是 X.509 证书. 在你的平台上, 你需要一个密码和私钥去生成结果。
- private static readonly string ClientSigningCertificatePath = WebConfigurationManager.AppSettings.Get("ClientSigningCertificatePath");
- private static readonly string ClientSigningCertificatePassword = WebConfigurationManager.AppSettings.Get("ClientSigningCertificatePassword");
- private static readonly X509Certificate2 ClientCertificate = (string.IsNullOrEmpty(ClientSigningCertificatePath) || string.IsNullOrEmpty(ClientSigningCertificatePassword)) ? null : new X509Certificate2(ClientSigningCertificatePath, ClientSigningCertificatePassword);
- private static readonly X509SigningCredentials SigningCredentials = (ClientCertificate == null) ? null : new X509SigningCredentials(ClientCertificate, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
过程我们可以用图表指示如下:
X.509 证书 ,在如一下地方一致: 注册token、创建APP、导出公钥到Sharepoint、SharePoint服务器管理注册SPTrustedSecurityTokenIssuer. 要让SharePoint和 非微软技术和谐共生“high trust” 模式下, 需要对JWT token 进行正确使用理解, 正确插入2个声明nii 和nameid, 对token 使用X.509 证书签名。
8.其它平台的JWT Libraries
想到提升开发效率,工具也是不可少的. 大量的JWT libraries可用. 试试看下面.
- https://github.com/auth0/java-jwt – Java
- https://github.com/firebase/php-jwt – A PHP JWT library
- https://github.com/michaelrhanson/jwt-js – JWT implemented in JavaScript, used with Node.js
在我搞东搞西的研究的时候, 我注意到没有针对ACS验证方式:S2S实现的库, 。。。。。。。
小手真疼,没人柔柔。。。。使用“低信任” 吧,别搞那么麻烦。
9.Office 365 APIs
Office 365, 挺好的O365 APIs,也不错,O365 API 有强大的能力去建立Web Site、本地程序、 iOS、 Android和其它使用O365数据的应用程序,都是通过REST APIs 和标准的 OAuth. 就像前面我们解释的“低信任” APP 很容易使用JWT library库一样, O365 APIs也是。
为改进验证的方式,现使用标准的OAuth 流. 同样 TokenHelper.cs, 微软推出了Active Directory Authentication Library (ADAL) 用来让 JWT 使用Azure Active Directory 更方便,ADAL 库提供很多方法,其中包括获得 access token, 这样就能在HTTP 头中添加 “Authorization: Bearer “. 使用时无需要考虑X.509 证书或是修改现有的库, 你可以配置你的APP使用 Azure Active Directory 然后调用 O365 API.
此文对些有很深的研究:, Call Multiple Services with One Login Prompt Using ADAL,
通过使用Azure Active Directory,完成一个APP,这个APP就是一个REST 调用, 很容易转成你的平台代码。
微软的“Microsoft Open Technologies group‘ 已经建立了很多关于Active Directory Authentication Library (ADAL) 的非微软平台的库:
如果 O365 上开发APP, 直接用这些个API吧,简单地把一些ADAL示例转成以上的平台的APP,那是多美好的一天。
10. 总结
最重要的部分都已经给你讲了, 解码token,获得变量的值,还包括 X.509 签名如何工作,也告诉你了 nameid 和nii 声明是怎么回事,
包括如何使用FBA 和SAML 的用户我都讲到了。
信息你就自己看看吧:
Understanding Authentication and Permissions with Apps for SharePoint and Office
SharePoint 2013 User Profile Sync for Claims Users
OAuth and the Rehydrated User in SharePoint 2013 – How’d They do That and What do I Need to Know
PHP - Get users SID from Active Directory via LDAP
SharePoint 2013: Perform operations on SharePoint Document Library from PHP site
Using SharePoint Apps with SAML and FBA Sites in SharePoint 2013
https://github.com/auth0/java-jwt – A Java JWT library
https://github.com/firebase/php-jwt – A PHP JWT library
https://github.com/michaelrhanson/jwt-js – JWT implemented in JavaScript, used with Node.js