2014-05-05 97 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爲經理等並作出類型的索賠在樹中顯示。

我向前走了一步,並創建了一個訪問拒絕處理程序,以便如果用戶因拒絕訪問該產品而被拒絕訪問,它會將其重定向到該產品購買頁面。

相關問題