Authlogic - Authentication via basic HTTP authentication - ruby-on-rails

I want to use "authenticate_ with_ http_ basic" but I just can not get it
working.
In my RoR app Authlogic is working fine and I'm using User Sessions for that. While keeping that method as it is now i need to use authenticate_with_http_basic.I have a iPhone SDK app and now I need to fetch some products from my webapp and display as list. So I'm assuming that i need to send the request to my webapp like this; http://username:password#192.168.1.9/products/
So my question is to validate this username and password and what I need to do to my UserSession Controller?

You don't need to do anything with UserSessionController, since that controller would only handle login form submit and logout.
Authlogic and authenticate_with_http_basic is irrelevant to each other. If you want to authenticate via HTTP basic, you just need to create a method to authenticate using method provided by Rails, and put that method on the before_filter. By logging in via HTTP authentication, I assume that the username and password should be mandatory for every request.
So finally, your ProductsController would be something like this
class ProductsController < ApplicationController
before_filter :authenticate_via_http_basic
# In case you have some method to redirect user to login page, skip it
skip_before_filter :require_authentication
...
protected
def authenticate_via_http_basic
unless current_user
authenticate_with_http_basic do |username, password|
if user = User.find_by_username(username)
user.valid_password?(password)
else
false
end
end
end
end

Authentication via HTTP Auth is now integrated into AuthLogic, and it is enabled by default.

Related

How do you restrict access to a certain webpage?

I am trying to allow access to the log-in/sign-up page for a admin user only from my computer or any other way that lets me only see the web page for an admin sing-up-log-in.
Or what do typical web applications do to restrict access to the public towards a certain web page? If there is a bets-practice way, I would like to implement that.
I currently have Devise installed.
You can use the authenticate_user! Devise helper, adding it as callback within the needed controller and specifying the methods you want to control.
For instance if you have a Post model, then adding the authenticate_user! in the PostController it'll ask the user to be logged to have access to the methods in that specific controller:
class PostsController < ApplicationController
before_action :authenticate_user!
If you want to restrict just some specific methods then you can play with only and/or except.
See: Devise will create some helpers to use inside your controllers
and views. To set up a controller with user authentication, just add
this before_action (assuming your devise model is 'User')
Devise - Controller filters and helpers
According to your comment then you can create a method in the ApplicationController in order to restrict all of your controllers and methods.
This way you can define an array of addresses, and if the remote_ip coming from the request is in the array then you give access, if isn't then perform any other action:
ApplicationController < ActionController::Base
before_action :protect
private
def protect
addresses = ['127.0.0.1', ...]
if addresses.include?(request.remote_ip)
# give access
else
# restrict access
end
end
end
But if you need something more sophisticated then you'd have to see on your Nginx or Apache, whatever you're using to deploy your project.
I normally restrict webpage access through controller methods. My recent use case was going to a webpage only when payment was successful but redirecting when it was not, if any body issued a get request for that page directly, it would result in 404.
In your case, there can be multiple option for setup.
You can use cookies to see users credentials using Action Dispatcher
Use Devise for users and then you can fix a certain role to a user through adding a new migration and assign roles yourself after registering or let them choose.
I will expect you followed Devise route. In the controller action check for current user's role.
If User Not signed in (using current_user == nil)
redirect to home page and then return
else
if
its admin you go ahead and use the success page as partial and let them see the page using `<%= render 'pages/mypage'%>` and use return to end
else
just redirect back to home page with a notice "Don't try this".
redirect_to root_path, notice: 'Don't try this' and then use
return to end
end
(Just for fun, to see how many times a user did this wrong action, you can also have a table which stores current_user and number_of_wrong_attempt, and store their email whenever they try to go that page without permission before redirect in controller. After that you can email them with a background rake task which checks for a certain false attempt threshold that: "Hey! Your registration is being removed because you are doing unprohibited actions")

Devise AJAX - POST request : current_user is null

