how to authenticate user in spring security with password encryption - spring-mvc

i m using spring security in my application.in my database .the password is in encrypted form.so in login when i m sending the password,that password should be converted to the encrypted form then i should be able to compare the password which i m sending and the password which is present in the database.if it matches,successful login should occur.
this is my spring-security.xml
<authentication-manager">
<authentication-provider >
<password-encoder ref="encoder"/>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select email,password from user where email=?"
/>
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
and here is my user table which contains email,password,contactno,address.
any help how can i check the encrypted password value for the password which user entering and how to check whether it matechs or not?

You can write your own PasswordEncoder to transfer you user to spring secure.
#Component("PasswordEncoder")
public class PasswordEncoderimpl implements PasswordEncoder{
#Override
public String encodePassword(String rawPass, Object salt) {
//it is the algorithm the transfer password to encrypted password
}
#Override
public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
//encPass is the password in your database
//rawPass is the password user entering
//then you can write it like
return encPass.euqals(encodePassword(rawPass));
}
}
Then your spring-security.xml will be:
<authentication-manager>
<authentication-provider>
<password-encoder ref="PasswordEncoder">
</password-encoder>
</authentication-provider>
</authentication-manager>

Related

Plain password in .net core SignInManager Identity

I have user table with plain passwords. I need connect the table into .net core web's AspNetUsers table.How to hash my user table's plain passwords like AspNetUsers's PasswordHash.
How can login with SignInManger plain-text password?
I recently did something like this. Our legacy system had its own password hashing method. I needed to covert everything over to asp.net users.
First thing I did was add two new columns to the Application user. These contain my legacy user password and that hash that was used to create it.
public string LegacyPasswordHash { get; set; }
public string LegacyPasswordSalt { get; set; }
Then i ran my sql script that copied all of the users in including their legacy password hash and salt.
Then i created a custom SignInManager.
public class ApplicationSignInManager : SignInManager<ApplicationUser> {}
In the password check method I test if its a legacy password user and if it is i covert the password that they just sent me over to a asp.net users password and delete their legacy password. Tip: is to remember to set the user security token on the user table as well this can not be null. You will have major issues with resting password if it is. As there is a bug in the token validation 2022
This is the section of the code i use for testing and resetting the password.
if (_password.EncodePassword(_user.LegacyPasswordSalt) == _user.LegacyPasswordHash)
{
_logger.LogInformation(LoggingEvents.LegacyUserCommand, "Legacy User {_user.Id} migrating password.", _user.Id);
await _userManager.AddPasswordAsync(_user, _password);
_user.SecurityStamp = Guid.NewGuid().ToString();
_user.LegacyPasswordHash = null;
_user.LegacyPasswordSalt = null;
await _userManager.UpdateAsync(_user);
return await new CheckTwoFactorCommand(_logger, _userManager, _user).Execute();
}
if (_shouldLockout)
{
_user.SecurityStamp = Guid.NewGuid().ToString();
await _userManager.UpdateAsync(_user);
_logger.LogInformation(LoggingEvents.LegacyUserCommand, "Login failed for Legacy user {_user.Id} invalid password. (LockoutEnabled)", _user.Id);
await _userManager.AccessFailedAsync(_user);
if (await _userManager.IsLockedOutAsync(_user))
return SignInResult.LockedOut;
}
_logger.LogInformation(LoggingEvents.LegacyUserCommand, "Login failed for Legacy user {_user.Id} invalid password", _user.Id);
return SignInResult.Failed;

Why is Aspnet Identity's PasswordHasher not tied to the User?

When I hash a password using Aspnet Identity's PasswordHasher, the password is not linked to the TUser whose password is set. So technically I can copy that password hash and set it for a different user and that same password hash will work.
The method signature takes TUser user as a parameter however it is not used in the hash/salt implementation.
Is this an oversight or is there some other reason TUser user is declared in the method signatures but not used?
Line 94:
public virtual string HashPassword(TUser user, string password)
and
Line 172:
public virtual PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword)
Here is source code.

Spring Security SAML Extension and #PreAuthorize

My requirements are to use SAML based SSO. Retrieve the user groups from SAML assertions and secure the rest api endpoints. I am using Spring security SAML extension and Spring MVC. The steps I have taken are.
Configure the application for SP using Spring SAML extension. [Done]
Retrieve assertions and assign roles [Done]
Create rest endpoint. [Done]
Secure rest endpoint and services based on roles. [Not working]
I have implemented SAMLUserDetailsService which returns a UserDetails object with authorities. 'loadUserBySAML' below.
#Override
public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException {
final String userId = credential.getNameID().getValue();
final String emailAddress = credential.getAttributeAsString("EmailAddress");
final String firstName = credential.getAttributeAsString("FirstName");
final String lastName = credential.getAttributeAsString("LastName");
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_STUDENT"));
return new User(userId, emailAddress, firstName, lastName, authorities);
}
I have added <!-- Enable security annotations on methods -->
<security:global-method-security pre-post-annotations="enabled" />to the securityContext.xml.
On the RestController and on the services I am using #PreAuthorize but this annotation seems to have no effect at all.
#PreAuthorize("hasRole('ROLE_PROGRAMLEAD')")
#RequestMapping(method = RequestMethod.GET)
public String hello() {
return "Hello.";}
Could someone please help me understand why the PreAuthorize is not firing? Am I missing some configuration?
I was facing the same issue. I wanted to perform API authorisation with SAML authentication. For it to work, you need to use the hasAuthority param with the annotation instead of the hasRole param.
The following worked for me:
#PreAuthorize(value="hasAuthority('Admin')")
The <security:global-method-security pre-post-annotations="enabled" /> needs to go in the servlet xml of the rest controller and not the security context xml.
Reference:
http://docs.spring.io/spring-security/site/faq/faq.html#faq-method-security-in-web-context

