Sinatra HTTP Basic Authentication get user and keep to use inside routes - sinatra

I'm building an small API in sinatra. I need to authenticate the routes, and I have that already working doing the following (as read from the documentation)
use Rack::Auth::Basic,"Protected Area" do |username, password|
user = User.validate username, password
end
But I'll have multiple users, so I'm doing something like this:
class Protected < Sinatra::Base
use Rack::Auth::Basic,"Protected Area" do |username, password|
User.validate username, password
end
get '/users' do
content_type :json
#I want to return the user who was authenticated
end
end
The class method Validate returns the user if the user does exists in the database or returns false if it doesn't exists. But what I have no idea how to do is how to access that user from inside a route, for example get '/users' do
Thanks!

If HTTP Authentication is enforced, the user's name is available in the request object, for instance:
use Rack::Auth::Basic,"Protected Area" do |username, password|
User.validate username, password
end
get '/' do
user = request.env["REMOTE_USER"]
"Hello, #{user}"
end
Please note that the HTTP authentication scheme can be awkward to use, you might want to consider using sessions instead.

TITLE = "Password protected Area"
# TITLE = "The page is password protected, please provide a password. (any username is ok)" # alternative title
use Rack::Auth::Basic, TITLE do |_, password|
password != File.read("./config/password.txt").strip
end
is he simplest solution in my opinion.
It reads from a text file, that you should add to your gitignore

Related

Flutter + Django OAuth integration

I am using Flutter as front end and Django for back end purpose. I am trying to integrate Google and Facebook OAuth in the app and using some flutter libraires I am able to fetch user details and access token in front end. Now the question is how do I handle users and access tokens for them and verify them through drf. I could totally depend on drf for OAuth and create users using http request in front end using OAuth toolikt for Django but is there a way that I handle incoming auth tokens in front end and verify them in drf so as to register them in backend.
#api_view(http_method_names=['POST'])
#permission_classes([AllowAny])
#psa()
def exchange_token(request, backend):
serializer = SocialSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
# This is the key line of code: with the #psa() decorator above,
# it engages the PSA machinery to perform whatever social authentication
# steps are configured in your SOCIAL_AUTH_PIPELINE. At the end, it either
# hands you a populated User model of whatever type you've configured in
# your project, or None.
user = request.backend.do_auth(serializer.validated_data['access_token'])
if user:
# if using some other token back-end than DRF's built-in TokenAuthentication,
# you'll need to customize this to get an appropriate token object
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
else:
return Response(
{'errors': {'token': 'Invalid token'}},
status=status.HTTP_400_BAD_REQUEST,
)
There’s just a little more that needs to go in your settings (full code), and then you’re all set:
AUTHENTICATION_BACKENDS = (
'social_core.backends.google.GoogleOAuth2',
'social_core.backends.facebook.FacebookOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
for key in ['GOOGLE_OAUTH2_KEY',
'GOOGLE_OAUTH2_SECRET',
'FACEBOOK_KEY',
'FACEBOOK_SECRET']:
# Use exec instead of eval here because we're not just trying to evaluate a dynamic value here;
# we're setting a module attribute whose name varies.
exec("SOCIAL_AUTH_{key} = os.environ.get('{key}')".format(key=key))
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.social_auth.associate_by_email',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
)
Add a mapping to this function in your urls.py, and you’re all set!

Authenticatee FrontendUser via PHP API call from Extbase

