I am following this tutorial:
http://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/8.0/authentication-and-security/user-authentication/security-check/
There they check the credentials, that they have received from the user's input in the app:
#Override
protected boolean validateCredentials(Map<String, Object> credentials) {
if(credentials!=null && credentials.containsKey("username") && credentials.containsKey("password")){
String username = credentials.get("username").toString();
String password = credentials.get("password").toString();
if(!username.isEmpty() && !password.isEmpty() && username.equals(password)) {
return true;
}
}
return false;
}
As you can see, the authentication returns true when usernameand password are equal. I have a mysqldatabse, where I have saved the registered users. So I want to check the entered credentials against the data in my database. How do I have to change the adapter and the method so I can do this?
To achieve this , you will need to write the code to connect to your DB, invoke the SQL query to check the data in DB.
Within your security check's validateCredentials method, you should write the code to connect to your DB that holds the registered user information. Check for the user details against the DB and based on the outcome , return true of false.
A sample Java SQL adapter is listed here. You can use it for your reference.
Related
I am trying to log in providing an email and password. I have tried hashing and not hashing the password myself. I run dd(Auth::attempt(Input::except('submit'))); and it returns false. Yes the array is correct. Yes that is what's in the database. I followed the attempt() to Illuminate/Auth/Guard.php attempt() The code for that function is below.
public function attempt(array $credentials = array(), $remember = false, $login = true)
{
$this->fireAttemptEvent($credentials, $remember, $login);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials))
{
if ($login) $this->login($user, $remember);
return true;
}
return false;
}
This function has not be modified at all. dd($user); returns the correct information, an instance of User with the attributes pulled from the db. and dd($credentials); returns an array of the post information, an email and password.
dd($this->hasValidCredentials($user, $credentials)); returns boolean false.
I have no idea why. Let me know if more info is required. Thank you!
My password table had a character limit of 20. I'm an idiot. It works now.
I am trying to find the best procedure for adding password requirements with Parse.com. It appears the easiest way would be to use a cloud function to execute right before user data is saved. My only caveat is that I want to validate user passwords only when the password is different from what is stored in the db or if the user does not exist in the db.
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
...
}
Couple of questions:
Does request.object.existed() work in beforeSave functions as it does with afterSave?
Can I access the user's password (using Parse.Cloud.useMasterKey()) via the request.object in the beforeSave functions? Or do I need to query the user's object inside the function.
In the log the input to the beforeSave function appears to have original and updated keys similar to the json below. However, I was not able to access the original and update json through the request.object. How would I access this data? It would be nice if the only check needed to be performed to verify whether a user's password as changed if a comparison between request.object.original.password !== request.object.updated.password
Sample cloudcode log output:
Input: {"original":{"email":"blah",
"firstname" : "blah",
"emailVerified":true,
"username":"blah",
"createdAt":"2014-04-28T23:05:47.452Z",
"updatedAt":"2014-0716T01:55:52.907Z",
"objectId":"blah",
"sessionToken":"blah"},
"update":{"firstname":"blah2"}}
Try something like this:
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
if (request.object.isNew()) {
// new object..
response.success();
} else {
if (request.object.dirtyKeys().indexOf("password") > -1) {
// Attempted to change the password.
response.error('No.');
}
}
});
Auth :: attempt works perfect, but when you pass the second parameter "true" apparently does not care or does not recover with viaRemember
viaRemember fails to work, check this
controller User
`$`userdata = array(
'email' => trim(Input::get('username')),
'password' => trim(Input::get('password'))
);
if(Auth::attempt(`$`userdata, true)){
return Redirect::to('/dashboard');
}
view 'dashboard', always show 777
#if (Auth::viaRemember())
{{666}}
#else
{{777}}
#endif
I have hit the same obstacle, so looking into the code one can see that viaRemember is not meant to be used as a function to check if the user was logged into the system in one of all the ways a user can be logged in.
'viaRemember' is meant to check if a user was logged into the system specifically via the `viaRemember' cookie.
From what I gather, authentication of user is remembered in two ways:
a via remember cookie.
The cookie value is compared to the via remember field in the users table.
a session cookie.
The cookie value is used in the server to get the session from the
session store. On the session object from the store there is data attached. One of the
data items is the user id connected to the session. The first time
the session was created, the system attached the user id to the data
of the season.
In Illuminate\Auth\Guard class:
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method because that would tremendously slow an app.
if ( ! is_null($this->user))
{
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveByID($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller))
{
$user = $this->getUserByRecaller($recaller);
}
return $this->user = $user;
}
The getUserByRecaller function is called only if the session cookie authentication did not work.
The viaRemember flag is only set in the getUserByRecaller function. The viaRemember method is only a simple getter method.
public function viaRemember()
{
return $this->viaRemember;
}
So in the end, we can use Auth::check() that does make all the checks including the viaRemember check. It calls the user() function in the Guard class.
It seems also the viaRemember is only an indicator. You need to do a type of Auth::check() the will get the process of authentication started and so the user() function will be called.
It seems that your project is on Laravel 4.0 but viaRemember() is added in Laravel 4.1! So that's expected.
in config\session.php file change the 'expire_on_close' = false to true and once you close restart your browser, it must be ok.
I'm trying to create a user provider so that I can authenticate through an Active directory server.
The problem is that, unlike most other LDAP servers, Active directory doesn't allow to retrieve some user's password attribute, even encrypted.
Here is my User class :
class LdapUser implements UserInterface
{
private $username;
private $first_name;
private $last_name;
private $password;
private $salt;
private $roles;
public function __construct($username, $first_name, $last_name, $password, $salt, array $roles) {
$this->username = $username;
$this->first_name = $first_name;
$this->last_name = $last_name;
$this->password = $password;
$this->salt = $salt;
$this->roles = $roles;
}
...
}
And here is my loadUserByUsername method (In my UserProvider class) :
public function loadUserByUsername($username)
{
$server = "my_ldap_server";
$root_dn = "my_root_dn";
$root_pw = "my_root_pw";
$ds = ldap_connect($server);
if ($ds) {
ldap_bind($ds, $root_dn, $root_pw);
$search = ldap_search($ds, "my_branch", "(sAMAccountName=".$username.")", array("sn", "givenName"));
$info = ldap_get_entries($ds, $sr);
if($info['count'] > 0) {
$user = $info[0];
return new LdapUser($username, $user['givenName'][0], $user['sn'][0], '???PASSWORD???', '???SALT???', array('ROLE_USER'));
} else {
throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
}
ldap_close($ds);
} else {
echo "Connexion au serveur LDAP impossible";
}
}
As you can see, I can't pass the password to my LdapUser class, since it's not accessible through Active Directory.
However, I think it's still possible to authenticate te user, by doing a ldap_bind($username, $password) with the password entered by the user in the login form. The problem is I can't figure out how to access this password in my LdapUserProvider class.
I tried $_POST['password'] but I got an undefined index error...
Any help would be welcome :)
There are a few LDAP Authentication bundles ready to use.
As pointed out below, you can try FR3D/LdapBundle, but it needs FOSUserBundle to work. You can also try IMAG (BorisMorel/LdapBundle), if you don't want to (or don't need to) use FOSUserBundle. BorisMorel uses php-ldap to work, it requires no additional bundle nor any zend components.
Even if you don't want to use them, I'd suggest you check out BorisMorel's implementation for more information. The code's quite simple to understand as it's very straightforward.
Your code sets the authentication state of a connection by transmitting a bind request. Does this code attempt to search for an entry, retrieve the password from that entry and then bind as that distinguished name? If so, even if you could retrieve the password, a properly configured directory server will not allow the transmission of a pre-encoded password. Passwords should always be transmitted in clear text over a secure connection (TLS or SSL) so the server can perform password quality and history validation. Therefore, your code must know the clear-text password beforehand. Alternatively, a LDAP-compliant server might allow the use of a proxied authentication for certain entries.
see also
LDAP: Mastering Search Filters
LDAP: Search best practices
LDAP: Programming practices
Try FR3dLdapBundle
The 2.0.x branch has support with Active Directory if you install Zend\Ldap component from Zend Framework 2
I have an ODATA services with a single schema. These point to a development database, and is served through a WCF Data Service which is then used by clients running Excel/Powerpivot to fetch their own data for reports and such.
The service is secured at runtime through pretty much the same basic authentication explained here: http://msdn.microsoft.com/en-us/data/gg192997
Now how this needs to work in the live environment is sit on the server and connect to different databases based on the username/password supplied. the Users will be typing in 'username#clientID' and 'password'. 'username#clientID' is then split() and username/password is checked against the SQL database. But the database server URL to check against will be determined by ClientID.
Also, once it is authorized the WCF data service needs to return data from the Database corresponding to the ClientID.
The approach I tried was to modify the connection string in the web.config file, but this doesn't work because it says the file is read-only. I'm not even sure if this would have worked at all. What I need to do is get the EDMX/WCF Data service to return the data from the correct database. Here's what I tried to do:
private static bool TryAuthenticate(string user, string password, out IPrincipal principal)
{
Configuration myWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
myWebConfig.AppSettings.Settings["test"].Value = "Hello";
myWebConfig.Save();
string newConnStr = myWebConfig.ConnectionStrings.ConnectionStrings["IntelCorpEntities"].ToString();
newConnStr.ToString().Replace("SERGEIX01", "SERVERX01");
myWebConfig.ConnectionStrings.ConnectionStrings["IntelCorpEntities"].ConnectionString = newConnStr;
myWebConfig.Save();
if (user.ToLower().Equals("admin") && password.Equals("password"))
{
principal = new GenericPrincipal(new GenericIdentity(user), new string[] { "Users" });
return true;
}
else
{
principal = null;
return false;
}
}
In your DataService derived class override the CreateDataSource method and in it figure out the right connect string, create a new instance of the EF object context for the connection string and return it.
The WCF DS Service will not use the default constructor on the EF object context then, it's completely up to you construct the instance with the right connection string.
In your svc.cs file add following :
protected override NorthWindEntity CreateDataSource()
{
System.Data.EntityClient.EntityConnection connection = new System.Data.EntityClient.EntityConnection();
connection.ConnectionString = "";
NorthWindEntity ctx = new NorthWindEntity(connection);
return ctx;
}