Kor*_*nis 8 c# asp.net-mvc sharepoint adfs2.0
我们编写一个Sharepoint应用程序,将其扩展为Provider-hosted,使用证书,并将我们的MVC项目锚定到它.在同一个IIS上展开所有这些,扩展了Sharepoint.
任务1:用户登录Sharepoint,启动我们的应用程序; 应用程序启动时没有任何授权请求,并从登录的Sharepoint获取用户.
任务#2:如果需要Sharepoint服务请求,我们的应用程序使用用户登录Sharepoint的相同用户名登录Sharepoint.
我们尝试了:
1) 构建提供者托管的应用程序,在其中编写MVC,创建自唱歌证书,调整Sharepoint站点和MVC之间的高可信度.
我们得到:
如果我们的MVC使用Windows身份验证,那么在转移到我们的应用程序时,会再次请求用户名和密码; 进入它们时,我们可以ClientContext
通过TokenHelper
使用该GetS2SClientContextWithWindowsIdentity
方法.
如果禁用了Windows身份验证,则用户不会登录请求,并且此方法会响应用户未登录的异常.
2)
我们安装并调整了ADFS,配置了Sharepoint以便与ADFS一起工作,写了Sharepoint的地址和我们在中继方信任中的应用(在Identifiers and
WS-Federtation`被动端点中)
我们得到: 用户登录Sharepoint,当转移到我们的应用程序时,后者获取用户数据(声明)
因此,第一项任务已经解除.之后,出现了在授权用户下获得对Sharepoint服务的访问的问题
我们试图AccessToken
通过我们收到的声明获取Sharepoint我们试图转移以下声明:
nii":"trusted:adfs
nii":"urn:office:idp:forms:adfs201 //adfs201 - name of our ADFS service
upn:UserLogin
emailaddress:UserEmail@domain.kz
Run Code Online (Sandbox Code Playgroud)
之后,我们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);
Run Code Online (Sandbox Code Playgroud)
然后,我们尝试ClientContext
使用以下方法:
GetClientContextWithAccessToken(targetApplicationUri.ToString(), accessToken);
Run Code Online (Sandbox Code Playgroud)
但是我们得到了错误报告:
401 Unauthorized
Run Code Online (Sandbox Code Playgroud)
ClientID
并IssureID
写得正确,小写
在那之后,我们决定请SecurityToken
来自ADFS的帮助下username
和password
.收到后,我们要求使用SharepointSTS进行授权SecurityToken
.然后,我们的应用程序获得了Cookie Sharepoint,它被锚定到查询(添加CookieContainer FedAuth
)到Sharepoint服务.激活时ExecutingWebRequest += ClientContext_ExecutingWebRequest
,会发生上述情况.
但为此,人们应该再次使用username
和password
要求.
如果我们不提交username
和password
,则ADFS以SecurityToken
用户的数据响应,其名称是启动应用程序池.我们需要登录SharePointSecurityToken
的用户.我们也试图发射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);
Run Code Online (Sandbox Code Playgroud)
但是响应与SharePoint授权所需的响应不同.
在端点的ADFS中,我们调整URL; 这非常SecurityToken (wresult)
需要我们的SharePoint授权由POST查询发送给它.问题是我们无法在应用程序中接收此查询,因为它在状态302中广播并通过GET方法重定向到我们的应用程序,而不SecurityToken
使用我们的Cookie.
问题是:我们如何获得SecurityToken
登录SharePoint的用户?
在这里突发奇想,但听起来您需要创建一个声明提供程序,它是一个继承自 SPClaimProvider 的类。
sharepoint 中的人员选择器是您用来选择人员和组的控件,它可以获取来自声明提供者的所有人员和组。
开箱即用,存在以下声明提供者,
AllUsersClaimProvider FormsClaimsProvider ActiveDirectoryClaimsProvider
如果您需要额外的索赔解决方案,则必须写一份,这还不错。
http://msdn.microsoft.com/en-us/library/office/ee537299(v=office.15).aspx
基本上,您可以在 FillClaimsForEntity 中向身份主体发出新的声明。
您可以在两个解决重载中查看输入是否存在声明匹配。
例如,假设您在人员选择器中输入“Bob”。然后,人员选择器使用 SPClaimsOperationManager*(忘记确切的拼写)对场中注册的每个声明提供者调用 Resolve(string input...)。
假设我们正在谈论表单索赔提供商。它将检查是否有用户的用户名或电子邮件地址与 Bob 匹配。对于每个映射 bob 的用户,它将创建一个选择器实体,并将其声明类型设置为 FormsLogonUser,值为 bob 等。并将每个用户添加到结果中。
因此,完成后,您将在人员选择器中看到鲍勃已被选中,或者您将看到鲍勃带有红色下划线,这意味着他们有多个匹配项,您需要进行选择。
在我看来,您需要构建一个以使人员选择器能够处理您的新声明。
一旦您创建并注册了声明提供者,您就可以使用人员选择器来授予使用您的声明访问该网站的权限。
例如,我曾经创建过一个索赔提供商,该提供商根据用户购买的产品发出索赔。
因此,我创建了“ http://blah.com/schema/claims/product ”的声明类型(这可以是您想要的任何唯一字符串),并且值类似于“pd.1234.0”。现在,在 FillClaimsForEntities 中,我在数据库中的实体参数上查找用户以获取他们的所有产品。然后,我为每个产品创建了一个产品声明,并将它们添加到声明列表中。
然后在 Resolve 中,我会查看产品是否存在,其 ID 或显示名称与解析输入进行数学运算,如果存在,则创建一个选择器实体。
搜索中也是如此。
然后我进入我们的产品页面,并使用人员选择器向拥有该产品声明的任何人授予对该页面的访问权限。“就像在表单身份验证中选择角色一样”。
此外,您还可以为声明层次结构提供代码支持,并且您可以在人员选择器中拥有多棵树,您正在使用的每种声明类型有一棵树。
例如,说“鲍勃”带回一个人、一本书和一位经理。您可以有 3 个层次结构,1 个用于人员,1 个用于书籍,1 个用于经理等。并使该类型的声明显示在该树中。
我更进一步,制作了一个访问被拒绝处理程序,这样,如果用户因不在该产品中而被拒绝访问,它会将他们重定向到该产品购买页面。
归档时间: |
|
查看次数: |
4473 次 |
最近记录: |