as I am building a Login for a Website I would like to store a auto generated password in MySQL in a safe way, thus encrypt it in some way. But I am not sure how to combine the auto generation with encrypting the password.
I looked at a lot of questions but none really helped me or answered my question considering that it should be autogenerated. Also I would like to solve it in an elegant way without hardcoding and stuff if possible. I would be really happy if someone could help me as I am a beginner, thanks in advance!
Question:
How do I auto generate a secure encrypted passwords, what datatype should I use in Java (currently String) and then to what database type is it mapped?
How do I make sure I can decrypt the password of the database to check if it matches when someone logs in?
User Entity:
@Entity
public class User {
@Id
@GeneratedValue
private Integer user_id;
@Column(unique = true)
private String username;
private String password;
@Enumerated(EnumType.STRING)
private Role role;
//non-Owning (address) side of the OneToOne relationship
@OneToOne(mappedBy = "user")
private RetailStore retailStore;
/**
* Constructor
*/
protected User() {
}
/**
* Constructor
* @param username
* @param role
*/
public User(String username, String password, Role role) {
super();
this.username = username;
this.password = password;
this.role = role;
}
User Repository:
@Repository
@Transactional
//necessary to be in an transaction to change something in database,
//instead of doing this for every method itself it is declared by
//the annotation @Transactional
public interface UserRepository extends JpaRepository<User, Long>{
}
Solved it and for me it works perfect and looks beautiful.
Unfortunetly there is no real short answer for it, personally I spent a lot of time on the internet and then kinda just build it up by myself but maybe it helps someone:
A lot of code for JWT for example you just have to copy. But I will show my UserDetailsService which is more a individual thing, for managing users, and also a part of the configuration which tells spring how to handle authorities and authorization including JWT and all that.
Configuration
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AuthConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Value("${jwt.get.token.uri}")
private String authenticationPath;
/**
* Configure AuthenticationManager so that it knows from where to load user for
* matching credentials. Use BCryptPasswordEncoder.
*
* @param auth which creates authentication manager
* @throws Exception if authentication manager has problems
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* Configure who has access to which URLs. Organize authorities and their needed
* Authorization.
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// no need of CSRF
http.csrf().disable()
// authenticate particular requests
.authorizeRequests().antMatchers("/adm/*").hasAuthority("ADMIN")
.antMatchers("/store/{username}/*").hasAuthority("STORE").and()
// make sure we use stateless session; session won't be used to
// store user's state.
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Add a filter to validate the tokens with every request
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
/**
* Configure which URLs can be ignored by spring web security. Thus there is no
* authentication.
*/
@Override
public void configure(WebSecurity webSecurity) throws Exception {
// no authentification needed for specific URLs (login request,...)
webSecurity.ignoring().antMatchers(HttpMethod.POST, authenticationPath)
.antMatchers(HttpMethod.OPTIONS, "/**");
}
}
UserDetailsServcie
@Service
public class JwtUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userrepo;
@Autowired
private RetailStoreRepository storerepo;
@Autowired
private PasswordEncoder bcryptEncoder;
// Aggregated root
public List<User> findAllUser() {
return userrepo.findAll();
}
// Single Item
/**
* Add new user (ADMIN or STORE).
*
* @param account information about new user
* @return new user
*/
public AccountDto addUser(AccountDto account) {
String username = account.getUser().getUsername();
// encode password (hashing)
String code = bcryptEncoder.encode(account.getUser().getPassword()).toString();
Role role = account.getUser().getRole();
// create new user
User user = new User(username, code, role);
// add new user to database
userrepo.save(user);
// check authorization and add store if needed
if (account.getUser().getRole().equals(Role.STORE) && account.getStore() != null) {
storerepo.save(account.getStore());
}
return account;
}
/**
* Delete user.
*
* @param userId id of user who is deleted
*/
public void deleteUser(Long userId) {
// check if user exists
if (userrepo.existsById(userId)) {
userrepo.deleteById(userId);
// also delete corresponding retail store if it is no admin
User user = userrepo.findById(userId).get();
if (user.getRole().equals(Role.STORE)) {
RetailStore trashStore = storerepo.findByUser_userId(userId);
storerepo.delete(trashStore);
}
} else {
throw new UserNotFoundException(userId);
}
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userrepo.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found with username: " + username);
}
return new JwtUserDetailsDto(user.getUserId(), user.getUsername(), user.getPassword(),
user.getRole().toString());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With