问题:There is no PasswordEncoder mapped for the id "null"
原因: 升级为Security5.0以上密码支持多种加密方式,强制用户的密码存储要加密。但是如果想恢复以前模式,注入这一个bean就可以实现了(暂时图方便的做法,还是要将密码加密之后再存储)。
//不加密
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
下面是拦截器WebSecurityConfigurerAdapter,发现Spring Security底层其实也是一堆的拦截器做这些安全控制,感觉自己做写拦截器还方便一点,实现自定义的功能,用这个框架就要遵循他的一些配置,有时候遇到问题还一时半会解决不了。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
@Configuration
@EnableWebSecurity
@ComponentScan("org.yulang.rent.services")
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailService userDetailService;
@Autowired
private MyAuthenticationFailureHandler failureHandler;
@Autowired
private MyAuthenticationSuccessHandler successHandler;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
/* httpSecurity.authorizeRequests().antMatchers("/").permitAll().and()
.authorizeRequests().antMatchers("/console/**").permitAll();
httpSecurity.csrf().disable();
httpSecurity.headers().frameOptions().disable();*/
httpSecurity.authorizeRequests()
.antMatchers("/webjars/**", "/images/**").permitAll()
.antMatchers("/products").hasAnyRole("MEMBER", "SUPER_ADMIN")//个人首页只允许拥有MENBER,SUPER_ADMIN角色的用户访问
.antMatchers("/login").permitAll()//这里程序默认路径就是登陆页面,允许所有人进行登陆
.antMatchers("/msg").permitAll()
.antMatchers("/register").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/login")
//.loginProcessingUrl("/login")//登陆提交的处理url
// .failureForwardUrl("/msg")//登陆失败进行转发,这里回到登陆页面,参数error可以告知登陆状态
//.defaultSuccessUrl("/products")//登陆成功的url,这里去到个人首页
.failureHandler(failureHandler).successHandler(successHandler)
.and()
.logout().logoutUrl("/logout").permitAll().logoutSuccessUrl("/msg?info=2")//按顺序,第一个是登出的url,security会拦截这个url进行处理,所以登出不需要我们实现,第二个是登出url,logout告知登陆状态
/* .and().rememberMe()
.tokenValiditySeconds(604800)//记住我功能,cookies有限期是一周
.rememberMeParameter("remember-me")//登陆时是否激活记住我功能的参数名字,在登陆页面有展示
.rememberMeCookieName("workspace");//cookies的名字,登陆后可以通过浏览器查看cookies名字*/
.and().csrf().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService);//配置自定义userDetailService
}
}
注:
使用thymeleaf写前台的时候,获取Spring Security当前登陆的用户名这样子可以获取,但是在未登录过程中,使用该代码会报异常。具体还有其他权限等信息,可以去session中获取或者debug查看。
${session.SPRING_SECURITY_CONTEXT.authentication.principal.username}