WebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserService userService;
public WebSecurityConfig(UserService userService) {
this.userService = userService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/","/registration")
.permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService)
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
}
UserService.java
@Service
public class UserService implements UserDetailsService {
private final UserRepo userRepo;
public UserService(UserRepo userRepo) {
this.userRepo = userRepo;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepo.findByUsername(username);
}
}
UserRepo.java
public interface UserRepo extends JpaRepository<User, Long> {
User findByUsername(String username);
}
User.java
@Data
@Entity
@Table(name = "usr")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String password;
private boolean active;
@ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
@CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
private Set<Role> roles;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return isActive();
}
public boolean isActive() {
return active;
}
}
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div th:insert="parts/_header :: header"></div>
<div th:insert="parts/_menu :: menu"></div>
<body>
<div style="margin-left:20px" class="ui mini breadcrumb">
<a class="section" href="#">Главная</a>
<i class="right angle icon divider"></i>
<div class="active section">Авторизация или регистрация</div>
</div>
<div class="ui raised very padded text container segment">
<h2>Авторизация</h2>
<div th:if="${param.error}">
Invalid username and password.
</div>
<div th:if="${param.logout}">
You have been logged out.
</div>
<form class="ui form" th:action="@{/login}" method="post">
<div class="field">
<label>Имя пользователя</label>
<input type="text" name="username" placeholder="Имя пользователя"/>
</div>
<div class="field">
<label>Пароль</label>
<input type="password" name="password" placeholder="Пароль"/>
</div>
<button class="ui button" type="submit" style="margin-top: 20px">Войти</button>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
</form>
<div class="ui divider"></div>
<div>
Нет аккаунта? <a href="/registration"> Зарегистрируйтесь</a>
</div>
</div>
<div th:insert="parts/_footer :: footer"></div>
</body>
</html>
Я думаю проблема связана с тем, что вы не внедрили зависимости и определить AuthenticationProvider(в нашем случае DaoAuthenticationProvider), настроить или отключить csrf, указать название полей username, password в loginPage которые будем вытаскивать и создавать UsernamePasswordAuthenticationToken:
UserService.java:
@Component(value = "customUserDetailsService")
public class UserService implements UserDetailsService {
private final UserRepo userRepo;
@Autowired
public UserService(UserRepo userRepo) {
this.userRepo = userRepo;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepo.findByUsername(username);
}
}
WebSecurityConfig.java:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserService userService;
@Autowired
public WebSecurityConfig(@Qualifier("customUserDetailsService") UserService userService) {
this.userService = userService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/","/registration")
.permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
public DaoAuthenticationProvider daoAuthProvider() {
DaoAuthenticationProvider daoAuthProvider = new DaoAuthenticationProvider();
daoAuthProvider.setPasswordEncoder(NoOpPasswordEncoder.getInstance());
daoAuthProvider.setUserDetailsService(userService);
return daoAuthProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthProvider());
}
}
внедряем зависимость UserService userService благодаря аннотации @Autowired над конструктором WebSecurityConfig.
с помощью @Qualifier("customUserDetailsService") указываем бин с определенным названием("customUserDetailsService"), который имеет соответствующую реализацию.
определяем AuthenticationProvider с помощью которого будет осуществлять аутентификация, в данной ситуации DaoAuthenticationProvider.Рассмотрим подробнее: когда ваш запрос проходит по FilterChain и дойдет до UsernamePasswordAuthenticationFilter, то так как в вашем запросе будут содержаться username и password, он их вытащит и на их основе создаст UsernamePasswordAuthenticationToken(username, password,) после данный объект аутентификации передастся AuthenticationManager, который будет искать подходящий AuthenticationProvider поддерживающий аутентификацию объекта UsernamePasswordAuthenticationToken и наткнется как раз на наш DaoAuhenticationProvider, который в свою очередь использует UserDetailsService - лезет в бд и ищет нашего юзера, на основе данных юзера создаст UserDetails() содержащий username, password,GrantedAuthority. В итоге UserDetailsService возвращает UserDetails и сравнивает данные UserDetails с данными UsernamePasswordAuthenticationToken, если они совпадают то все ок, иначе ошибка.
login.html
Предлагаю отключить csrf если вы не знаете как его настраивть:
удалить или закоментить строчку <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
отключить csrf: http.csrf().disable()
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
я - новичок, так что не судите строгоЯ разрабатываю приложение на Java под Android
У меня есть задача, нужно сделать фильтры для стримов с разными типами объектов
Пытаюсь сделать тест, имитация работы 2х пользователей над док-мИспользую библиотеки RestAssured и JerseyTest
Подскажите, пожалуйста, как правильно написать взаимодействие между двумя контроллерами