OpenID Backchannel Logout contains no Logout Token - single-sign-on

I am trying to implement Single-Sign-Out procedure within my clients and Identity Provider (Identity Server 4). I managed to set correctly an Iframe page that gets rendered whenever a user logs out (either from the Identity Server itself or from a client). Such rendering triggers the call of the endsession endpoint, which is an internal mechanism of Identity Server that calls all the clients who have a BackChannelLogoutUri registered. My client receives the call from Identity Server (it's a POST call) but unfortunately the call is not authenticated.
This causes a redirect in my client due to a non authorized call.
At the same time I cannot really debug what's happening in this endsession endpoint of Identity Server. Any tips by any chance on how to proceed?

You need to use [AllowAnonymous] attribute on your POST action for single sign out in your client application. The user in this case is validated not by cookie, but by the logout_token that Identity Server passes in the POST call.

Related

Is the web browser a security threat to my Delphi REST application?

I have created a REST application in Delphi using kbmMW middleware. It works really great, is fast, efficient etc. But in testing I've used both a Delphi client - which more closely simulates how it will be used in production (iOS, Android, Windows Tablet clients), and several different web browsers with manual REST uri entry.
The REST response format for the most part is JSON, but can be anything I want it to be. One of the REST calls I coded returns the session token.
In order to obtain the session token one has to request a resource using https; when the server sees that you have not yet authenticated it kicks back a 401 unauthorized, which tells the browser to force an authentication dialog, seeking username and password, or triggers the indy client to supply the pre-coded credentials.
I set the internal, kbmMW-wrapped Indy http component to use basic authentication (only inside ssl, of course); once authenticated the server generates a session-based token and returns the token to the client.
When I test this in my Delphi client, which uses Indy's TIdHTTP client, and I set it to use basic auth, set the username and the password, and initiate the request, the Indy components preserve the session token and apparently reuse it. I can call the function on the server that returns my session token, and the token remains the same for the lifetime of the session.
If I authenticate with the browser and the un/pw dialog, then call the function to return the session token, I am required to authenticate once using un/pw, but every subsequent request to retrieve the session token returns a different token every time.
My question is, does this mean that a web browser poses a potential security risk to my server? What governs how long a session lasts when the requesting client is a TIdHTTP vs. when the requesting client is a web browser (I've tested IE, Chrome, Firefox, Opera - all the same response)?
Why does a browser get a different token with every request, while an indy client reuses the same token over and over until expiration?
Does this mean that a potential hacker could compromise my server by utilizing a DDOS attack vector and creating sessions on my server until it runs out of memory?
I thought that the Indy http server would distinguish a requestor based on form vars like Referer, IP Address, Browser type etc. How can a browser, executing the same request over and over with the same IP, Referer etc. force a new login at the server side each time?
Is the browser caching the username and password and ignoring the token?
The server side authentication event only fires once with an indy client request, but fires with every request from a web browser, resubmitting the un/pw combo every time, and ignoring the token.
Should I set an ETag in the response header to the token so that the browser won't keep logging in and creating new sessions?
Help!

Identity Server 4 - Check iframe session issue - oidc client

I'm using OIDC Client in my angular application for authentication against identity server 4. Everything works fine until i hit sign out.
I've enabled monitor session (enabled by default) so that other browser can detect the sign out and i can log the user out in other tab of the same browser. When I sign out from one tab, the other tab makes a request to the identity server for silent refresh token and that get succeed. I'm expecting the other browser to signout as well. If i hit the F5 in the other tab then yes, it gets redirected to login again. but not automatically.
Update
to log out from other clients that share the same identity server frontChannel
, you can add an Iframe in your identity to notify your clients about the logout (oidc-client.js supports front-channel signout)
Front-channel server-side clients
To signout the user from the server-side client applications via the front-channel spec, the “logged out” page in IdentityServer must render an to notify the clients that the user has signed out. Clients that wish to be notified must have the FrontChannelLogoutUri configuration value set. IdentityServer tracks which clients the user has signed into, and provides an API called GetLogoutContextAsync on the IIdentityServerInteractionService (details). This API returns a LogoutRequest object with a SignOutIFrameUrl property that your logged out page must render into an .
Back-channel server-side clients
To signout the user from the server-side client applications via the back-channel spec, the SignOutIFrameUrl endpoint in IdentityServer will automatically trigger server-to-server invocation passing a signed sign-out request to the client. This means that even if there are no front-channel clients, the “logged out” page in IdentityServer must still render an to the SignOutIFrameUrl as described above. Clients that wish to be notified must have the BackChannelLogoutUri configuration value set.
Browser-based JavaScript clients
Given how the session management specification is designed, there is nothing special in IdentityServer that you need to do to notify these clients that the user has signed out. The clients, though, must perform monitoring on the check_session_iframe, and this is implemented by the oidc-client JavaScript library.
after that you can listen the event addUserSignedOut of oidc-client in all your clients and trigger signoutRedirect to logout your client
this._userManager.events.addUserSignedOut(() => {
this._userManager
.signoutRedirect()
.then(resp => {
console.log('Success');
})
.catch(err => {
console.log(err);
});
});
check this documentation for more details

How to set a authenticated user web session for sending rest requests

I want to test an API which has the followoing instruction:
This API requires the caller to have an authenticated user web session.
When I login to the application and send a GET request in other tab it works. But I want to send a PUT request now so I cannot use browser. How can I have an authenticated user session while sending request through some other rest client. For eg: postman/ mozilla rest client.
I have tried logging into application through chrome and then using postman rest client. But it did not work. I have also tried Basic authentication providing application username and password.
So, given you mentioned you're using JWT, your API is most likely handing out this token upon logging in. At this moment your web client (javascript?) is probably storing it somewhere (cookie, local storage, session storage… – you can use your browser's dev tools to inspect). For all subsequent requests, this token is attached. If this token is getting persisted as a cookie, the browser itself takes care of attaching it to every request. If it is persisted somewhere else, your client has to "manually" attach this token to every request.
If you want to test your API call, first you need to login and get your hands on the token. Then, for all authenticated requests, you need to attach this token (probably as the Authorization HTTP header).

REST Service with third party OAuth2

I'm building a REST server and a client for it. Now I need to embed some third party oauth2 authentication. Right now I'm directing the user to the server, let him authenticate to the service and then I redirect to the client, somewhat like this:
Client: Not Authenticated -> Server -> Redirect to Third Party -> Redirect to Server -> Redirect to App.
Then I store a cookie on the client to identify the user (the cookie is sent using withCredentials and CORS).
My problem now is what should I do with re-authentication when the token expires? Since the client and server only communicate through json, I would have to initiate the full authentication process again and therefore the user would lose all state in the app. Does anyone have a suggestion on how to get around this problem? Is it better to do authentication on the client side and store the access token on the server or something?
Whatever you have done is the proper way to get OAuth access_token. And your access_token is temporary so can expire.
I think you can do either of these :
Check if Authorization Server ( which you use for getting token) provides option to get a longer duration token using your access_token. This is suggested in OAuth 2 specification as well.
Try to store User's state without using session.

Can I avoid session authentication in my web service without having to validate the username/password in each request?

I am building a RESTful web service using ASP.NET web API. I've read that it isn't very RESTful to use session authentication since a "login" request is required before any other request can be successfully made. In addition, it requires the client to maintain state.
My original design was to have the client call a "login" request using basic HTTP authentication over SSL. The web service would then verify the credentials and respond with a session key. The client then uses that session key to sign all subsequent requests. When the web service receives any of these requests it looks up the session key, signs the request in the same way, and checks if the two signatures are equal.
Is it possible to avoid this session authentication without having to send the username/password with each request? The credential verification does not happen within the web service (it is routed to another server that maintains users). I'm concerned that performance will be affected if I need to validate each request.
It's not possible. You either store the state or get the credentials with each request. The second option is what you would want with your HTTP API.
Depends what you mean with "validate"
you could e.g. cache the hash(username+password) in your application. And on subsequest requests check if the cached entry still exists. This way you can save roundtrips to your backend store.