Я могу войти только с учетными данными, указанными в .inMemoryAuthentication()
. Когда кто-то регистрируется, данные пользователя (электронная почта, пароль) будут успешно сохранены в базе данных PostgreSQL, но когда пользователь хочет войти в систему с указанными данными, он говорит «Неверное имя пользователя и пароль». Чего мне не хватает?
SecurityConf. java
@EnableGlobalMethodSecurity(securedEnabled=true)
@Configuration
public class SecurityConf extends WebSecurityConfigurerAdapter {
String[] staticResources = {
"/css/**",
"/images/**"
};
@Bean
public UserDetailsService userDetailsService() {
return super.userDetailsService();
}
private UserDetailsService userService;
@Autowired
public void setUserService(UserDetailsService userService) {
this.userService = userService;
}
@Autowired
public void configureAuth(AuthenticationManagerBuilder auth) {
try {
auth
.inMemoryAuthentication()
.withUser("user")
.password("{noop}user") //Add password storage format, for plain text, add {noop} avoiding the error: java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
.roles("ADMIN")
.and()
.withUser("admin")
.password("{noop}admin")
.roles("ADMIN");
} catch (Exception e) {
System.out.println(" " + e.getMessage());
}
}
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers(staticResources);
}
@Override
public void configure(HttpSecurity httpSec) {
try {
httpSec.authorizeRequests()
.antMatchers(staticResources).permitAll()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/registration").permitAll()
.antMatchers("/reg").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll();
} catch (Exception ex) {
System.out.println(" " + ex.getMessage());
}
}
ApiController. java
public class ApiController {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private EmailService emailService;
private UserService userService;
@Autowired
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@RequestMapping("/")
public String home() {
return "index";
}
@RequestMapping("/registration")
public String registration(Model model) {
model.addAttribute("user", new User());
return "registration";
}
//@RequestMapping(value="/reg", method=RequestMethod.POST)
@PostMapping("/reg")
public String registration(@ModelAttribute User user) {
System.out.println("NEW USER");
emailService.sendMessage(user.getEmail(), user.getFullName());
log.info("New User");
// log.debug(user.getPassword());
// log.debug(user.getEmail());
userService.registerUser(user);
return "auth/login";
}
@RequestMapping(path = "/activation/{code}", method = RequestMethod.GET)
public String activation(@PathVariable("code") String code, HttpServletResponse response) {
String result = userService.userActivation(code);
return "auth/login?activationsuccess";
}
}
Пользователь. java
@Entity
@Table(name="users")
public class User {
@Id @GeneratedValue
private Long id;
@Column(unique=true, nullable=false)
private String email;
@Column(nullable=false)
private String password;
private String fullName;
boolean enabled;
String activation;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(
name = "users_roles",
joinColumns = {@JoinColumn(name="user_id")},
inverseJoinColumns = {@JoinColumn(name="role_id")}
)
private Set<Role> roles = new HashSet<Role>();
public User() {
}
public Long getId() {
return id;
}
public String getFullName() {
return fullName;
}
public Set<Role> getRoles() {
return roles;
}
public void setId(Long id) {
this.id = id;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public boolean getEnabled() {
return enabled;
}
public String getActivation() {
return activation;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public void setActivation(String activation) {
this.activation = activation;
}
@Override
public String toString() {
return "User [id=" + id + ", email=" + email + ", password=" + password + ", fullName=" + fullName + "]";
}
public void addRoles(String roleName) {
if (this.roles == null || this.roles.isEmpty()) {
this.roles = new HashSet<>();
this.roles.add(new Role(roleName));
}
}
}
Роль. java
@Entity
@Table(name="roles")
public class Role {
@Id
@GeneratedValue
private Long id;
private String role;
@ManyToMany(mappedBy="roles")
private Set<User> users = new HashSet<User>();
private Role() {
}
public Role(String role) {
this.role = role;
}
public Long getId() {
return id;
}
public String getRole() {
return role;
}
public Set<User> getUsers() {
return users;
}
public void setId(Long id) {
this.id = id;
}
public void setRole(String role) {
this.role = role;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@Override
public String toString() {
return "Role [id=" + id + ", role=" + role + ", users=" + users + "]";
}
}
RoleRepository
public interface RoleRepository extends CrudRepository<Role, Long> {
Role findByRole(String role);
}
UserRepository. java
public interface UserRepository extends CrudRepository<User, Long> {
User findByEmail(String email);
User findByActivation(String code);
}
UserDetailsImpl. java
public class UserDetailsImpl implements UserDetails {
private static final long serialVersionUID = -5461896565515368402L;
private User user;
public UserDetailsImpl(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
Set<Role> roles = user.getRoles();
for(Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getRole()));
}
return authorities;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getEmail();
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return user.getEnabled();
}
}
UserService. java
public interface UserService {
public String registerUser(User user);
public User findByEmail(String email);
public String userActivation(String code);
}
UserServiceImpl. java
@Service
public class UserServiceImpl implements UserService, UserDetailsService {
private UserRepository userRepository;
private RoleRepository roleRepository;
private final String USER_ROLE = "USER";
@Autowired
public void UserRepository(UserRepository userRepository, RoleRepository roleRepository) {
this.userRepository = userRepository;
this.roleRepository = roleRepository;
}
@Override
public User findByEmail(String email) {
return userRepository.findByEmail(email);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = findByEmail(username);
if(user == null) {
throw new UsernameNotFoundException(username);
}
return new UserDetailsImpl(user);
}
@Override
public String registerUser(User userToRegister) {
User userCheck = userRepository.findByEmail(userToRegister.getEmail());
if (userCheck != null) {
return "alreadyExist";
}
Role userRole = roleRepository.findByRole(USER_ROLE);
if (userRole != null) {
userToRegister.getRoles().add(userRole);
} else {
userToRegister.addRoles(USER_ROLE);
}
userToRegister.setActivation(generateKey());
userToRegister.setEnabled(true);
userRepository.save(userToRegister);
return "ok";
}
public String generateKey() {
String key = "";
Random random = new Random();
char[] word = new char[16];
for(int i = 0; i < word.length; i++) {
word[i] = (char) ('a' + random.nextInt(26));
}
String toReturn = new String(word);
return new String(word);
}
@Override
public String userActivation(String code) {
User user = userRepository.findByActivation(code);
if (user == null) {
return "no result";
}
user.setEnabled(true);
user.setActivation("");
userRepository.save(user);
return "ok";
}
}
login. html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap.min.css">
<!--We are choosing these two to let the browser to load faster-->
<link rel="stylesheet" type="text/css" href="css/logincss.css">
<!--this is the last one so that we can override previous boostrap styles if we want-->
<head>
<body class="signin-body">
<div class="container signin-container">
<div class="row">
<div class="col"></div>
<div class="col-sm-12 col-md-8">
<div class="card signin-card">
<div class="card-block">
<!-- <img src="/imgages/logindetails.png" class="img-fluid signin-img"> -->
<img src="images/logindetails.png" width="50%" height="50%" class="img-fluid signin-img">
<form name="login" th:action="@{/login}" method="post" class="signin-form">
<div class="form-group">
<h2 class="form-signin-heading">Please sign in</h2>
<div th:if="${param.error}" class="alert alert-danger">Wrong username and password</div>
<div th:if="${param.logout}" class="alert alert-success">You successfully logged out</div>
<label for="username" class="sr-only">Username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required="true">
<label for="password" class="sr-only">Password</label>
<div class="form-group">
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required="true">
</div>
</div>
<button class="btn btn-lg btn-primary btn-block signin-btn" type="submit">Login</button>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck1">
<label class="custom-control-label" for="customCheck1">Remember me <a href="#"> Need help?</a></label>
</div>
</form>
</div>
</div>
<a class= "new-account" href="/registration">Create New Account</a>
</div>
<div class="col"></div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="css/bootstrap-4.3.1-dist/js/bootstrap.min.js"></script>
</body>
</html>