我一直在关注指南,但我无法让Spring Security
工作。
它看起来像是在验证但不是授权或反之,或者没有重定向到登录成功页面。也许这是一个愚蠢的错误,但我看不到它。
我的春季安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private Environment env;
@Autowired
private UserSecurityService userSecurityService;
private static final String[] PUBLIC_MATCHERS = {
"/webjars/**",
"/css/**",
"/js/**",
"/images/**",
"/",
"/about/**",
"/contact/**",
"/error/**/*",
"/h2-console/**"
};
@Override
protected void configure(HttpSecurity http) throws Exception {
List<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
// Required by h2 console to work
if(activeProfiles.contains("dev")) {
http.csrf().disable();
http.headers().frameOptions().disable();
}
http
.authorizeRequests()
.antMatchers(PUBLIC_MATCHERS).permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").defaultSuccessUrl("/payload")
.failureUrl("/login?error").permitAll()
.and()
.logout().permitAll();
}
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSecurityService);
}
}
application-dev.properties
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=sa
spring.datasource.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect
日志:
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - 以前经过身份验证:org.springframework.security.authentication.AnonymousAuthenticationToken@2dafa81d:Principal:anonymousUser;证书:[保护];认证:真实;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90:RemoteIpAddress:0:0:0:0:0:0:0:1; SessionId:0D60174BBA25377F65443D95DB72F713;授权机构:ROLE_ANONYMOUS
DEBUG o.s.s.access.vote.AffirmativeBased - Voter:org.springframework.security.web.access.expression.WebExpressionVoter@7a27baf6,返回:1
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - 授权成功
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager没有更改身份验证对象
DEBUG o.s.security.web.FilterChainProxy - /js/scripts.js到达了额外的过滤器链的末尾;继续原始链
DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext为空或内容为匿名 - 上下文不会存储在HttpSession中。
DEBUG o.s.s.w.a.ExceptionTranslationFilter - 正常处理链
DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder现已清除,请求处理完成
DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext为空或内容为匿名 - 上下文不会存储在HttpSession中。
DEBUG o.s.s.w.a.ExceptionTranslationFilter - 正常处理链
DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder现已清除,请求处理完成
答案 0 :(得分:4)
在身份验证期间,应用程序会抛出以下错误:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
抛出此异常,因为提供的(纯文本)密码缺少密码编码器{id}
- 前缀。 Spring Security 5现在使用以下格式存储密码(以前版本的spring security不是这种情况):
{id}encodedPassword
这意味着对于纯文本密码,{noop}
id告诉spring使用NoOpPasswordEncoder
(基本上将密码作为纯文本处理)来匹配密码。
但是,非常不鼓励存储纯文本密码(尽管它可能对自动化测试很有用)。
强烈建议您使用BCryptPasswordEncoder
,Pbkdf2PasswordEncoder
或SCryptPasswordEncoder
。
<强> BCryptPasswordEncoder 强>
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
class Config {
@Bean
public PasswordEncoder passwordEncoder() {
// Create an encoder with strength 31
// values from 4 .. 31 are valid; the higher the value, the more work has to be done to calculate the hash
return new BCryptPasswordEncoder(12);
}
}
安全配置
@Configuration
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
PasswordEncoder passwordEncoder;
...
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSecurityService)
.passwordEncoder(passwordEncoder);
}
}
编码密码
@Service
class UserService implements UserDetailsService {
private UserRepository userRepository;
private PasswordEncoder passwordEncoder;
UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
User createUser(String username, String password) {
// encrypt the plain-text password
String encodedPassword = passwordEncoder.encode(password);
User user = new User(username, encodedPassword));
//...
return userRepository.save(user);
}
}
要支持多个编码器,可能需要查看DelegatingPasswordEncoder
和PasswordEncoderFactories
。
有关详细信息,请查看https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-format