Kentor/Sustainsys redirects back to SP after receiving LogoutResponse from IDP - saml-2.0

In my application Kentor v.21 single logout works fine for different IDP-s. However one particular IDP after logging out sends the LogoutResponse back to SP. In SP log I see the line: Received logout response _9b1700c5-6f58-43aa-8b63-a2a4ad6fa3f2, redirecting to https://mysp.url/home/ . I am not sure where does this URL come from, but in the result, the user gets logged back into the SP app. Is there a way to configure it on SP side to redirect to some other page?

After the logout response is received, a redirect is done to the URL specified when initiating the logout (through authprops or query string). And if none was specified, the default return url from the config is used.
You can also intercept and alter the redirect location by overriding the LogoutCommandResultCreated notification and alter the Location property on the CommandResult

Related

What is PostLogoutRedirectUris and signout-callback-oidc in signout flow

what is the purpose of
PostLogoutRedirectUris = { "https://yourclienthost:port/signout-callback-oidc" }
in Client Config please?
When I put it, IdentityServer logout page show confirmed logout message AND shows a link to redirect back to my application.
When I omit it, IdentityServer show confirmed logout message BUT NOT shows a link to redirect back to my application
Regardless of the options, IdentityServer still logs me out. So I am confused what that config does. Please help clarify. Thank you very much!
The purpose of PostLogoutRedirectUris in client config is security.
When the client initiates signout, the client opens a url like that:
https://[identity-server]/connect/endsession?post_logout_redirect_uri=https%3A%2F%2Fclient%2Fapp%2Fsignout-callback-oidc&id_token_hint=XXX&state=YYY&...
Pay attention that the client itself tells IdentityServer where to redirect to after signout. This means that the client might cheat IdentityServer to redirect to a malicious URI.
That's why a white-list of URIs is used on the IdentityServer side, which is called PostLogoutRedirectUris. The list contains all possible deployment locations of the client e.g.
"PostLogoutRedirectUris": [
"https://localhost:44321/signout-callback-oidc",
"https://client/app/signout-callback-oidc", ...
]
When the callback URI suggested by the client is not on the white-list, then
IdentityServer shows confirmed logout message but NOT a link to
redirect back to your application
The signout process continues like that:
.../connect/endsession above redirects to https://[identity-server]/Account/Logout?logoutId=ZZZ
The Logout action renders a page with the link back to the client ( https://client/app/signout-callback-oidc&id_token_hint=XXX&state=YYY&... )
On the same page there is also an iframe wich opens https://[identity-server]/connect/endsession/callback?endSessionId=TTT
This iframe renders another iframe which signs out the client by calling https://client/app/signout-oidc?sid=SSS&iss=https://identity-server
On the same page there is also some JavaScript which automatically opens the link from step 3 and goes back to your client app.
The /signout-callback-oidc route in a MVC client does nothing (probably; I don't know what it does) but it redirects to the home page. (*)
The signout from both IdentityServer and the client app is already complete in step 5. /signout-callback-oidc has nothing to do with the signout itself. It only provides a landing page back in the client app so that the user does not get stuck on a page in IdentityServer.
(*) More precisely, /signout-callback-oidc in the client app redirects to options.SignedOutRedirectUri which can be set during AddOpenIdConnect().
By defaut SignedOutRedirectUri == "/". I prefer to change that option to "/Account/Login". In this way I see the login page right after signout.
"/signout-callback-oidc" is just the default value of options.SignedOutCallbackPath. You can change that path but there is no benefit. This route is automatically registered and automatically handled by the middleware. You cannot write your own controller/action for that route.
PostLogoutRedirectUri is meant to redirect you when you log out of your client. It will, e.g. bring you back to your client application's home screen. When you implement a 'single' logout for your application, you stay logged in to IdentityServer.
Once you are logged out of IdentityServer itself however, no PostLogoutRedirectUri is used and the flow ends on the IdentityServer UI.
In this case, it probably means that you implemented your signout by calling SignOutAsync twice. Once for the local application and once for the IDP but I can't be sure without seeing your code.

How does Single-logout works with OKTA(IDP)-Shibboleth(SP)-App

OKTA-Shibboleth(Apache)-Nakisa(Tomcat)
SSO is working for logging-in.
Now, I need to configure Logout. So, user logs out from the app, user needs to be redirected to OKTA page with tiles.
But, currently,user is redirected to the app again.
It's sending user to /logout?redirect=default.html but that default.html is captured by Apache rule and logging user back in.
It looks like it needs to hit
https://xxxx/Shibboleth.sso/Logout. When I access this url, it says logout is successfully done although it's not going back to OKTA. Does that mean that in the App's logout setting, they need to redirect to this?
But, how do I make user to go back to IdP(i.e OKTA) again?
This is what I assume that will happen.
Logout button click > logout from Shibboleth > return to OKTA so user can click other tiles.
Something to configure Shibboleth2.xml?
Document says i just need to configure the following which is there by default.
<!-- SAML and local-only logout. -->
<Logout>SAML2 Local</Logout>
But, how does it redirect user to OKTA(IdP) once user log out completes.
Is it configured in IdP's metadata ?
You can redirect the user after a local logout event anywhere you'd like, via passing the ?return= parameter a URL-encoded destination, i.e. you should update your logout link to:
https://xxxx/Shibboleth.sso/Logout?return=https%3A%2F%2Fgoogle.com
in order to redirect folks to Google once logout has taken place.
Now, you only need an Okta URL to return folks to... so I think if your client's Okta tenant is "foobar.okta.com", redirecting them after local logout to the Okta login page shouldn't prompt them to login, since they will already have the Okta Session... so maybe try:
https://xxxx/Shibboleth.sso/Logout?return=https%3A%2F%2Ffoobar.okta.com%2Flogin
Of course, you'll need to test that... but it should work, and on the off chance that the user's Shibboleth SP session was active, and their Okta session invalidated through some other mechanism, that'll just return them to their regular Okta login page.
You can obviously redirect them to any endpoint with the return parameter, for example, whatever Okta's logout URL (if you wanted to kill their Okta session too).
The only logout that's configurable by Metadata is SLO (single logout), i.e. if you wanted it to, Shibboleth can redirect the user to Okta after they complete the logout of the SP session, along with a specially-craft <LogoutRequest> assertion payload, which Okta would parse and act on in any number of ways, i.e. killing the user's Okta session, propagating Okta-initiated subsequent <LogoutRequest> assertions to other Service Providers, etc. In practice, this never really works, because such configurations are very difficult to get working between all of the relevant parties.

Identity server 4 strange behavior, not redirecting back to the mvc client after login

Using aspnetcore 2.1and Identity Server 4 quickstart, I have setup a token server with an mvc client so that when the AuthorizeAttribute is used it redirects to the ID4 server login screen and after logging in it redirects back to the mvc client.
Since we were refactoring an old application with custom salt and hash in the database I have created a custom user store, role store and password hasher.
I can login fine using
signInManager.PasswordSignInAsync()
but it does not redirect back to the client as I would expect.
From the fiddler log i can see it redirects to /connect/authorize/callback then back to the login page.At which point the user is clearly logged in because the user name appears with the option to logout.I put in a breakpoint on the login get action and see that User.Identity.IsAuthenticated is true.
For testing I swapped the login method for the login action method from the is4inmem template which uses
HttpContext.SignInAsync(user.SubjectId, user.Username, props)
at which point it does redirect back to the client.
Am I missing some part of the custom userstore which _signInManager.PasswordSignInAsync calls to log users in the same way as HttpContext.SignInAsync?
Getting the config ready to paste here I relised that I had this line commented out:
builder.AddAspNetIdentity();
When I uncommented that it worked perfectly.

OKTA Logout SAML App

I have setup an Application that's is using OKTA as IDP. The app is SAML Based.This part is working fine.
But I am unable to log out. For this we have
1. Enabled Single Logout
2. Set the Single Log out URL (I received this from Metadata of IDP under header Identity Provider Single Logout URL)
3.Sp Issues (I received this from Metadata of IDP under header Identity Provider Issuer )
4. Signature Certificate (This is the certificate of IDP)
Now when I call the Logout URL I am receiving 403. On checking the Logs of OKTA I see the (User Single Sign out from App Failure:- Malformed Request)
Can any one please help me how to fix it.
I am assuming that I just need to call the logout URL and the session will kill off. Is my understanding correct?
Reviving a very old thread, check that you have a ?ReturnTo=<path> at the end of the logout URL.
Okta requires strictly post binding requests for logout. Please make sure you are making POST requests for logout and you are using correct entity Id in request.
I think the setting values below need to be set for sp side.
Set the Single Log out URL
Sp Issues
Signature Certificate
It is not on idp side.

Blank page after login using bookmarked authorization URL in IdentityServer4

We have discovered that our users very often for the first time visits our web application by browsing the direct URL of the OIDC client (https://oidcclienturl.com/), The ASP.NET Core OIDC authentication middleware kicks in and the user gets redirected back to Identityserver 4 login page.
Everything works fine but then they decide to add the (temporary? state, nonce, cookies...) authorization URL as a bookmark in their browser before entering their credentials and continuing back to the web application.
This causes an issue when the user later uses the bookmark in a new session. The login seem to actually work after entering valid user credentials even if the user uses an old authorization URL, but when the user gets redirected back to the web application they end up on a blank page (https://oidcclienturl.com/signin-oidc).
After the blank page have been loaded the user is able to browse the direct URL (https://oidcclienturl.com/) sucessfully and appear as an authentcated user in the web application.
Any ideas whats causing the blank page?
That blank page shouldnt exist, if I understand it correctly its the default callback path of the oidc authentication middleware in ASP.NET Core.
Unfortunately, the real-world problem of users bookmarking the login page isn't handled cleanly by OIDC, which requires the client app to initiate the login flow.
I've addressed this by adding a RegistrationClientId column to my user data table, which is the Identity Server ClientId corresponding to the client app that called IDS when the user account was created. In the client app configuration, we use the custom Properties dictionary to add a URI fragment:
new Client
{
ClientId = "some_client",
ClientName = "Some Client",
ClientUri = "https://localhost:5000",
Properties = new Dictionary<string, string>
{
{ "StartLoginFragment", "/Auth/StartLogin" }
}
// other config omitted
};
When a user logs in, an empty return URL indicates IDS wasn't called by a client app, so we use RegistrationClientId to query IClientStore, then we combine the ClientUri and StartLoginFragment URIs and use the resulting URI to redirect the user back to the client application.
Over in the client application, that endpoint kicks off the OIDC sign-in flow, and since the user is already signed-in on IDS, it comes right back to the correct location in the client app. The controller action looks like this:
[HttpGet]
public async Task StartLogin()
{
await acctsvc.SignOutAsync();
await HttpContext.ChallengeAsync("oidc",
new AuthenticationProperties()
{
RedirectUri = "/"
});
}
The call to SignOutAsync just ensures any client-app signin cookies are cleaned up. It's in our custom account service, but it just runs HttpContext.SignOutAsync on the usual "Cookies" and "oidc" schemes. Normally that would also result in a signout call to IDS, but the redirection by the subsequent ChallengeAsync replaces the pending signout call.
The downside is that the action is an HTTP GET meaning pretty much anyone could theoretically trigger this action. At most it would be an annoyance.
In the special case where your IDS is only handling auth for a single client, you can skip a lot of that -- if they land on the page with no return URL, just send them to your client app start-login endpoint straightaway, before they login.

Resources