Adrian Parker
|
|
Group: Forum Members
Posts: 11,
Visits: 27
|
I have a asp.net website with a logout button that redirects to logout.aspx... which is actually an HTTP Handler and contains the following code in the ProcessRequest method.. Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest Try If ctx.Authentication_SingleSignOn Then Dim ProviderID As String = ctx.siteConfigDef("sso_provider_id", "") If SAMLServiceProvider.CanSLO(ProviderID) Then SAMLServiceProvider.InitiateSLO(context.Response, Nothing, Nothing, ProviderID) End If End If Catch ex As Exception End Try
context.Session.Clear() context.Session.Abandon() context.Items.Clear() context.Request.Cookies.Remove("ASP.NET_SessionId") FormsAuthentication.SignOut() context.Response.Redirect("login.aspx", True) End Sub
In the top of the login.aspx page I have this.. If ctx.Authentication_SingleSignOn Then Dim ProviderID As String = ctx.siteConfig("sso_provider_id") If String.IsNullOrEmpty(ProviderID) Then ctx.accessDenied("The system is not configured correctly for Single Sign On") Return End If
Try If SAMLServiceProvider.CanSLO(ProviderID) Then SAMLServiceProvider.InitiateSLO(ctx.current.Response, Nothing, Nothing, ProviderID) End If Catch ex As Exception End Try
SAMLServiceProvider.InitiateSSO(ctx.current.Response, Nothing, ProviderID) Return End If
What's happening is that when the user presses the logout button, it's going through the logout code, but when it redirects to the login page, it's redirecting to the SSO provider, which doesn't prompt for credentials and just redirects back to our side to the start page.. SSO credentials aren't being cleared on logout. Closing and reopening the browser will prompt for the credentials on the provider site as expected. I notice that even after logout, the ASP_NET.SessionId is set to the same value once it hits the login page. Am I not doing something I should be ? Regards Adrian
|
|
|
ComponentSpace
|
|
ComponentSpace Development
Group: Administrators
Posts: 3.2K,
Visits: 11K
|
Hi Adrian, When you call SAMLServiceProvider.InitiateSLO it will return a 302 redirect HTTP response with the logout request encoded as a query string parameter. At the end of the ProcessRequest you're calling context.Response.Redirect to redirect to your login page. This will override the redirect for sending the logout request. Your logic should be to only redirect to the login page if you haven't called SAMLServiceProvider.InitiateSLO. Similarly, in your login page don't call SAMLServiceProvider.InitiateSSO if you've called SAMLServiceProvider.InitiateSLO as the sending of the logout request will be overridden by the sending of the SAML authn request.
Regards ComponentSpace Development
|
|
|
Adrian Parker
|
|
Group: Forum Members
Posts: 11,
Visits: 27
|
+xHi Adrian, When you call SAMLServiceProvider.InitiateSLO it will return a 302 redirect HTTP response with the logout request encoded as a query string parameter. At the end of the ProcessRequest you're calling context.Response.Redirect to redirect to your login page. This will override the redirect for sending the logout request. Your logic should be to only redirect to the login page if you haven't called SAMLServiceProvider.InitiateSLO. Similarly, in your login page don't call SAMLServiceProvider.InitiateSSO if you've called SAMLServiceProvider.InitiateSLO as the sending of the logout request will be overridden by the sending of the SAML authn request. Thanks for the reply, I've made the following changes.. in the logoff.aspx... Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest Dim UsedSLO As Boolean = False Try If ctx.Authentication_SingleSignOn Then Dim ProviderID As String = ctx.siteConfigDef("sso_provider_id", "") If SAMLServiceProvider.CanSLO(ProviderID) Then SAMLServiceProvider.InitiateSLO(context.Response, Nothing, Nothing, ProviderID) UsedSLO = True End If End If Catch ex As Exception End Try
context.Session.Clear() context.Session.Abandon() context.Items.Clear() context.Request.Cookies.Remove("ASP.NET_SessionId") context.Request.Cookies.Add(New HttpCookie("ASP.NET_SessionId", "")) FormsAuthentication.SignOut()
If Not UsedSLO Then context.Response.Redirect("~/secure/login.aspx", True) End If End Sub
and in the login.aspx.. Try If SAMLServiceProvider.CanSLO(ProviderID) Then SAMLServiceProvider.InitiateSLO(ctx.current.Response, Nothing, Nothing, ProviderID) Else SAMLServiceProvider.InitiateSSO(ctx.current.Response, Nothing, ProviderID) End If Catch ex As Exception ctx.accessDenied("There is a problem signing you into the system, please contact support") End Try
This does beg the question though, if SLO isn't supported, what do you need to remove to have InitiateSSO not think you're already logged in at the remote site ? In the logout, I know in the sample you have the FormsAuthentication.SignOut() before calling the SLO, but I didn't want to clear out anything that might mean the SLO didn't have enough info to know who we are when calling SLO. Regards Adrian
|
|
|
ComponentSpace
|
|
ComponentSpace Development
Group: Administrators
Posts: 3.2K,
Visits: 11K
|
Normally you would establish a local authentication session once SSO completes (eg call FormsAuthentication.SetAuthCookie). You would only call SAMLServiceProvider.InitiateSSO if you don't have a local authentication session.
However, if you've already called SAMLServiceProvider.InitiateSSO/SAMLServiceProvider.ReceiveSSO you can call this sequence again at any stage. If the user is still logged into the identity provider, they won't be prompted to login again.
Regards ComponentSpace Development
|
|
|
Adrian Parker
|
|
Group: Forum Members
Posts: 11,
Visits: 27
|
+xNormally you would establish a local authentication session once SSO completes (eg call FormsAuthentication.SetAuthCookie). You would only call SAMLServiceProvider.InitiateSSO if you don't have a local authentication session. However, if you've already called SAMLServiceProvider.InitiateSSO/SAMLServiceProvider.ReceiveSSO you can call this sequence again at any stage. If the user is still logged into the identity provider, they won't be prompted to login again. Here's what I have at the moment.. in pseudocode assuming no errors etc Login Page.. IF usingSSO THEN IF canSLO THEN InitiateSLO ELSE InitiateSSO END IF ELSE normal site login END IF
The reason I put the SLO part in the login page is that when the session times out and it auto-redirects to the login page, I wanted the user to have to login again as normal, but I'm now thinking this will just annoy them so I've asked the vendor whether it should just go back to their start page.. so the code would then just be simply.. IF usingSSO THEN InitiateSSO ELSE normal site login END IF
SSO Page (where identity provider site redirects to after their login) ReceiveSSO IF valid user FormsAuthentication.SetAuthCookie redirect to users start page ELSE oops END IF
Logout handler IF usingSSO THEN IF canSLO THEN InitiateSLO END IF END IF
destroy the session FormsAuthentication.SignOut IF SLO not called redirect to login page END IF
I'm still not sure what to do in the logout part if SLO isn't used.. what do I have to clear locally to ensure the user will be prompted for an identity provider login ? Thanks Adrian
|
|
|
ComponentSpace
|
|
ComponentSpace Development
Group: Administrators
Posts: 3.2K,
Visits: 11K
|
If the identity provider doesn't support SLO but you want the user logged out from the identity provider, the only other option is to prompt the user to close the browser.
Regards ComponentSpace Development
|
|
|
Adrian Parker
|
|
Group: Forum Members
Posts: 11,
Visits: 27
|
+xIf the identity provider doesn't support SLO but you want the user logged out from the identity provider, the only other option is to prompt the user to close the browser. ok thanks.. I'm still curious about what is sent to the identify provider to identify who the current user is... i.e. how would you put the current browser into a state that was the same as closing and re-opening the browser again ?
|
|
|
ComponentSpace
|
|
ComponentSpace Development
Group: Administrators
Posts: 3.2K,
Visits: 11K
|
The logout request includes the name identifier and session index. These should uniquely identify the logged in user.
However, in most use cases the logout request is sent using the HTTP-Redirect or HTTP-Post binding. This means the message is sent via the browser and therefore it's in the context of the user's browser session. The identity provider knows who the current user is via whatever cookies it uses.
Regards ComponentSpace Development
|
|
|
Adrian Parker
|
|
Group: Forum Members
Posts: 11,
Visits: 27
|
+xThe logout request includes the name identifier and session index. These should uniquely identify the logged in user. However, in most use cases the logout request is sent using the HTTP-Redirect or HTTP-Post binding. This means the message is sent via the browser and therefore it's in the context of the user's browser session. The identity provider knows who the current user is via whatever cookies it uses. ok thanks, I've made the changes, it's going to up to the vendor as to when they test it on their system.
|
|
|
ComponentSpace
|
|
ComponentSpace Development
Group: Administrators
Posts: 3.2K,
Visits: 11K
|
You're welcome. Let us know if there are any issues.
Regards ComponentSpace Development
|
|
|