First of all im Using TYPO3 Version 8.7.
The current problem i'm facing regards authentication of FrontendUser (fe_user) stored on a given page (in this case pid 168).
Apparently i'm trying to authenticate user with given credentials sent by a mobile application. I'm able to parse the user data and perform an authentication:
// plain-text password
$password = 'XXX';
// salted user password hash
$saltedPassword = 'YYY';
// keeps status if plain-text password matches given salted user password hash
$success = FALSE;
if (\TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::isUsageEnabled('FE')) {
$objSalt = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($saltedPassword);
if (is_object($objSalt)) {
$success = $objSalt->checkPassword($password, $saltedPassword);
}
}
While debugging this code snippet, i recognized the password sent by the user via Request, which gets encrypted with the given Salt algorithm change every time i retry this request. I'm not sure how to get a correct authentication, if the password changes constantly.
The $objSalt object contains the right Hashing Method($pbkdf2-sha256$25000), the password stored in the Database starts with the same prefix, but the actual payload is different.
So What is the exact problem or whats the thing i'm missing in the above code to complete the authentication?
Thanks for your help
BR,
Martin
the password sent by the user via Request, which gets encrypted with the given Salt algorithm change every time i retry this request
Yes, that because the salt is changed every time.
You should retrieve the salting instance with:
$instance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($user['password']);

Rails - How to authorise user with third party api

I'm setting up some authentication in my rails application. Only thing is I want to log in a user based on their credentials with another API.
The application will have to send a POST request with their username and password in the body to the API and if the request is successful then the user authorised.
I'm having trouble trying to do this with devise, I'm just looking for tips you guys have in order to implement this.
Thanks!
Devise allows you to define custom strategies for authentication. You can therefore create a new strategy to handle it. Database Authentication is one of the strategy already defined at Devise. You can check the source here
A rough idea of your strategy could like this.
Create a file at config/initializers/external_authenticatable.rb and define the strategy
require 'devise/strategies/database_authenticatable'
module Devise
module Strategies
class ExternalAuthenticatable < DatabaseAuthenticatable
def authenticate!
resource = password.present? && mapping.to.find_for_database_authentication(authentication_hash)
if validate(resource){ valid_credentials?(resource) }
remember_me(resource)
resource.after_database_authentication
success!(resource)
end
fail(:not_found_in_database) unless resource
end
def valid_credentials?(resource)
request_params = { email: resource.email, password: password }
# Make your post request here and return true false using authentication_hash
end
end
end
end
Now we need to inform devise that we want to use this strategy first before any other defaults. This can be done by editing /config/initializers/devise.rb
config.warden do |manager|
manager.strategies.add(:external, Devise::Strategies::ExternalAuthenticatable)
manager.default_strategies(:scope => :user).unshift :external
end
Restart your Rails application and you are done.

Perl Dancer2 Authentication Password Management

