首先回顾一下SharePoint认证方式的发展变化。早期的SharePoint 2003,仅支持windows认证,这就要求所有的用户必须是AD用户。到了SharePoint 2007的时候,增加了对ASP.NET form认证的支持,因此使用SharePoint的用户不仅有AD用户,还有form认证的用户。到了SharePoint 2010,认证方式迈出了很大的一步,支持了claims-based认证方式。这种方法有什么好处呢?使用windows认证和form认证的时候,在认证的过程中,SharePoint会使用两种不同的security token,对于windows认证,使用windows security token,而对于form认证,使用FBA security token。如果这样,每添加一种认证方式就需要一种security token,这样显然是不合适的。所以claims-based认证方式使用SAML标准,因此统一了security token。为了统一认证方式,SharePoint多做了一些工作,就是将window security token和form security token以及其他的认证方式提供的security token,都转成了一个SAML token,这个工作是通过STS(Security Token Service)来完成的。在SharePoint2010的时候,这些SAML token是保存在服务器的内存中,还不能在整个Farm中共享,但是到了SharePoint 2013,这些SAML token实现了整个Farm的共享,这个工作是通过DCS(Distributed Cache Service)来完成的。因此,SharePoint 2013可以支持很多种的认证方式,包括Windows Azure Access Control Service (ACS) ,Windows Account, Google, Facebook等等。
App必须工作在claims-based认证方式下,SharePoint支持三种App的认证:
1,内部App认证(Internal app authentication),我的理解SharePoint使用已配置的authentication provider来验证用户。
2,使用OAuth的外部App认证(External app authentication using OAuth),使用OAuth来验证用户。
3,使用S2S的外部App认证(External app authentication using S2S High-trust),使用S2S(site to site)来验证用户。
如果需要实现对App的认证,SharePoint需要做到两件事,第一,需要判断出来一个请求是用户发出的还是一个app发出的;第二,如果是一个app发出的请求,那么还要判断是使用内部认证方式还是外部认证方式来做认证。
如果SharePoint接收到一个请求,SharePoint首先会判断这个请求是否包含app外部认证方式专用的token:access token,如果包含,那就可以判断出这个请求是由一个app发出来的,而且这种情况下,SharePoint会使用外部app认证方式。
如果一个请求不包含access token,而是包含一个SAML token,这就需要检查URL,如果请求的URL是app web,那么SharePoint会认为这个请求是由app发出来的,这种情况下SharePoint会使用内部App认证来验证这个请求。如果URL不是一个app web的URL,SharePoint会认为这个请求是一个SharePoint user发出的。以下图示列出了4种情形:
第一种情形就是常见的用户访问SharePoint的情形,例如一个用户访问一个SharePoint的页面,这个时候SharePoint使用SAML token认证用户。
第二种情形是用户访问一个App Web,这个时候SharePoint除了认证用户之外,还要使用内部App认证来验证app的权限。
第三和第四种情形是使用外部认证专用的access token,这个时候SharePoint会使用外部App认证方式来验证app的权限,不同的地方在于第三种情形中,access token中既包含了app的信息,也包含了用户的信息。使用access token也是外部App认证的特点。
SharePoint-hosted App,即把app部署在本地的SharePoint中的时候,都是使用内部App认证方式。因此在App的manifest.xml文件中,需要配置内部认证方式:
<AppPrincipal> <Internal /> </AppPrincipal>
<AppPrincipal> <Internal AllowedRemoteHostUrl="~remoteAppUrl" /> </AppPrincipal>