How to debug warden/devise because it's ignoring a cookie - ruby-on-rails

I used SAML strategy for devise (https://github.com/apokalipto/devise_saml_authenticatable).
I did some modifications to it and I see that if a user isn't authenticated it goes and authenticate a user and I log that sucess!() called. As result, browser is getting a session cookie.
The browser coming back to my website with this session cookie. However, warden requires to authenticate again (leading to never ending authentication loop) instead of just letting this user through.
My question is: How can I debug it to see why warden calls authentication (vs just letting it through).
I added before_action to ApplicationController and did puts request.env. I see that session cookie is coming. However, I am not sure what should be the next step to check what's going on.

Related

Post CSRF check, devise still runs full function

In Rails, using devise, if a CSRF Check fails then the user's current session is cleared, i.e., logs the user out, because the server assumes it's an attack (which is the correct/desired behavior).
But the request, is completed, hence the user record is still created. Hacker can then log in correctly.
How can I stop the method from continuing once devise realises auth_token is incorrect?
Devise doesn't do any checking of the auth token - it's action controller which does this (although it does call handle_unverified_request on your controller so that you can customise behaviour). In rails 4 and higher you can also specify what happens by default when the auth token is invalid:
protect_from_forgery with: :exception
causes an exception to be raised, which would stop the request being processed.
However I am not sure what this buys you though - CSRF is so that an attacker cannot abuse the fact that the user is already logged into your application, but if the attacker has a valid set of credentials then they don't need to do CSRF in the first place.

Devise Warden Authentication Fails First Time, Succeeds After

I am using Devise to authenticate users for my rails app using database authentication (for username and password) and token authentication for an API that I built with Grape. Devise is generating an authentication token as expected. However, it seems that authentication always fails after the first request and works subsequent times. I am calling authenticate! before my API calls in Grape, which is defined as follows:
def authenticate!
error!({"error" => "Unauth 401"}, 401) unless env['warden'].authenticate
end
This is very odd behaviour. If I try to login with the browser first, then via a curl call to the API, it works. It seems that the first request will just always fail after a server restart.
Is that the expected behaviour? If so, why is that and how do I avoid it? Do authentication key logins always need a regular login via the browser first?
P.S: I did read Devise authentication fails on first attempt, succeeds afterwards, but it does not seem to answer the question.

Spring Security "exceptionMappings"

Using Spring Security preauthentication, my web app re-directs to /login_disabled.html upon hitting a InsufficientAuthenticationException.
sample of applicationContext-security-preauth.xml
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop key="org.springframework.security.
InsufficientAuthenticationException">
/login_disabled.html
Based on this post, it seems that I should be able to re-direct the user to log in again.
Would I just need to re-direct the user to the webpage responsible for authentication?
It's not really clear for me what's the problem here. The redirection to the login page is automatically done without any further configuration if you have form-login set up. If the user tries to access a secured page without being authenticated, the ExceptionTranslationFilter invokes the AuthenticationEntryPoint to initiate authentication.
Using ExceptionMappingAuthenticationFailureHandler to map InsufficientAuthenticationException to a redirect-url won't work anyway because:
It's not indicating an authentication failre. It indicates the condition that the user is only anonymously authenticated while trying to access a secured resource. (As opposed to an auth failure such as entering bad credentials, or user has disabled status.)
It never even gets thrown. (Only instantiated and passed as a parameter in the above linked code.)

Occasional 422 error: client not sending session cookie?

A few users are getting a 422 ActionController::InvalidAuthenticityToken error when POSTing a form.
It happens to a minority of users some of the time. If they try their request again later, it often works.
The authenticity token is getting sent along in every case. I'm assuming the client isn't sending the session cookie along with the POST (that would explain why the server can't verify the token). Why would this be?
Finally, the form is submitted via javascript ($('#new_user')[0].submit()), would that somehow prevent the session cookie from being sent?
Disabling the verify_authenticity_token before_filter is unfortunately not an option.
We have run into this scenario with one of our apps. We store our sessions in memcached and if the session is evicted from the cache or the session expires any subsequent post/put/delete raised a 422. We got round this by implementing a before filter 'requires_login?' that checked the session and logout the user out if the session had expired. We then moved the method protect_from_forgery in the application controller to run after requires_login?
E.G
before_filter :requires_login?
protect_from_forgery
Hope this makes sense

Rails app session not recognized for iOS NSURLRequests

I have a simple rails app with a single controller. I have a "before filter" for some of the methods of my controller, where I check if the user is logged in by looking at the session object:
#user = User.where(:id => session[:user_id]) if session[:user_id]
In a "login" method of my controller, I do:
session[:user_id] = user.id
Pretty usual stuff. If I access my app from a web browser (Chrome), everything works fine. However, when I use NSURLRequest from my iOS app to access my rails app, the server always creates a new session for each request. It never seems to be able to identify the existing session, even though the request is sending the cookie with the proper session ID in it. In fact, if I look at the "cookies" object in my rails app, I can see it contains the session ID. However, the session object is always empty! Not sure why the server is not able to retrieve the session. I'm using Passenger Phusion. Any suggestions?
If you are POSTing to your login page, and the post does not include a CSRF token matching the token in the session, then Rails will fail the request and invalidate/reset the session as a security precaution.
To fix it, simply read the CSRF token out of the session and include it in your request, or turn off CSRF token checking, you can place skip_before_filter :verify_authenticity_token in your controller to skip the CSRF protection checks. Note that the latter approach does open potential security holes, so including the tokens and checking them is recommended if it is at all viable.

Resources