I try to develop a single page application with authentication. I use Devise (Rails) and AngularJS.
For some different reasons my rails application and my angularjs application are not on the same server. So, I have to handle cross domain issues... And I can't send X-CSRF-Token in my header.
I can correctly sign in and sign out and send GET request without problem. In my rails controllers, I can use current_user, it's correctly set.
However, when I send a POST request, current_user is null. It seems my session_id is not sent. The problem is due to cross domain, because if I send my ajax request from the same server, it is OK.
I think, I have 2 solutions :
- Don't use authentication cookie-based, but use token
- Put front-end and back-end on the same server.
Other ideas ? Why current_user is null when I send a POST request from cross domain ?
You could send the CSRF token in the headers HOWEVER it's a bad practice that exposes some security holes (issue thread on github explaining why)
Safest way to go about this is to disable CSRF all together:
class ApplicationController < ActionController::Base
# or use Api::BaseController < ApplicationController if you are namespacing
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session
end
AND use token based authentication that you can either implement yourself or use devise's :token_authenticatable. You will have to configure AngularJS to send the token either in params or headers. Here's a snippet I use for having rails figure out if the token is in the headers or params.
class Api::BaseController < ApplicationController
prepend_before_filter :get_auth_token
private
def get_auth_token
if auth_token = params[:auth_token].blank? && request.headers["X-AUTH-TOKEN"]
params[:auth_token] = auth_token
end
end
end
So in the end how it works is:
Client uses login method that you defined to authenticate
Obtains authentication token from the server
Uses the token in each subsequent request for the purpose of authorization

Devise: after successful login hook

In my rails app, I am using devise for my authentication system. I have a situation in which I want to encrypt some data using a key that is based off of the user's password. The easiest way that I can think to do this is during a successful sign in, to generate the user's private key from their plain-text password (passed in from the login form) and store that in the user's session. I don't really want to ask the user to enter their password more than once.
Does devise provide a way to specify a callback function after a successful login? Or is there a better way to do this?
http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/DatabaseAuthenticatable#after_database_authentication-instance_method
In the user model where you're using devise create a after_database_authentication instance method.
Assume you have Devise resourse User with attribut password, then you can access user password after login in after_sign_in_path_for, which is called after sucessful login.
# app/control,lers/application_controller.rb
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
password = param[:user][:password]
do_cool_stuf_with_password(password)
#...
return url_for_root
end
end

How to authenticate Token with devise

I want to use devise' token_authenticatable helper to authenticate users against the system.
I found some older documentations where a method named valid_authentication_token?(...) is used but couldn't find the same in newer devise version.
So what's the right way to authenticate a user?
Should I request the Model for user with named token and checking if email-adresses match?
Thanks a lot for your help.
PascalTurbo
If you add
t.token_authenticatable
to you user ActionRecord, and add
devise :token_authenticatable
to your User model
and specify which param is your token key in config/initializer/devise, something like this:
config.token_authentication_key = :auth_token
then controllers that use
before_filter :authenticate_user! # Tell devise to use :user map
to authenticate. after the authenticate_user!, individual methods can test using
user_signed_in?
will authorize users either by the login session or the devise authorization token that is passed on the query string or passed using HTTP basic authentication. See Devise helper code for details.

Checking submitted token against authenticity token in database with devise

I'm using a Chrome extension to send data to my Rails app (the staged_images controller). So I have a form that sends the data, along with an authentication token. Each user has a token which is generated by Devise, and is saved into the Users table. What I need to do now is receive that data in the controller and check the submitted token against the one stored in the Users table.
So the create action in my controller should look something like this:
def create
#user = User.find(params[:staged_image][:user_id])
if #user.authentication_token == submitted_token # this is pseudo code, don't know exactly what to say here
# execute code
else
# raise error
end
end
I'm just having trouble with the specifics of how to check the one token against the other. I'm a newbie. Help me!
Thanks
You should pass to the token controller and have a filter on the top and pass a auth_token in your call (http://yoursite/staged_images?auth_token=YOUR_STORED_TOKEN').
class staged_images < ApplicationController
before_filter :authenticate_user!
end
Devise will raise an exception if the token is invalid.
You can access the user information with the helper current_user

Resources