我在这里遇到了Spring Security的问题。 我使用Spring Boot构建Web应用程序,并尝试引入Spring Security进行身份验证和授权。 我想实现一个登录页面,但我发现spring security总是返回302响应。 这是与这些问题相关的代码。
@Data
@Entity(name = "tb_user")
public class User implements UserDetails{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String account;
@Column(nullable = false)
private String password;
@ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
private List<Role> roles;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities = new ArrayList<>();
List<Role> roles = this.getRoles();
for(Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
@Override
public String getUsername() {
return account;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@Data
@Entity(name = "tb_role")
public class Role {
@Id
@GeneratedValue
private Long id;
private String name;
}
public interface UserRepository extends JpaRepository<User, Long> {
User findByAccount(String account);
}
public class CustomUserService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findByAccount(s);
if(user == null) {
throw new UsernameNotFoundException("User doesn't exist");
}
return user;
}
}
@Configuration
public class WebSecurity extends WebSecurityConfigurerAdapter {
@Bean
UserDetailsService customUserService() {
return new CustomUserService();
}
@Bean
PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return s.equals(charSequence.toString());
}
};
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/plugins/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.and()
.logout().permitAll();
}
}
<form action="/login" method="post">
<input type="text" name="username"><br/>
<input type="password" name="password"><br/>
<input type="submit" value="Login">
</form>
然而,当我在登录表单中添加百里香的行为时,问题就解决了,一切都变好了。就像这样。
<form th:action="@{/login}" action="/login" method="post">
<input type="text" name="username"><br/>
<input type="password" name="password"><br/>
<input type="submit" value="Login">
</form>
现在我很困惑。 它应该与百里香叶相匹配吗? 但它没有任何意义。 那一定是错的。 我希望有人能给我一个答案。 请。
答案 0 :(得分:0)
如果<input type="hidden" name="_csrf" value="...."/>
<form />
作为属性(并且正确设置了弹簧安全性),Thymeleaf会自动添加th:action
。当你离开th:action
时,csrf丢失,而春天拒绝你的表格。