Using Omniauth both for login with Devise as well as for accessing API's - devise

In our application, we allow the user to access their data at different providers (Google Calendar, Microsoft Outlook, Facebook timeline, etc.) through the available API's, using Omniauth. For this we have an omniauth.rb with all the necessary configs, like:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], scope: 'email,user_posts,user_status,public_profile,manage_pages,instagram_basic'
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
name: 'google',
scope: 'email, profile, calendar.readonly',
access_type: 'offline',
prompt: 'select_account consent'
# etc...
end
Now we like to add login with Google as an alternative way to log in. Since we use Devise for our user session management, we'd like to use Devise's Omniauth features to implement login with an OAuth provider like Google. However, as soon as we make our model "omniauthable", the existing Omniauth functionality stops working throwing an No route matches [GET] "/auth/facebook" when trying to add an oauth account to access an API.
What is the correct way of combining the use of Omniauth in both Devise and in our own plain vanilla OAuth flow?

I found the answer myself: it's a matter of not using the thin wrapper of functionality that Devise adds to OmniAuth, but instead taking care of the OmniAuth routing yourself. I have described this approach here in the Devise Wiki.

Related

Ember-Simple-Auth customised Devise Authenticator serverTokenEndpoint defaulting to users/sign_in

Pretty much as described in the title. I have a basic Ember Simple Auth setup. With a Devise Authenticator I've setup a custom URL for the serverTokenEndpoint.
(Coffeescript)
devise = DeviseAuthenticator.extend
serverTokenEndpoint: ENV.apiBaseURL + 'session'
tokenAttributeName: 'authentication_token'
resourceName: 'session'
export default devise
Authenticating and Invalidating are ok. But trying to navigate to certain pages I get requests for - https://apiBaseURL/users/sign_in. Which the endpoint doesn't exist.
Why is the configured URL not being used?
Or are there any other places this URL is set? Or used? It's currently causing the page to break and the user cannot continue.
Leaving this question here incase others stumble upon this issue as well. It was actually an issue with the back-end Devise setup.
Any endpoint which required Authentication token was sending this redirect if no token found/ was invalid. URL was take from the devise configuration of the back-end.

Ember Simple Auth with Multiple Devise Scopes

I have the following scenario:
Rails app with User and Admin devise models, so I have two scopes.
Created on ember app on router:
Router.map(function() {
this.route('panel', function() {
this.route('login');
this.route('logout');
});
this.route('admin', function() {
this.route('login');
this.route('logout');
});
});
I'm using jj-abrams branch once my app is Ember 2.0
Both authenticating on /users/sign_in and /admins/sign_in
I followed steps on https://github.com/simplabs/ember-simple-auth/tree/master/packages/ember-simple-auth-devise#server-side-setup and authentication is working.
Ember is hitting the right urls after creating authenticators and adapters, but the problem is that ESA just have one session service. Once user or admin is logged in session.isAuthenticated is true and I don't know which scopes are logged in.
Which is the best way to proceed:
Add a role on user reply and set on session
Create a new session for admin user
I solved this problema creating 3 authenticators for each scope, and I handle each one.
It is a particular solution once I don't use other authenticators (OAuth2), but now I can check if authenticator:user, authenticator:admin, authenticator:manager was used on to login.
I have created checks on routes, so user can only access his panel, admin can access user and admin panel, and manager can access the whole system.
I've posted the ember and the API on github:
https://github.com/fernandes/ember-auth-web for the ember
https://github.com/fernandes/ember-auth-api for the devise api
ps: I think would be better to create sessions for each scope, but I don't know how to do it (and if its better or not), in this solution you can login one scope at once (not like devise on rails you can log with many scopes at once).

How to integrate Devise and SAML?

What is the best way to get SAML working with the widely used https://github.com/plataformatec/devise?
https://github.com/apokalipto/devise_saml_authenticatable doesn't do signed/encrypted auth requests and that's a deal breaker for us, and the usual sources haven't helped.
Devise's Omniauth integration, for example, requires an app ID and secret that Onelogin's SAML connector doesn't provide.
So, the answer that worked for me is to use the gemlfile and omniauth.rb settings as outlined in https://github.com/PracticallyGreen/omniauth-saml#usage and then to follow devise's omniauth tutorial at https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview, replacing facebook with SAML. Note that you mightn't need the UID field mentioned in the tutorial, depending on how your IdP stores their users (and you wouldn't get a permanent UID if you use the transient nameid format). Use whatever uniquely identifies your user at the IdP, which is quite possibly an email address.
The devise.rb stuff added by ioblomov doesn't seem to add anything and in fact causes an issue if you do it as well as doing an omniauth.rb file. This creates a situation where the IdP does two callbacks, one using the omniauth.rb settings and another using the devise.rb settings. Given that the devise.rb settings are not complete (they don't have a consumer url for example), I can't see how even having it on its own could ever work. It is not clear to me what "devise integration" even means in the context of omniauth-saml. Once you get an auth response back (which you will just from using the omniauth.rb settings), then all you have to do is use the devise method sign_in_and_redirect in your callback controller and then you have all the usual devise stuff available to you for that user. I will submit a PR to omniauth-saml but I wouldn't be holding my breath as the project appears to be sporadically maintained at the moment.
I had to deal with recently to hook a rails app up to a university network using Shibboleth for SSO. I ended up using devise, omniauth and running on Apache with mod-shib2. I am not sure if you are using Shibboleth specifically but it is built on top of SAML. The lightweight rack-saml implementation did not work for me.
Turns out the Devise config's parameters were wrong. I documented the correct settings in a fork/PR:
https://github.com/omniauth/omniauth-saml#devise-integration

Rails RESTful API + Devise - How to check for user's credentials

I've built a RESTful API with Ruby On Rails, and now I good like to know whether the user's credentials received by POST are valid or not, using Devise.
Any ideas?
Devise - getting started should set you up.
EDIT:
Devise, by default, validates users by their email and password. If you want to add validation by username, refer this wiki
Basically, you need to add username to the model and make it 'attr-accessible'
Devise sets up paths for user sign-up, sign-in and sign-out, etc.
Refer devise asciicast for these path helpers.
To write controller tests, refer to this wiki for details.
EDIT:
Sorry for not understanding your requirements. Here is how to find user from credentials. This you can use from your service to validate user.

Multiple authentication schemes with Devise and Rails 3

This is probably a common question, but I haven't seen any complete answers to it anywhere:
I have an Rails 3 app that is using Devise for authentication on the web and is working fine. All actions on all controllers are authenticated and the routes are all restful. Users get redirected to a web page to enter their username and password and then can access the resources.
Now I need to add an API to the system. Most of the controllers/actions will be shared between the web and API users, but the API users will have a different authentication scheme (API keys perhaps).
So, if a web user goes to
/projects/1/users
to see the users on the web, an API user should go to
/api/v1/projects/1/users
to see the same thing with a parameter like APIKey=abcd.... either in the header or params to allow authentication.
I know the solution is around overriding the SessionController and the Routes but can't find a detailed answer about this anywhere.
You might be able to achieve the same results by using Token authentication:
http://rdoc.info/github/plataformatec/devise/master/Devise/Models/TokenAuthenticatable