Я новичок в безопасности весны и пытаюсь реализовать весеннюю безопасность в своем веб-приложении весенней загрузки. Я следую за блоком SpringSecurity для обеспечения безопасности через user
и role
с использованием базы данных. Код также найден в github. Этот блог говоритРепозиторий возвращает значение null в Spring Security
Примечание
Мы будем передавать боб UserRepository к UserDetailsService, потому что этот компонент будет загружен перед загрузкой в хранилище, так что мы могли бы получить useeRepository боба утратившего в out SSUserDetailsService.
N.B: У меня есть изменение SSUserDetailsService
к WebUserDetailsService
У меня есть
Entity:
User
иRole
создает 3 таблицы (user
,role
&user_roles
)
/*------------------------------------- User entity -------------------------------------*/
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String username;
private String password;
private boolean enabled;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
// getters, setters & toString
}
/*------------------------------------- Role entity -------------------------------------*/
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String role;
@ManyToMany(mappedBy = "role", fetch = FetchType.LAZY)
private Set<User> users;
//getters, setters & toString
}
Repository:
UserRepository
для извлечения данных из базы данных
/*----------------------------------- User repository ----------------------------------*/
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
настройки безопасности:
WebSecurityConfigurer
&WebUserDetailsService
/*------------------------------- WebSecurityConfigurer -------------------------------*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private UserRepository userRepository;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceBean());
}
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return new WebUserDetailsService(userRepository);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/img/**", "/js/**").permitAll()
.antMatchers("/", "/home").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.antMatchers("/user/**").hasAuthority("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username").passwordParameter("password").permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
;
}
}
/*------------------------------- WebUserDetailsService -------------------------------*/
@Transactional
public class WebUserDetailsService implements UserDetailsService {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WebUserDetailsService.class);
private UserRepository userRepository;
public WebUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
User user = userRepository.findByUsername(username);
if (user == null) {
LOGGER.debug("user not found with the provided username");
return null;
}
LOGGER.debug(" user from username " + user.toString());
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthorities(user));
}
catch (Exception e){
throw new UsernameNotFoundException("User not found");
}
}
private Set<GrantedAuthority> getAuthorities(User user){
Set<GrantedAuthority> authorities = new HashSet<>();
for(Role role : user.getRoles()) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getRole());
authorities.add(grantedAuthority);
}
LOGGER.debug("user authorities are " + authorities.toString());
return authorities;
}
}
Связь с базами данных:
application.properties
#defauls
#security.user.name=user
#security.user.password=password
#security.user.role=ROLE_USER, ROLE_ADMIN
#configurations
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
#initializations
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
#credentials
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/spring_boot_security
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.schema=classpath:/data/schema.sql
#query-configurations
spring.datasource.maxActive=10
spring.datasource.max-idle=4
spring.datasource.min-idle=2
spring.datasource.test-while-idle=true
spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1
spring.datasource.time-between-eviction-runs-millis=60000
spring.datasource.min-evictable-idle-time-millis=300000
#server-configurations
hazelcast.server.address=127.0.0.1
Проблемы:
userRepository.findByUsername()
возвращает null для действительных учетных данных вWebUserDetailsService
>loadUserByUsername()
. Я заметил, что если я поставлю следующий код (комментируя строкуUser user = userRepository.findByUsername(username);
) в качестве цели тестирования, то увидел, что для проверки не существует ошибки. То естьuserRepository
не работает. Что делать, чтобы вытащить пользователя по имени пользователя, используяuserRepository
?@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { try { //User user = userRepository.findByUsername(username); Role role = new Role(); role.setId(1L); role.setRole("USER"); Set<Role> roles = new HashSet<>(); roles.add(role); User user = new User(); user.setEnabled(true); user.setId(1L); user.setPassword("12345"); user.setUsername("johir1"); user.setRoles(roles); if (user == null) { LOGGER.debug("user not found with the provided username"); return null; } LOGGER.debug(" user from username " + user.toString()); return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthorities(user)); } catch (Exception e){ throw new UsernameNotFoundException("User not found"); } }
Я называю
userRepository.findByUsername()
в моем отображении"/"
URL, чтобы проверить, является ли хранилище работать или нет. Я понял, что есть ошибка дляtoString()
, заявленная вUser
.Нет ошибки, если я прокомментировал строку", roles=" + roles +
. Как загрузить роль с соответствующим пользователем? Посмотрите на ToString() в пользовательском@Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", enabled=" + enabled + ", roles=" + roles + '}'; }
Есть ли проблема в отображении многих-ко-многим? – Johir
getRoles ничего не возвращает, пока пользователь пользователь найден пользователемRepository.findByUsername(). Зачем? – Johir