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
Related
I have made an api in laravel with socialite and github and I need to log out so that the application asks me with which github account I want to log in every time.
What you are asking is how to logout from your registered user (which used Github) and destroy the oAuth session of github?
Maybe have a look at this:
laravel socialite logout issue
OK.
If you are using socialite, do check the documentation of each provider you use. Probably you should make a GET or a POST request to their service in order to log out the user.
For example, Globus.org uses this link (documentation link) in order for you to log out your users:
GET https://auth.globus.org/v2/web/logout
Clicking it will log out your user from your service.
Do note that most provider might use similar techniques.
Use POSTMAN to make such requests and experiment (especially when you are trying to register users, making calls with POSTMAN might seem helpful)
Then you are faced with the following issue:
What type of data did you store on you database? (the next bullet might help you understand what I mean)
Did you store in some way, the provider name the user used to login to your system?
If so, each provider might use a different way to log out / register a user from your Laravel project.
We are starting project based on the great jhipster work.
While we would like to keep the option to be session based (with a login page), we also have the need for enalble clients pass user info in the header of each request,
(e.g. Authenticate: username:password) to have it session less like without login, as regular users do.
Do we have this implemented OOTB? If not, what is the best approach for having that?
Thanks ahead for any comment & answer.
JHipster supports both "session-based" (with a login page, and the Spring Security token is stored in the HTTP Session), and OAuth2 (which is stateless, and the token are stored in the database).
The OAuth2 mechanism also uses a login page, but I guess you could make it work without it if needed -> isn't this the best solution for you?
We also have another stateless mecanism in the pipe, see https://github.com/jhipster/generator-jhipster/issues/892
I'm trying to get omniauth-saml configured, but I'm not entirely sure what I need to put in app_id and app_secret for this configuration.
I'm using this gem: https://github.com/PracticallyGreen/omniauth-saml
If I leave those fields blank, of course I get:
Received wrong number of arguments. [nil, nil]
The documentation within the gitlab.yml file links to more documentation about gitlab and omniauth, but that document no longer exists (redirects to old README).
Any assistance would be appreciated, thanks!
https://github.com/gitlabhq/gitlab-public-wiki/wiki/Working-Custom-Omniauth-Provider-Configurations#working-cas-configuration
The working CAS configuration shows you how you skip using the standard configuration and just pass the options directly to the provider using devise.rb. That's how I would configure omniauth-saml as well.
I was able to get SAML working with Gitlab 6.2.4, but it is not the most elegant solution. I am using Okta as the IdP, but I believe the configuration is sufficiently generic and could be applied to any SAML IdP.
Added omniauth-saml to the Gemfile and ran bundle
bundle install --without development test postgres --path vendor/bundle --no-deployment
Created GITLAB/config/initializers/omniauth.rb
Devise.setup do |config|
config.omniauth :saml,
idp_cert_fingerprint: "your IdP certificate fingerprint",
idp_sso_target_url: "your IdP SAML end point"
end
Modified GITLAB/app/controllers/omniauth_callbacks_controller.rb (added this following the definition for ldap)
def saml
handle_omniauth
end
I had to manually add the callback for SAML as I was getting the same error as the original poster when I tried to properly define SAML as a provider in gitlab.yml. This is the only way I could get Gitlab to start and authenticate via SAML. This feels very hacky, so there is probably a more elegant way to implement this; however, I could not find an example anywhere.
https://github.com/gitlabhq/gitlab-public-wiki/wiki/Custom-omniauth-provider-configurations#working-saml-configuration
I managed to get it to work, so I documented the procedure on the GitLab wiki.
EDIT: It seems like SAML is now supported officially. No Single Logout yet, though… This seems to be an omniauth limitation.
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.
I am trying to build a rails 3 back-end for a mobile application. However, I am new to creating rails 3 apps.
Users will need to have a session on the server, but I have no support for normal cookies, so I would need to send a session_id along with every request.
What kind of authentication system should I use in rails 3, is there a gem?
I have read that in rails 2 it was possible to set the session_id from the URL, but that this function is stripped from rails 3 due to security concerns. Is this even true? If there is a way to do this, I am very interested, despite the possible security holes.
Usually I'd use HTTP Digest authentication to solve this problem. Most of the Rails authentication plugins (such as Authlogic, probably Devise) will support HTTP Basic or Digest authentication though a plugin. In this way, you don't have to worry about expired cookies and the like.
You can also pass an api_key parameter instead of a session id.
In many cases I've used an api key as the HTTP Basic username. This gives clean URLs and session-less authentication.
The security problem you're probably referring to is Cross-Site Request Forgery. It is indeed a real problem. Its why you hide actions with side effects (create, update, destroy) behind forms with a CSRF token. Otherwise a malicious link can perform unintended actions to a site that you're already authenticated to without needing to know your credentials.
As long as your API key isn't easily discoverable by anyone in an automated fashion, the risk should be minimal.
Update
A small update: Devise no longer has authentication_token as its implementation was deemed too insecure. A good alternative is Brian Auton's suggestion.
The summary of his method is that he generates an authentication_key AND authentication_secret in a separate model. You then authenticate by sending both your key and secret, if a match is found you are temporarily signed in as a user.
In your application controller this looks like so:
class ApplicationController < ActionController::Base
before_filter :authenticate_from_token
protected
def authenticate_from_token
if current_token.try :authenticatable
sign_in token.authenticatable, store: false
end
end
def current_token
AuthenticationToken.find_authenticated({
secret: (params[:secret] || request.headers[:secret]),
secret_id: (params[:secret_id] || request.headers[:secret_id]),
})
end
end
The authenticatable of the token in this case is a User model, or any other thing that has been made authenticatable (the tokens are polymorphic). As you can see it can easily be made to work with Devise.
I like this method a lot and have implemented it in a recent API. Do read up on it on his website.
Old answer
Outdated answer, kept for reference to older versions of Devise: Devise has a 'authentication_token' column which I can use for authenticating a user. I could have a login API method which I will send a username + password too, then get the token back and store that locally to sign all my other calls with. It basically is a cookie system, but one that is directly supported by Devise.
On top of this I could re-generate the token on either every call or on every 'session'.