2013-07-12 19 views
3

我有一個基於Web API的應用程序,當前使用的是令人驚歎的Thinktecture IdentityModel 4.5。Cookie的Thinktecture IdentityModel AuthenticationConfiguration映射 - 如何?

它設置爲基於聲明的身份驗證,接受授權標頭中發送的基本身份驗證憑據。 javascript客戶端保存返回的會話令牌,並將其用於隨後的請求,方法是將其包含在作爲方案的會話之前的授權標頭中。

javascript客戶端還會將令牌保存到cookie中,以便在窗口關閉並重新快速打開時進行檢索,或者打開新窗口以防止用戶重新進行身份驗證。該cookie被命名爲sessionToken,它的值是實際的令牌。

這一切都非常好。

問題是我在鏈接到直接地址(/ api/controller/id/pdfdocument)的應用程序頁面上有一個鏈接,並在新窗口中打開它(目標:_blank)。因此,無法在此請求中包含授權標頭。但是,由於會話仍處於活動狀態,cookie會正確傳輸。

我試圖添加一個映射到AuthenticationConfig.Mappings集合,以添加從cookie收集令牌的支持,但是我只是無法獲得配置,無法使其正常工作,並且無法在網上找到其他資源。我假設有一些非常簡單的事情需要修復。

我的代碼:

private static AuthenticationConfiguration CreateAuthenticationConfiguration() 
    { 
     var sessionTokenConfiguration = new SessionTokenConfiguration(); 
     sessionTokenConfiguration.EndpointAddress = "/Authenticate"; 
     sessionTokenConfiguration.DefaultTokenLifetime = new TimeSpan(1, 0, 0); 

     var authenticationConfig = new AuthenticationConfiguration 
     { 
      ClaimsAuthenticationManager = _authenticationManager, 
      RequireSsl = false, 
      EnableSessionToken = true, 
      SessionToken = sessionTokenConfiguration, 
      SendWwwAuthenticateResponseHeaders = false 
     }; 

     var securityTokenHandler = new Thinktecture.IdentityModel.Tokens.Http.BasicAuthenticationWithRoleSecurityTokenHandler(_userService.ValidateUser, _userService.GetRolesForUser); 
     securityTokenHandler.RetainPassword = false; 
     var realm = "localhost"; 

     var authorizationMapping = new AuthenticationOptionMapping 
     { 
      Options = AuthenticationOptions.ForAuthorizationHeader(scheme: "Basic"), 
      TokenHandler = new System.IdentityModel.Tokens.SecurityTokenHandlerCollection { securityTokenHandler }, 
      Scheme = AuthenticationScheme.SchemeAndRealm("Basic", realm) 
     }; 
     authenticationConfig.AddMapping(authorizationMapping); 

     var cookieMapping = new AuthenticationOptionMapping 
     { 
      Options = AuthenticationOptions.ForCookie("sessionToken"), 
      TokenHandler = new System.IdentityModel.Tokens.SecurityTokenHandlerCollection { securityTokenHandler }, 
      Scheme = AuthenticationScheme.SchemeOnly(scheme: "Session") 
     }; 
     authenticationConfig.AddMapping(cookieMapping); 

     //authenticationConfig.AddBasicAuthentication(_userService.ValidateUser, _userService.GetRolesForUser); 

     return authenticationConfig; 
    } 

此配置,然後應用,像這樣:

HttpConfiguration config; 
var authenticationConfig = CreateAuthenticationConfiguration(); 
config.MessageHandlers.Add(new AuthenticationHandler(authenticationConfig)); 

這是cookie的樣子在請求頭:

Cookie: sessionToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzNzM2NDA5NjgsImlzcyI6InNlc3Npb24gaXNzdWVyIiwiYXVkIjoiaHR0cDovL3Nlc3Npb24udHQvIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImEiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL2F1dGhlbnRpY2F0aW9ubWV0aG9kIjoiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2F1dGhlbnRpY2F0aW9ubWV0aG9kL3Bhc3N3b3JkIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9hdXRoZW50aWNhdGlvbmluc3RhbnQiOiIyMDEzLTA3LTEyVDEzOjU2OjA4LjA5N1oiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiSWQiOiIyIn0.UlPeD9HzduQfwHE7NuXi9eMVo40hypi_LBK-f76VYFI; username=a 

任何最受讚賞的幫助!

+0

Ibraheem,如果你碰巧看到這個評論我想你可以幫助我這個問題http://stackoverflow.com/questions/27731539 –

回答

2

因此,在等待幾分鐘並且沒有收到回覆並且迫切需要這個功能之後,我潛入了Thinktecture IdentityModel 4.5源代碼,看看發生了什麼,看起來這個功能實際上並不支持。它不僅不被支持,而且從它的外觀來看,cookie映射實際上並未實現。

我分叉庫,並提出了一些小的改動,以允許此功能: https://github.com/ibraheemhlaiyil/Thinktecture.IdentityModel.45

並派出Thinktecture本的多米尼克·拜爾在拉請求: https://github.com/thinktecture/Thinktecture.IdentityModel.45/pull/95

Cookie的使用有它的缺點,似乎Thinktecture儘量遠離他們,但我不能想出一個不同的解決方案來解決我的問題 - 一個JavaScript客戶端的Web應用程序,需要打開一個新的窗口/選項卡,並保持認證會話在新窗口/選項卡。

如果要使用此功能,只需在SessionTokenConfiguration對象上設置新的CookieName屬性即可。 IdentityModel使用HeaderName屬性來確定哪個頭查找認證數據。同樣,如果設置了CookieName屬性,則如果在標題上未找到驗證數據,則將確定爲哪個cookie名稱查找驗證數據。

在下面的例子中,如果沒有驗證數據在授權標頭中找到驗證數據尋找命名sessionToken該cookie。

private static AuthenticationConfiguration CreateAuthenticationConfiguration() 
    { 

     var authenticationConfig = new AuthenticationConfiguration 
     { 
      ClaimsAuthenticationManager = _authenticationManager, 
      RequireSsl = false, 
      SendWwwAuthenticateResponseHeaders = false, 
      EnableSessionToken = true, 
      SessionToken = new SessionTokenConfiguration 
      { 
       EndpointAddress = "/Authenticate", 
       DefaultTokenLifetime = new TimeSpan(1, 0, 0), 
       HeaderName = "Authorization", 
       CookieName = "sessionToken", 
       SigningKey = CryptoRandom.CreateRandomKey(32) 
      } 
     }; 

     authenticationConfig.AddBasicAuthentication(_userService.ValidateUser, _userService.GetRolesForUser); 

     return authenticationConfig; 
    } 

如前所述,這種結構被應用於像這樣你的應用程序在啓動時:

HttpConfiguration config; 
var authenticationConfig = CreateAuthenticationConfiguration(); 
config.MessageHandlers.Add(new AuthenticationHandler(authenticationConfig)); 

該Cookie認證數據具有完全相同的形式如在授權報頭髮送的數據,因此,如果發,cookie應該看起來像:

Cookie: sessionToken=Session eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzNzM2NDA5NjgsImlzcyI6InNlc3Npb24gaXNzdWVyIiwiYXVkIjoiaHR0cDovL3Nlc3Npb24udHQvIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImEiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL2F1dGhlbnRpY2F0aW9ubWV0aG9kIjoiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2F1dGhlbnRpY2F0aW9ubWV0aG9kL3Bhc3N3b3JkIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9hdXRoZW50aWNhdGlvbmluc3RhbnQiOiIyMDEzLTA3LTEyVDEzOjU2OjA4LjA5N1oiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiSWQiOiIyIn0.UlPeD9HzduQfwHE7NuXi9eMVo40hypi_LBK-f76VYFI 

希望有人找到這個有用的!

相關問題