Spring-MVC : Encryption/Decryption with user password

I am working on a Spring-MVC application which uses Hibernate as the
ORM and PostgreSQL as the database, in which I am looking for
on-the-fly encryption decryption solution, but only for 2 columns in
the database, the rest all can stay non-encrypted. I have a Person
entity, which has a password and I am encrypting the password with
BCrypt and saving them in database. I understand once the password is BCrypt encrypted I cannot decrypt it. I am planning to put an intermediate page temporarily where I would request the password once again and save it in some format which I can use for on the fly encryption-decryption.
If possible, I would like to use this password to encrypt/decrypt
those 2 columns once the user logs in and does action on those 2
columns.
As I am using Spring-Security too, I am injecting the encoder bean so
Spring-Security can login the user. Here is how I am saving the
password and my security-application-context. As I am just starting
with this problem, not that much progress to paste here :
Person model :
#Entity
#Table(name="person")
public class Person implements UserDetails{
#Id
#Column(name="id")
#GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "person_seq_gen")
#SequenceGenerator(name = "person_seq_gen",sequenceName = "person_seq")
private int id;
#Valid
#Email
#Pattern(regexp = emailRegexp)
#Column(name = "username")
private String username;
#Valid
#NotEmpty(message = "Password may not be empty")
#Column(name = "password")
private String password;
// getters and setters ommitted }
PersonServiceImpl :
#Override
#Transactional
public boolean addPerson(Person p) {
Person existingUser = personDAO.findPersonByUsername(p.getUsername());
if(existingUser == null) {
this.personDAO.addPerson(p);
p.setAccountstatus(false);
p.setOnetimeemail(false);
p.setUsername(p.getUsername().toLowerCase());
// as you can see I am encrypting the password and saving in DB, I don't know how to access the plain password at this point to use in some algorithm for on-the-fly encryption/decryption
p.setPassword(BCrypt.hashpw(p.getPassword(), BCrypt.gensalt(11)));
p.setUsername(p.getUsername().toLowerCase());
this.personDAO.addPerson(p);
sendAccountActivationEmail(p.getUsername(), p.getFirstName());
return true;
} else {
return false;
}
}
Security-application-context.xml
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11" />
</beans:bean>
<beans:bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="LoginServiceImpl"/>
<beans:property name="passwordEncoder" ref="encoder"/>
</beans:bean>
Any pointers, help would be nice. If there is anything unclear, kindly let me know. Thanks a lot.

Integration between our Asp.NET MVC form authentication and Office 365

I have the following:-
1) Intranet Asp.net MVC-4 web application, which currently authenticate the users using form authentication with our on-premises active directory through ldap string.
2) So users enter their username and password >> the application will authenticate their user names and passwords from AD and login them accordingly.
3) Now our organization will turn off the on-pressies AD, and we will migrate to office 365.
so i am not sure if i can modify my asp.net mvc-4 intranet (access from our internal network only) to authenticate the entered username and password from office 365 instead of using ldap string?
currently the login is been performed as follow:-
the login post action method:-
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Login(LoginModel model, string returnUrl)
{
MembershipProvider domainProvider;
domainProvider = Membership.Providers["Domain1ADMembershipProvider"];
if (ModelState.IsValid)
{
// Validate the user with the membership system.
if (domainProvider.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
List<String> domains2 = new List<String>();
domains2.Add("AD-*****GROUP");
ViewBag.Domains = domains2;
return View(model);
}
}
List<String> domains = new List<String>();
domains.Add("AD-*********GROUP");
ViewBag.Domains = domains;
return View(model);
}
web.config contain the ldap to the on-premises AD and username/password settings:-
<membership>
<providers>
<add name="Domain1ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="Domain1ConnectionString" connectionUsername="********8" connectionPassword="********" attributeMapUsername="sAMAccountName" />
</providers>
</membership>
<connectionStrings>
<add name="Domain1ConnectionString" connectionString="LDAP://ad-*****roup.intra/OU=TDM,DC=ad-***group,DC=intra" />
i do not have any idea from where to start and if i can achive what i am looking for,, and if this is supported or not?

Resources