SP initiated SAML logout response success, Idp does not log user out - c#

I have created a SAML library in my app that creates an authentication request and is successfully logged in, but when it sends a LogoutRequest, the response shows:
"samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"
This should mean that the session has ended successfully at the Idp correct? I provide the session ID and the username of the logged in user in the logout request the same way as successfully specified in the auth request. However, when I attempt another login request, I am not prompted for credentials as though the session is still active. What would cause this? I do not have access to the Idp's ADFS server to view the logs and they are taking a long time to respond with them. Could I be missing something and still get a success message when it really wasn't a successful logout?

Related

Identity Server 4, ASP.NET Core Identity and registration return url

I have an Identity Server application with ASP.NET Core Identity interface to manage login, registration, ecc.
I have some MVC applications that rely on the Identity Server to authenticate.
Everything is working correctly: when I try to access a protected page, I'm redirected to the login page and, after login, I'm redirected back to the protected page that is now accessible.
The only problem is that the returnUrl passed to the login page is something like
/connect/authorize/callback?client_id=myClientId&redirect_uri=https://localhost:44309/signin-oidc&response_type=code&scope=openid profile email offline_access&code_challenge=yyfbWuF...&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0
If I add this url to my registration confirm email link, it will work only if the link is opened in the same browser where I started the authentication request.
If the confirm email link is opened in another browser it will confirm the account and login correctly, but, when redirected to the client, it will cast an exception:
Exception: Correlation failed.
Unknown location
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
This is because, i guess, the new browser doesn't have the cookies generated during the authentication attempt in the other browser.
So my question is:
is there any way to get the original protected page url, when redirected to the login page, so I can use that in my confirm email link?
It should be enough, because, once the account is confirmed I would be redirected back to my protected page that should fire a new authentication request to the login page, but, being already logged in, it would be a silent authentication.
"This is because, i guess, the new browser doesn't have the cookies generated during the authentication attempt in the other browser."
This is also my understanding.
One approach to this issue is to handle the error gracefully on the client side. If this type of error occurs (correlation failed), we know something is not right with the authentication and we redirect to the login page on the client side. (Perhaps, an unfriendly is trying to gain access, so redirect to the login page.)
In terms of a user confirming their email on a different browser, I think that is reasonable to redirect to a login page and have them login. They register, confirm their email and then are asked to log in to the application if it is a different browser.
Let me know if you worked something else out!

CSRF validation fails for certain calls in the same request

After login page, the application makes multiple calls to bring up a report. Intermittently, some calls fail with 500 error with underlying message "A required anti-forgery token was not supplied or was invalid".
It doesn't always happen. Sometimes. the entire request is successful and the report comes up without issues. Other times, I see this anti-forgery error.
We have the same __RequestVerificationToken both failed and good calls in the same request. Session ID is the same as well. Any idea why it this issue is happening?
Successful request:
Failed request:
Problem
The CSRF token is being reused for requests subsequent to authentication A CSRF token is only valid for the initial session. Once authentication occurs, a new session is created and thus a new CSRF token is required.
TL;DR
You’re seeing an invalid token error because the token you’re using is from the session prior to user login
Solution
Refresh the CSRF token after authenticating user.
References
Refresh CSRF token after authentication: https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-3.1#refresh-tokens-after-authentication

Token authentication for an ASP.NET Website

I developed an ASP.Net website with cookie authentication.
After reading about CSRF attacks I decided to change my website to work with token authentication which will be saved in the client side.
So what I have done is:
used logins
user receives a token and saves it in the sessionStorage
user sends the token in the header of each API requests.
This works great.
Now the one thing that is missing for me is the page loads, meaning if a user tries to access a page before he is logged-in it should redirect him to the login page. This is something I want to do obviously before the page is loaded, for example before i had this code in the Site.Master:
if (!AuthCookieValidator.IsValid(HttpContext.Current))
{
s_Logger.Info("the user is not authenticated, logging out!");
Response.Redirect("/Login");
}
But now I can't implement this logic unless i keep both session based token + client side token.
What's the solution here?
So my solution is like so:
User logins
User receives a token and saves it in the sessionStorage
User sends the token in the header of each API requests.
If the user tries to reach a url directly, before the react code starts to render the page it will send an authentication check request with the token and render accordingly.
Any comments are appreciated about my approach

How to restrict a user ID to have only one Login at a time in ASP.NET Web API

The Thing i want to do is , We have a user who is logged in a device .We have to restrict that user to login from other device.
To Login into Other device he should have to log out from the first device.
I have tried to create authentication token via web API.
Every time a user login ,a new oath token is generally passed in the request headers. (Token would be expire on logout.)
If Same User try to login from other device a new Oath token would be generated
is there anyway to check if a token is already assigned to that user then do not allow him to login
What if,
1.user close the working tab or browser
2.or He navigate to other web page by changing the URL
Are there other solutions to ensure one concurrent login per user ?
This should be simple enough to make sure a user have only one login at a time.
Steps to do would be (ASP.NET/ASP.NET MVC):
Step 1: As soon as user login, check if session for this user already exists.
Step 2: If Session already exists, delete the on going session (Here you can also prompt a message to user if he wants to stop currently going session and start a new one.)
Step 3: On User's action you may delete current session and start a new session for the user.
Step 4: If there is no current session going on, you can simply create a new one .
Update:
For ASP.NET WEB API
Here you have to use Authentication token.
On login you can provide authentication token to user.
On Relogin you can check if token is already issued for this user, and accordingly perform your action.
Hope this helps. Let me know if you have queries.
I assume you know how to code above, if not let me know.

Return HTTP 401 and say client DO NOT repeat request

We implemented custom authentication. User name and password are send in request body. If user or password is invalid then Server returns HTTP 401. Server is implemented with C#, MVC3 and .NET 4.0.
We faced the problem that if client received 401 then it automatically resends the same request 2 times. Actually this is issue for iOS only. iOS guys said that it happens on low level and it is out of control in application. So probably server should be able to say client do not send request again.
This is problem for us because we use Active Directory and in case of invalid password we spend 3 attempts instead of just one. So account becomes locked very soon and unexpectedly.
I found this document that says
401 Unauthorized
... The client MAY repeat the request with a suitable Authorization header field.
How to return HTTP 401 and say to client DO NOT repeat request anymore?
You may use 403 instead:
From W3 site:
10.4.4 403 Forbidden
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
Indeed, this is a little tricky: 403 seems more appropriate when authentication was successful, but the resource requested is not allowed for the specific user, which is not your case. However, 403 means client should not repeat authentication, and this is what you want.
If the login page is to be interpreted only by humans, then you may consider returning "200 OK" and simply display the login page again (perhaps with a visible indication to the user that the login has failed).

Categories

Resources