2014-05-05 59 views
8

我们使用证书编写Sharepoint应用程序,将其扩展为提供程序托管,并将我们的MVC项目锚定到它 在Sharepoint展开的同一IIS上展开所有这些。Sharepoint身份验证。如何从ADFS获取SharePoint cookie

任务#1:用户登录Sharepoint,启动我们的应用程序;应用程序启动时没有任何授权请求,并得到从SharePoint它登录的用户

任务#2:如果SharePoint服务请求是必要的,我们在SharePoint应用程序日志中的用户名登录的用户登录SharePoint中。

我们尝试:

1)构建供应商提供托管应用程序,它写我们的MVC,创建自唱证书,调整高信任的SharePoint网站和我们的MVC之间。

我们得到: 如果我们的MVC使用Windows身份验证,然后转移到我们的应用程序时,用户名和密码被要求一遍又一遍;当输入它们时,我们可能使用GetS2SClientContextWithWindowsIdentity方法得到ClientContextTokenHelper

如果Windows身份验证被禁用,则用户没有登录请求,这个方法来响应不同的是,用户没有登录。

2) 我们安装和调整ADFS,配置的Sharepoint与ADFS工作,写(-Federtation` WS无源端点在Identifiers and)SharePoint和我们在继电保护方信任的应用程序的地址

我们得到: 用户登录SharePoint和转移到我们的应用程序时,该啦tter获得用户数据(索赔)

因此,第一项任务已经完成。 之后,授权用户在获得访问SharePoint服务的问题出现

我们试图通过我们收到 索赔获得AccessToken为SharePoint我们试图传递以下声明:

nii":"trusted:adfs 
nii":"urn:office:idp:forms:adfs201 //adfs201 - name of our ADFS service 
upn:UserLogin 
emailaddress:[email protected] 

在那之后,我们叫的方法响应AccessToken按照输入的索赔

string issuer = string.IsNullOrEmpty(sourceRealm) ? issuerApplication : string.Format("{0}@{1}", issuerApplication, sourceRealm); 
    string nameid = string.IsNullOrEmpty(sourceRealm) ? sourceApplication : string.Format("{0}@{1}", sourceApplication, sourceRealm); 
    string audience = string.Format("{0}/{1}@{2}", targetApplication, targetApplicationHostName, targetRealm); 

    List<JsonWebTokenClaim> actorClaims = new List<JsonWebTokenClaim>(); 
    actorClaims.Add(new JsonWebTokenClaim(JsonWebTokenConstants.ReservedClaims.NameIdentifier, nameid)); 
    if (trustedForDelegation && !appOnly) 
    { 
     actorClaims.Add(new JsonWebTokenClaim(TokenHelper.TrustedForImpersonationClaimType, "true")); 
    }  

    if (addSamlClaim) 
     actorClaims.Add(new JsonWebTokenClaim(samlClaimType, samlClaimValue)); 

    // Create token 
    JsonWebSecurityToken actorToken = new JsonWebSecurityToken(
     issuer: issuer, 
     audience: audience, 
     validFrom: DateTime.UtcNow, 
     validTo: DateTime.UtcNow.AddMinutes(TokenLifetimeMinutes), 
     signingCredentials: SigningCredentials, 
     claims: actorClaims); 

    string actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken); 

    if (appOnly) 
    { 
     // App-only token is the same as actor token for delegated case 
     return actorTokenString; 
    } 

    List<JsonWebTokenClaim> outerClaims = null == claims ? new List<JsonWebTokenClaim>() : new List<JsonWebTokenClaim>(claims); 
    outerClaims.Add(new JsonWebTokenClaim(ActorTokenClaimType, actorTokenString)); 

    //**************************************************************************** 
    //SPSAML 
    if (addSamlClaim) 
     outerClaims.Add(new JsonWebTokenClaim(samlClaimType, samlClaimValue)); 
    //**************************************************************************** 

    JsonWebSecurityToken jsonToken = new JsonWebSecurityToken(
     nameid, // outer token issuer should match actor token nameid 
     audience, 
     DateTime.UtcNow, 
     DateTime.UtcNow.AddMinutes(10), 
     outerClaims); 

    string accessToken = new JsonWebSecurityTokenHandler().WriteTokenAsString(jsonToken); 

然后,我们试图让ClientContext,我们荷兰国际集团的方法:

GetClientContextWithAccessToken(targetApplicationUri.ToString(), accessToken); 

但我们得到了一个错误报告:

401 Unauthorized 

ClientIDIssureID写正确的,小写

在那之后,我们决定从ADFS要求SecurityToken的帮助usernamepassword。收到它后,我们请求使用SecurityToken在SharepointSTS中进行授权。然后,我们的应用程序获得了Cookie Sharepoint,它被锚定到Sharepoint服务的查询(添加到CookieContainer FedAuth)。当激活ExecutingWebRequest += ClientContext_ExecutingWebRequest时,发生上述情况。

但是为此,应该使用usernamepassword再次请求。

如果我们不SecurityToken与用户的数据提交usernamepassword,然后ADFS回应,其中的应用程序池启动的名下。我们需要登录到SharePoint的用户的SecurityToken。 我们还试图发出SecurityToken

var session = System.IdentityModel.Services.FederatedAuthentication.SessionAuthenticationModule.CreateSessionSecurityToken(ClientPrincipals, "context", DateTime.UtcNow, System.DateTime.UtcNow.AddHours(1), true); 
System.IdentityModel.Services.FederatedAuthentication.SessionAuthenticationModule.AuthenticateSessionSecurityToken(session, true); 

但反应不是我们所需要的SharePoint权限相同。

在端点的ADFS中,我们调整URL;我们需要SharePoint授权的SecurityToken (wresult)通过POST查询发送给它。问题是,我们无法在应用程序中接收到此查询,因为它在状态302中广播,并通过GET方法重定向到我们的应用程序,而我们的Cookie没有SecurityToken

现在的问题是:我们怎么能得到SecurityToken的用户登录SharePoint?

回答

0

在这里一发不可收拾,但它听起来像你需要创建一个声明提供程序,这是一个从SPClaimProvider继承的类。

sharepoint中的人员选择器(用于选择人员和组的控件)将从索赔提供商处获取所有人员和组。

开箱即用,下面的声明提供存在的,

AllUsersClaimProvider FormsClaimsProvider ActiveDirectoryClaimsProvider

如果您需要更多的权利要求的分辨率,你必须写一个,这是没有那么糟糕。

http://msdn.microsoft.com/en-us/library/office/ee537299(v=office.15).aspx

基本上,FillClaimsForEntity在这里你可以发布到身份委托新的索赔。

这两个解决超载是您看到输入是否存在索赔匹配的地方。

E.g.假设你在人员选择器中输入“Bob”。然后,人员选择器使用SPClaimsOperationManager *(忘记确切的拼写),对农场中注册的每个声明提供程序调用Resolve(字符串输入...)。

所以说我们正在谈论Forms Claims Provider。它会检查用户是否有与Bob匹配的用户名或电子邮件地址。对于每个映射bob的用户,它将创建一个选择器实体,并将它的声明类型设置为具有bob值等的FormsLogonUser。并将结果添加到每个用户。

所以当它这样做,你要么看到鲍勃在人员选取器为已选定,否则你会看到鲍勃用红色下划线这意味着他们的多项匹配,你需要挑。

这听起来像你需要建立一个让人们选择工作与你的新索赔。

一旦您声明提供商已经制作并注册,您就可以使用人员选择器使用您的声明授予对网站的访问权限。

对于示例场景,我曾经根据用户购买的产品提出索赔提供商的索赔提供商。

所以我提出了一个“http://blah.com/schema/claims/product”的索赔类型(这可以是任何你想要的唯一字符串)并且这些值是诸如“pd.1234.0”之类的东西。现在在FillClaimsForEntities中,我查找了我们数据库中的实体参数的用户以获取他们的所有产品。然后我为每个产品创建了一个产品声明并将其添加到声明列表中。

然后在解决我会看看,如果一个产品,一个ID或显示名称mathing决心输入存在,并创建一个选择器的实体,如果它没有。

搜索中的相同内容。

然后,我进入我们的产品页面,并授予使用人员选择器访问该产品声明的任何人的网页访问权限。 “就像在表单身份验证中选择角色一样”。

您也可以编写索赔层次结构支持,您可以在人员选取多棵树,1个树您正在使用的每一个要求的类型。

E.g.说“鲍勃”带回一个人,一本书和一个经理。你可以有3个heirarchies,1人,1书,1为经理等并作出类型的索赔在树中显示。

我向前走了一步,并创建了一个访问拒绝处理程序,以便如果用户因拒绝访问该产品而被拒绝访问,它会将其重定向到该产品购买页面。

相关问题