1

我正在使用WIF和使用ThinkTecture STS的聯合安全模型。聯合身份驗證後,WIF無法重定向到包含散列的URL

當我嘗試請求url:http://domain.com/#page,WIF在驗證後沒有重定向到正確的頁面。

PARAM在wctx不含/#路徑的正確路徑。相反,它會忽略散列和其後的所有內容,因此參數僅爲/。沒有哈希的普通網址可以正常工作。

有沒有這方面的鍛鍊或我格式化我的網址不正確?
有什麼建議嗎?

回答

1

它看起來像它的瀏覽器沒有發送URL的哈希部分回服務器。我相信這是一個HTTP標準,因爲哈希部分最初只用於客戶端錨定標記。

有使用ajax/javascript的解決方法,但是因爲我使用簡單的GET請求,所以看起來不可能。

看到這些類似的問題,這說明問題......

How to get Url Hash (#) from server side

do browsers remove # in URL automatically?

1

這是哈希代碼段的整點 - 它們不會在服務器上結束。

3

您可以通過發射JavaScript來執行重定向來保留哈希部分,而不是立即重定向。 JavaScript代碼可以通過window.location.hash訪問哈希部分,並使用它來構建ru。

您需要配置頁面以允許未經身份驗證的用戶(以便WIF被動身份驗證不會啓動)。然後,您可以在頁面代碼中處理未經身份驗證的用戶。

您可以在應用程序啓動代碼(例如Web窗體中的Global.asax.cs)中掛接FederatedAuthentication.WSFederationAuthenticationModule.RedirectingToIdentityProvider事件。

例如(Web窗體):

public class Global : HttpApplication 
{ 
    protected void Application_Start(object sender, EventArgs e) 
    { 
     FederatedAuthentication.WSFederationAuthenticationModule.RedirectingToIdentityProvider 
     += this.RedirectToIdentityProviderViaJavaScript; 
    } 

    const string RedirectHtml = 
    @"<html> 
     <head> 
      <script type='text/javascript'> 
       function authenticate(url, utcTimeString) {{ 
        var ru = window.location.pathname + (window.location.hash || ''); 
        var wctx = 'rm=0&id=passive&ru=' + encodeURIComponent(ru) + '&wtc=' + encodeURIComponent(utcTimeString); 
        url += '&wctx=' + encodeURIComponent(wctx); 
        window.location = url; 
       }} 
      </script> 
     </head> 
     <body onload=""authenticate('{0}', '{1}');""> 
     </body> 
    </html>"; 

    private void RedirectToIdentityProviderViaJavaScript(object sender, RedirectingToIdentityProviderEventArgs e) 
    { 
     var fam = FederatedAuthentication.WSFederationAuthenticationModule; 
     var msg = new SignInRequestMessage(new Uri(fam.Issuer), fam.Realm); 
     var stsUrl = msg.WriteQueryString(); 
     var utcTime = WebPageRoutines.EncodeUtcTimeString(DateTime.Now); 
     var html = string.Format(RedirectHtml, WebPageRoutines.JavascriptEncode(stsUrl), WebPageRoutines.JavascriptEncode(utcTime)); 
     Response.ClearContent(); 
     Response.Write(html); 
     Response.Status = "200 OK"; 
     Response.End(); 
    } 
} 

但是要注意,你不能混用?帶有#部分的參數。 RU仍然存在STS重定向(Thinktecture IdentityServer v2),但WIF似乎在STS發佈POST之後的最終重定向時混亂了它。

它會放置?部分在#部分之後。
http://www.somewebsite.com/page?param=1&other=2#hashbit
變爲:
http://www.somewebsite.com/page#hashbit?param=1&other=2

2

最好使用CreateSignInRequest從web.config中得到的所有參數。猜猜它修復了querystring的問題。使用MVC的示例

 const string redirectHtml = 
      @"<!DOCTYPE html> 
       <html> 
       <head> 
        <meta charset='utf-8'> 
        <script type='text/javascript'> 
         function authenticate(url) {{ 
          var ru = window.location.pathname + (window.location.hash || ''); 
          window.location = url.replace('REPLACEWITHURL', encodeURIComponent(ru)); 
         }} 
        </script> 
       </head> 
       <body onload=""authenticate('{0}');""> 
       </body> 
      </html>"; 

     var authenticationModule = FederatedAuthentication.WSFederationAuthenticationModule; 
     var message = authenticationModule.CreateSignInRequest("passive", "REPLACEWITHURL", false); 
     var stsUrl = message.WriteQueryString(); 
     var html = string.Format(redirectHtml, HttpUtility.JavaScriptStringEncode(stsUrl)); 
     filterContext.Result = new ContentResult { Content = html }; 
+0

這很有效。我不在MVC應用程序中,所以我的解決方案已經改編。 'filterContext.Result = new ContentResult {Content = html};' 已恢復爲原始解決方案: 'Response.ClearContent(); Response.Write(html); Response.Status =「200 OK」; Response.End();' –

+0

需要注意的是,在這個解決方案中,「REPLACEWITHURL」不是開發人員在其中放置U​​RL的指令。這是事件在編寫重定向頁面時要替換的字符串。 –