So any one who has used perl dancer knows that to authenticate a user on login you can call authenticate_user
authenticate_user(
params->{username}, params->{password}
);
This is part of the Auth::Extensible plugin.
To me it looks like it encourages the use of storing passwords in plain text! Sure you can hash the password first then make sure the stored password is the same hash but this seems to be more of a work around and i found isn't guaranteed to work. I have only got this to work using sha1 which shouldn't be used. I want to use Bcrypt but the passphrase simply wont match. Possibly odd characters not matching i'm not sure.
The thing is using the dancer Passphrase plugin i can already validate the username and password without even needing to rely on authenticate_user to verify them. But for the dancer framework to consider the user logged in you still have to call authenticate_user which must be passed the password.
I'm completely stuck. I'm curious how other people have managed to use proper password management in dancer2?
Firstly, I'll echo the "you almost certainly don't need to be using authenticate_user()" comments. The plugin can handle all that for you.
However, "it doesn't hash it" is wrong; here's how it works. The
authenticate_user keyword loops through all auth realms configured, and for
each one, asks that provider's authenticate_user() method to see if it accepts
the username and password. The Database provider (and the others) fetch the
record from the DB, and use $self->match_password() (which comes from the
Provider role) to validate it; that code checks if the stored password from
the database starts with {scheme} and if so, uses
Crypt::SaltedHash->validate to validate that the user-supplied password (in
plain text, as it's just come in over the wire) matches the stored, hashed
passsword ($correct in the code below is the stored password):
if ( $correct =~ /^{.+}/ ) {
# Looks like a crypted password starting with the scheme, so try to
# validate it with Crypt::SaltedHash:
return Crypt::SaltedHash->validate( $correct, $given );
}
So, yes, if your stored password in the database is hashed, then it will match
it if the password supplied matches that hash.
For an example of what a stored hashed password should look like, here's
the output of the bundled generate-crypted-password utility:
[davidp#supernova:~]$ generate-crypted-password
Enter plain-text password ?> hunter2
Result: {SSHA}z9llSLkkAXENw8FerEchzRxABeuJ6OPs
See the Crypt::SaltedHash doco for details on which algorhythms are
supported by it, and the format it uses (which "comes from RFC-3112 and
is extended by the use of different digital algorithms").
Do bear in mind that the code behind authenticate_user is exactly what's used
under the hood for you.
For an example of just letting the plugin do the work for you, consider:
get '/secret' => require_login sub {
my $user = logged_in_user();
return "Hi, $user->{username}, let me tell you a secret";
};
... that's it. The require_login means that the plugin will check
if the user is logged in, and if not, redirect them to the login page
to log in. You don't need to call authenticate_user yourself, you
don't need to set any session variables or anything. logged_in_user()
will return a hashref of information about the logged in user (and because
the route code has require_login, there's guaranteed to be one at this
point, so you don't need to check).
If you need to check they have a suitable role, instead of just that they
are logged in, then look at require_role in the documentation instead.
In the documentation for Dancer2::Plugin::Auth::Extensible, the description for authenticate_user() says:
Usually you'll want to let the built-in login handling code deal with authenticating users, but in case you need to do it yourself, this keyword accepts a username and password ...
Which strongly implies to me that you shouldn't be calling this function at all unless you're doing something particularly clever.
I haven't used this module myself, but it seems to me that all the hashing and encryption stuff should be handled by one of the authentication providers and if there's not one that covers the case you use, then you can write one yourself.
Whenever I need to store secure passwords for a Dancer app, I reach for Dancer2::Plugin::Passphrase. I wonder if I should consider writing an Auth::Extensible style authentication provider for it.

How to implement user login in Jersey API

I am implementing RESTful API using javax.ws.rs. The response of the calls that I need to implement requires knowing which user is logged in currently. I tried making a separate call for the user login:
api.myapi.co.uk/authenticate?username=xxxx&password=xxxx
where I basically save the user information is a global variable
and then tried to make another call to retrieve information from the database based on the user that has been saved earlier but I find the value as null during the second call. What am I missing? Is my approach wrong? do you have any suggestions please?
Your code probably looks like this, right?
#Path("/")
public class MyResource{
private String username;
private String password;
#Path("authenticate")
public String authenticate(#QueryParam("username") username, #QueryParam("password") password) {
if(!username.equals("zainab") || !password.equals("letmein"))
return "Incorrect username or password";
this.username=username;
this.password=password;
return "Sucessfully authenticated";
}
#Path("secret")
public String secret() {
if(username == null || password == null)
return "Sorry, not authorized";
return "You are authorized: "+username;
}
}
If so, the problem is that JAX-RS creates a new Resource object for each request. A request to "/secret" then uses a new instance of MyResource, which has username and password as null.
Then, you might think, I'll just make it static! Then, your resource can't handle concurrent requests. What if Person A calls "/authenticate", then "/secret". Then Person B calls "/secret" without authenticating. He can then access "/secret" without authenticating!
Anyways, this violates the idea of RESTful services. The S in RESTful stands for "Stateless". This means that the server should store no state per client, and possibly give the user a token to pass with concurrent requests.
One possibility is to accept the username and password for every request to secret ("/secret?username=zainab&password=letmein"). Or you could implement token-based authentication, where the user calls "/authenticate" to get a token, and they pass that token on all later requests. Here is a link to help with that.
Also, note that username and password is usually not send in the URL as a query param, but instead in the Authorization HTTP header as such Authorization: base64encode("USERNAME:PASSWORD")