I'm making a little app for work to handle shared to-do lists, I'm almost done but I'd like to add some very simple authentication. I followed the doc to add hashdb to the scaffolded site (https://github.com/yesodweb/yesod-cookbook/blob/master/cookbook/Using-HashDB-In-a-Scaffolded-Site.md), and it compiles fine, but when I log in with correct username / password (added by hand in the database) I get this :
10/Dec/2016:13:36:02 +0100 [Debug#SQL] SELECT `name`,`password` FROM `user` WHERE `name`=?; [PersistText "Ulrar"]
10/Dec/2016:13:36:08 +0100 [Error#yesod] Exception from Warp: stack overflow #(cstod_GjWCdZJB9K0EGPCbjz5gnP:Application Application.hs:133:15)
Line 133 of Application.hs is this one : $(qLocation >>= liftLoc)
That's from the default code.
As you can see my "User" table is pretty simple, I have a primary key on the name and a password, and that's it. The name must be unique, of course.
I'll be adding the few user by hand in the database, that'll be more than enough for us.
I tried the query by hand, it returns what you'd expect, and trying to log in with the wrong username / password does "work", it redirects to the login form with an error. Only using the correct username / password couple will give that Exception, and it does seem to load for a while before throwing it after clicking on the button.
I end up on http://localhost:3000/auth/page/hashdb/login with just "Something went wrong" written.
I assume I must have missed something, I'm using the yesod-mysql scaffolded site and I have this in the YesodAuth instance :
authPlugins app = [authHashDB (Just . UniqueUser)]
I removed the getAuthId definition since I had no idea what to put there, the definition from the doc doesn't compile because getAuthIdHashDB isn't exported anymore apparently. Is this my problem ?
Thanks !
Yep, my problem was indeed removing getAuthId !
Solved it by adding this instead :
authenticate creds = runDB $ do
x <- getBy $ UniqueUser $ credsIdent creds
case x of
Just (Entity uid _) -> return $ Authenticated uid
Nothing -> return $ UserError InvalidUsernamePass
Related
I'm building a web application with Snap that needs to authenticate both staff and customers. So far I'm using the auth snaplet provided by snaplet-postgresql-simple to authenticate the two types of users from the same table in the database.
The initialization code therefore looks something like this:
s <- nestSnaplet "sess" sess $ initCookieSessionManager sessionKeyfile "sess" Nothing (Just sessionTimeout)
db <- nestSnaplet "pg" pg Pg.pgsInit
a <- nestSnaplet "auth" auth $ initPostgresAuth sess db
I'm considering separating the two types of users into two tables for these reasons:
the information associated with each type of user (i.e. the columns) is actually different (e.g. I don't need to know first and last names of staff)
I want to allow the staff to be authenticate to the backend without being logged into the frontend (I'd need separate cookies then, I guess)
I think security could benefit if the two types of users are in separate tables
I'm considering using two instances of the snaplets for postgresql-simple and sessions.
The initialization code would then look something like this:
s1 <- nestSnaplet "sess1" sess1 $ initCookieSessionManager sessionKeyfile "sess1" Nothing (Just sessionTimeout)
s2 <- nestSnaplet "sess2" sess2 $ initCookieSessionManager sessionKeyfile "sess2" Nothing (Just sessionTimeout)
db <- nestSnaplet "pg" pg Pg.pgsInit
a1 <- nestSnaplet "auth1" auth1 $ initPostgresAuth sess1 db
a2 <- nestSnaplet "auth2" auth2 $ initPostgresAuth sess2 db
Is that possible to use several instances of a snaplet like that?
Or does my problem have a better solution?
I wouldn't use two instances. I'd use a single instance where a user represents whatever is common to both, and then you add a user type column and put the extra information in other tables linked with a foreign key.
I am trying to use this code that was provided to me for a penetration test exercise. According to the author that created this you enter this code and it will get the users hashes from a machine we are trying to compromise. When I enter the code it does not return anything from the database. All I get is a ":" on the screen. Something does not seem right with this code can you please help. My job is not to fix the code but to just query the information from the database to get the hashes for the users. I am just going based up on the instructions of the LAMPSecurity CTF8 pdf that was provided to me.
<?php
$res = db_query('select name,pass from users');
while ($rec = db_fetch_object($res)) {
print $rec→name . ":" . $rec→pass . "<br/>";
}
?>
Somewhere during the parsing of your PDF, the characters -> have been turned into the UTF8 equivalent of →.
However, → is not a valid operator in PHP.
Replace → with -> and try again.
Also, your code doesn't connect to the DB anywhere, so that may cause further issues.
i am using Devise and devise_security_extension.
https://github.com/plataformatec/devise
https://github.com/phatworx/devise_security_extension
I tried to figure out how i could validate a provided password WITHOUT updating a User record.
Validation (password was not used before, password is complex enough ....)
For example:
john = User.find(1)
john.password = "Testing"
john.password_confirmation = "Testing"
result = john.save
Result would return true or false. With result.errors i would get the related error messages (Thats exactly what i want but without really change this user password).
My Problem is that this would really change the password of this user (object). That would cause problems with old_passwords.
Is there any way to do a dry run ? (result = john.save_dry_run)
FYI:
I already tried to change the User password and change it back after i got the result. But this is really ugly and also make much trouble with devise old_passwords table.
I hope my question is clear enough. If you need any further information please let me know !
You should call valid? rather than save in your example. This will only run the model validations without actually saving any data to the database:
john = User.find(1)
john.password = "Testing"
john.password_confirmation = "Testing"
result = john.valid?
You can find more information in the Rails documentation.
For a school project we have to create an evaluation website that requires a login.
For the database connection I chose LINQ, because it's new and is supposed to be easier/better in use.
I managed to create a login check with the following:
public static Boolean Controle(int id, string wachtwoord)
{
DataClassesDataContext context = new DataClassesDataContext();
var loginGebruiker =
from p in dc.Gebruikers
where p.GebruikerID == id
where p.GebruikerWachtwoord == wachtwoord
select p;
return true;
}
Now I'm trying to create a "forgot password" option, where you enter your id and the password gets returned (later it would be emailed to you, don't know how I would do this either, suggestions?)
I tried with the following code:
public static string Forgot(int id)
{
var context = new DataClassesDataContext();
var wachtwoordLogin = (
from p in dc.Gebruikers
where p.GebruikerID == id
select p.GebruikerWachtwoord);
return wachtwoordLogin.ToString();
}
Code behind the button on the page:
lbl1.Text = Class1.Forgot(Convert.ToInt32(txt1.Text));
Now when I enter the an id of the first user (1), lbl1 becomes this:
SELECT [t0].[GebruikerWachtwoord] FROM
[dbo].[Gebruiker] AS [t0] WHERE
[t0].[GebruikerID] = #p0
I don't know how to solve this and I have been looking everywhere, I hope somebody can help me.
Thanks,
Thomas
LINQ uses delayed execution, so your 'wachtwoordLogin' is really just "how to get your data." Its not until you apply an operator that LINQ will actually attempt to retrieve your data.
Your first statement:
var loginGebruiker = (
from p in dc.Gebruikers
where p.GebruikerID == id
where p.GebruikerWachtwoord == wachtwoord
select p).FirstOrDefault()
if (loginGeruiker != null) {
//Valid login
} else {
// invalid
}
FirstOrDefault means, take the first item in the list, or return none.
In you other case you need the same thing:
user = wachtwoordLogin.FirstOrDefault();
Further reading: MSDN 101 LINQ Samples
For your question about emailing a forgotten password, have you ever thought about implementing the golden questions algorithm instead? Its simplified, and does the same thing.
Basically, at the time of registering just get them to answer some questions, and if they can verify them, allow them to reset the password.
you enter your id and the password gets returned
What, then, is the point of having a password if anybody who knows a username can see it? I know this isn't what you're asking, but for someone getting started in programming I feel a duty to point this out. What you're creating here is essentially a completely broken login model. Nobody should ever use a system like this.
You should never ever display a password. Not on the screen, not in an email, never.
Passwords, if they even need to be stored at all (CodingHorror has had a couple of good posts on this lately, advocating things like OpenID), should be stored in hashed form and essentially unable to be retrieved. When a user logs in, similarly hash the password they provide (immediately upon reaching the application code, before transporting it anywhere else in the system) and compare that to the stored hashed version.
If the user asks for his password, you don't have it. You can't give it to him. This is for his protection. Instead of providing the user with his password, if it's forgotten then you provide the user with a means to reset his password (sending an email to the address on file with a temporarily available URL, a set of "security questions" to verify his identity, etc.) so that he can enter a new one to overwrite the old one. But you shouldn't be able to "show" the user his password because even you as the administrator of the system shouldn't be able to see it in any usable form.
wachwoordLogin will be an IQueryable so you can get this by using FirstOrDefault() which will return null if not found:
(from p in dc.Gebruikers
where p.GebruikerID == id
select p.GebruikerWachtwoord).FirstOrDefault();
I am developing a web app by using Grails and using Grails LDAP as my Authentication mechanism. However, i always get following error:
{Error 500: Cannot pass null or empty values to constructor
Servlet: default
URI: /ldap-app/j_spring_security_check
Exception Message: Cannot pass null or empty values to constructor
Caused by: Cannot pass null or empty values to constructor
Class: GrailsAuthenticationProcessingFilter }
My SecurityConfig.groovy file is :
security {
// see DefaultSecurityConfig.groovy for all settable/overridable properties
active = true
loginUserDomainClass = "User"
authorityDomainClass = "Role"
requestMapClass = "Requestmap"
useLdap = true
ldapRetrieveDatabaseRoles = false
ldapRetrieveGroupRoles = false
ldapServer = 'ldap://worf-mi.dapc.kao.au:389'
ldapManagerDn = 'CN=sa-ldap-its,OU=Unix Servers for Kerberos,OU=Information Technology Services,OU=Special Accounts,DC=nexus,DC=dpac,DC=cn'
ldapManagerPassword = 'Asdf1234'
ldapSearchBase = 'OU=People,DC=nexus,DC=dpac,DC=cn'
ldapSearchFilter = '(&(cn={0})(objectClass=user))'
}
I had the same problem, read the solution above and did something else. Instead of modifying GrailsUserImpl.java I simply switched the password in the user table from NULL to '' (empty String). Since the password is not used for LDAP, the emptry string will be transmitted (instead of the NULL value) which has the same effect as
super(username, "", enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities);
but it doesnt affect the source code. This worked for my project, hope it helped too.
Steven
i had the same problem and found a solution.
This error occurs, because the Acegi-Plugin tries to store the Ldap-users password into the User-object.
In fact depending on settings of the LDAP-Server it is not allowed to retrieve the password, so an empty value is given to the constructor, as the errormessage tells.
The fix i found is not really nice, but helps to get the plugin up and running. You have to change one field in the following file:
~/.grails//projects//plugins/acegi-0.5.3/src/java/org/codehaus/groovy/grails/plugins/springsecurity/GrailsUserImpl.java
or on windows:
C:/Users//.grails//projects//plugins/acegi-0.5.3/src/java/org/codehaus/groovy/grails/plugins/springsecurity/GrailsUserImpl.java
Constructor GrailsUserImpl() has the following body:
super(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities);
which has to be changed to:
super(username, "", enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities);
Unfortunately this has to be done for every developer-client and every new project.. But it gets the ldap auth to run finally.
As i read they are working on this bug and try to fix it with version 0.6 of the plugin.
Hope i could help.
br,
Tim
Just add "ldapUsePassword = false " in your securityconfig file:
Setting ldapUsePassword to false is
important too. What we’re telling the
Acegi plugin is not to extract the
users password from Active Directory.
If you don’t set this to false, you’ll
get a lovely exception which isn’t
particularly useful,
java.lang.IllegalArgumentException:
Cannot pass null or empty values to
constructor. What this is trying to
tell you is that the users password is
null, which is correct since the
default setting for the Acegi plugin
is to try to extract the users
password from Active Directory, and we
haven’t told Acegi what attribute
Active Directory stores the password
in. By setting ldapUsePassword to
false, the plugin provides a bogus
password for the user details, and
we’re able to proceed without incident