I am using the doorkeeper gem to use tokens to authenticate requests.
When I have doorkeeper_for configured as defined below, tokens are required, which is good and expected:
doorkeeper_for :all
When I set a conditional for doorkeeper_for to be the condition I actually want (allowing requests to local deployment endpoints without tokens)
doorkeeper_for :all, :unless => lambda { request.url =~ /http:\/\/(localhost|127.0.0.1|0.0.0.0):8080/
Or if I set this condition to any number of junk conditions:
doorkeeper_for :all, :if => lambda { true }
doorkeeper_for :all, :unless => lambda { true }
Then doorkeeper allows all requests to go through without tokens, which is bad and not expected.
Noting that I have a require 'doorkeeper' statement and that I've fiddled around with various include statements in my API controller such as include Doorkeeper::Helpers::Filter
This may have to do with a problem with Doorkeeper working with Grape, though again it is strange that it works just fine without the conditional. Any insight into why this is happening would be appreciated!
After speaking with the main contributor to doorkeeper-gem we've determined that it has to do with the use of Grape. This feature should work just fine with Rails based controllers:
https://github.com/doorkeeper-gem/doorkeeper/issues/426
Grape itself is supposed to be a closer-to-the-metal API framework and isn't necessarily supposed to be used with Rails, which contributed to this issue.
As a final note, there is a gem specifically for integrating Grape and Doorkeeper gems:
https://github.com/fuCtor/grape-doorkeeper
Related
I am using authlogic gem for the authentication and recently we implemented feature for logout_on_timeout.
So we have placed the below code:
class UserSession < Authlogic::Session::Base
before_persisting :reset_stale_state, :unless => :single_access?
after_persisting :enforce_timeout, :unless => :single_access?
logout_on_timeout true
end
The single access token works but then logout on timeout stops working. We have a discussion thread already on this:
https://github.com/binarylogic/authlogic/issues/64
But unfortunately, none of the solutions work.
Kindly advise on how to get timeout working while keeping single access token.
I have currently configured Devise,Doorkeeper and grape in my rails application.
Devise and Doorkeeper are configured so that I can register and login with Devise on the website and Doorkeeper provides oAuth endpoints that can create tokens.
How can I add a token to a HttpRequest and protect the grape API with it?
Edit:
So I tried to implement the Winebouncer implementation Tom Hert suggested.
I followed the instructions on https://github.com/antek-drzewiecki/wine_bouncer
I have installed the gem.
I have defined config/initializers/wine_bouncer.rb as the following.
WineBouncer.configure do |config|
config.auth_strategy = :default
config.define_resource_owner do
User.find(doorkeeper_access_token.resource_owner_id) if doorkeeper_access_token
end
end
I have registered Winebouncer as middleware in grape in my base api controller.
app\controllers\api\base.rb
module API
class Base < Grape::API
mount API::V1::Base
use ::WineBouncer::OAuth2
end
end
I mounted my projects controller in my V1 base controller
app\controllers\api\v1\base.rb
module API
module V1
class Base < Grape::API
mount API::V1::Projects
end
end
end
And this is my projectscontroller
app\controllers\api\v1\projects.rb
module API
module V1
class Projects < Grape::API
version 'v1'
format :json
resource :projects do
desc "Return list of projects" , auth: { scopes: [] }
get do
Project.all
end
end
end
end
end
To be honest I don't yet know how the ", auth: { scopes: [] }" in the description is suppossed to work. And how to add the token to a request, but I would expect my request but be blocked when no token is added. But the the request is still producing the json data.
I found quite interesting code here: https://github.com/fuCtor/grape-doorkeeper
It seems to be still maintained. But I think this is good just to get the idea of what is going on there.
I would recommend this: https://github.com/antek-drzewiecki/wine_bouncer
As said on the page:
Protect your precious Grape API with Doorkeeper. WineBouncer uses
minimal modification, to make the magic happen.
obedeijn, i just noticed your question on stackoverflow.
WineBouncer works just like doorkeeper, it looks for the Authorizations header with a "Bearer x" where x is the token.
I am using devise + omniauth to enable facebook/linkedin/twitter login on my website.
I have multiple models with totally different roles and both need social logins, I have been using devise+omniauth successfully unitl now as I needed that only for one login.
However now devise gives error saying I cant use omniauthable on multiple models.
I looked around and someone was helpful enough to create this wiki explaining how to use omniauth with devise without omniauthable module.
But I think since I would want to use it for different models, I would have to use different paths for signup, which this wiki doesnt explain.
I looked into omniauth and it has some scarce details about options request_path and callback_path which seem to be relevant, but I couldn't figure out what exactly needs to be done.
Any help will be much appreciated.
EDIT
This is what I have done till now.
# omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
FACEBOOK_AUTH_REGEX = /^\/(model1|model2)\/auth\/facebook\/$/
FACEBOOK_CALLBACK_REGEX = /^\/(model1|model2)\/auth\/facebook\/callback\/$/
LINKEDIN_AUTH_REGEX = /^\/(model1|model2)\/auth\/linkedin\/$/
LINKEDIN_CALLBACK_REGEX = /^\/(model1|model2)\/auth\/linkedin\/callback\/$/
facebook_callback_path = lambda do |env|
env["PATH_INFO"] =~ FACEBOOK_CALLBACK_REGEX
end
linkedin_callback_path = lambda do |env|
env["PATH_INFO"] =~ LINKEDIN_CALLBACK_REGEX
end
facebook_request_path = lambda do |env|
match_data = FACEBOOK_AUTH_REGEX.match env["PATH_INFO"]
if match_data
"/#{match_data[1]}/auth/facebook/callback/"
end
end
linkedin_request_path = lambda do |env|
match_data = LINKEDIN_AUTH_REGEX.match env["PATH_INFO"]
if match_data
"/#{match_data[1]}/auth/linkedin/callback/"
end
end
provider :facebook, FACEBOOK_ID, FACEBOOK_SECRET, :callback_path => facebook_callback_path, :request_path => facebook_request_path
provider :linkedin, LINKEDIN_ID, LINKEDIN_SECRET, :callback_path => linkedin_callback_path, :request_path => linkedin_request_path
end
#routes.rb
match "/:model_name/auth/:provider/callback/", :to => "recruiter_omniauth_callbacks#sync"
And it seems to work fine for linkedin but in facebook I get
{"error":{"message":"Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request","type":"OAuthException","code":100}}
Not Sure why I get this, what are the two urls it says should be same, I think I am using :model_name/auth/facebook/callback/ everywhere so not sure what is the problem it has.
Any help?
I post an example for a similar case here with other perspective of attacking that problem, hope it helps, regards!
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I use rspec, devise and cancan at the moment. To be honest, I find cancan to be very confusing and I am encountering a lot difficulties in picking it up and using it effectively. The docs are not very in depth making this extremely difficult for me to debug (check my past questions).
Is there an alternative to CanCan that's also easily integratable in the other tools I am using?
As of early 2014, Pundit is a popular alternative to CanCan (and the successor CanCanCan). Pundit matches each controller with a policy object. Unlike CanCan, there's no central rule file for all access control. It's simpler than CanCan. There's an example app from the RailsApps project:
Rails Pundit Example
I've also written a tutorial on Rails Authorization with Pundit.
Another alternative is the Authority gem from Nathan Long. All your rules logic goes in Ruby classes called "authorizers" that are associated with models.
Some guys are continuing the development of cancan. Check it out:
https://github.com/CanCanCommunity/cancancan
For the same reason i've done this: http://mcasimir.github.com/checkin/.
Checkin is an authorization gem that is independent from the role/authentication library you use.
You can express even complex rules rather simply with a declarative/cascading permissions DSL.
I found it very handy. The debug is also supported via the explain method that will log the authorization process on every request.
Here are some of the features:
Handy DSL to define roles and permissions with a declarative approach
Check authorization for CRUD operations automatically
Standard way to rescue from Authorization errors
Authorization subject decoupled from model (compatible with any autentication system)
Role-based authorization decoupled from role system (compatible with any role
system)
Decorator for current_user and other subject objects
Scoped authorization rules
Cascading authorization rules
Simple: even complex authorization behaviour is understandable at glimpse and
easily predictable
Support for controller based mass assignment protection
Here is a very simple example of the DSL:
class UserSubject < Checkin::Subject
role :guest, :alias => :anonymous do
!subject_model
end
role :logged_in, :alias => [:connected] do
!!subject_model
end
role :owner, :require => [:logged_in], :method => :own do |object|
object && ( object.respond_to?(:author) && ( subject_model == object.author ) ) || ( object.respond_to?(:owner) && ( subject_model == object.owner ) )
end
role :administrator, :require => :logged_in, :alias => :admin do
subject_model.has_role?(:administrator)
end
#
# Permissions
#
permissions :for => :comments do
allow :administrators
allow :logged_in, :to => [:create]
deny
end
# Admin
scope :admin do
permissions do
allow :administrators
allow :owners, :to => [:edit, :update]
deny
end
end
end
Checking roles and permissions:
subject = UserSubject.new(User.first, :scope => :admin)
subject.logged_in?
subject.guest?
subject.own?(Post.first)
subject.can_edit?(Post.first)
I apologize for being so wordy.
I found https://github.com/stffn/declarative_authorization to be rather complete. And it's logical to use.
Sounds like Pundit may be coming up strong. It has a less 'magic', more straightforward approach.
https://github.com/elabs/pundit
I am currently exploring Heimdallr. The one feature it has that most of these cancan alternatives don't are restricted scopes for index actions.
You also might want to check out this "ultra lite authorization library" - six
Check TheRole gem. very interesting alternative for cancan
I'd recommend Action Access, it's much simpler and straightforward, has seamless integration with Rails and it's very lightweight. It boils down to this:
class ArticlesController < ApplicationController
let :admin, :all
let :user, [:index, :show]
# ...
end
This will automatically lock the controller, allowing admins to access every action, users only to show or index articles and anyone else will be rejected and redirected with an alert.
If you need more control, you can use not_authorized! inside actions to check and reject access.
This makes controllers to be self contained, everything related to the controller is within the controller. This also makes it very modular and avoids leaving forgotten trash anywhere else when you refactor.
It's completely independent of the authentication system and it can work without User models or predefined roles. All you need is to set the clearance level for the current request:
class ApplicationController < ActionController::Base
def current_clearance_level
session[:role] || :guest
end
end
You may return whatever your app requires, like current_user.role for example.
It also bundles a set of handy model additions that allow to extend user models and do things like:
<% if current_user.can? :edit, :article %>
<%= link_to 'Edit article', edit_article_path(#article) %>
<% end %>
Here :article refers to ArticlesController, so the link will only be displayed if the current user is authorized to access the edit action in ArticlesController. It supports namespaces too.
It allows to lock controllers by default, customize the redirection path and the alert message, etc. Checkout the documentation for more.
There's also Consul.
You create a Power class with methods that return only those objects the user has access to, instead of loading objects and check permissions on them. Talk by the author.
I have a controller action that may be hit by the client with a
oauth client token (no authenticated user), or may be hit by an authorized client with an access
token (for a specific user). I want to set up a nice little before filter to accomodate
this. I tried:
oauthenticate :strategies => [:oauth10_request_token, :oauth10_access_token],
:interactive => false,
:only => [:wonky_action]
If I try to hit this action with an access-token request, then it
complains because it tries to remember the OauthNonce twice. Here's
what my ClientApplication.verify_request method looks like:
def self.verify_request(request, options = {}, &block)
begin
signature = OAuth::Signature.build(request, options, &block)
nonce = OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
unless nonce
Rails.logger.warn "Oauth request failing because of invalid nonce."
return false
end
value = signature.verify
unless value
Rails.logger.warn "Signature verification failed."
end
value
rescue OAuth::Signature::UnknownSignatureMethod => e
false
end
end
Looking at this, the behavior is no surprise. It runs through the
oauth10_request_token method, and remembers the nonce without a
problem, but the token is not a request token, so it fails. Then, it
tries to run through oauth10_access_token, and when it calls
verify_request the second time, it tries to remember a nonce that
we've already remembered.
The best solution I can come up with is to separate the Nonce-remembering from the rest of the request verification. In other words,
the server would verify the nonce first, and then do the signature
verification (or whatever else verify_request wants to do) as many
times as it pleases.
I don't see a clear way to do this without forking Pelle's
application_controller_methods file, but I'm hoping I'm just missing
the obvious fix that one of you will suggest! Thanks for your help!
In case you're interested, I'm using rails3 with pelle's oauth-plugin
and his fork of oauth:
gem 'oauth', :git => "http://github.com/pelle/oauth.git", :require => 'oauth/server'
gem "oauth-plugin", :git => 'https://github.com/pelle/oauth-plugin.git', :branch => 'rails3'