spring security 使用总结
自定义security校验
@EnableWebSecurity
@Configurable
public class MyConfig extends WebSecurityConfigurerAdapter {
@Resource
private UserProvider userProvider;
/**
* 自定义验证用户账号和密码
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(userProvider);
}
}
自定义权限类AuthenticationProvider
@Component
public class UserProvider implements AuthenticationProvider {
@Resource
private UserService userService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getPrincipal().toString();
String password = authentication.getCredentials().toString();
UserDetails userDetails = userService.loadUserByUsername(username);
//校验密码是否正确
if (new BCryptPasswordEncoder().matches(password,userDetails.getPassword())) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, userDetails.getPassword(), userDetails.getAuthorities());
return usernamePasswordAuthenticationToken;
}else {
throw new BadCredentialsException("用户账号或密码错误");
}
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
自定义UserDetailsService
@Component
public class UserService implements UserDetailsService {
@Resource
DataSource dataSource;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
UserDetails userDetails = jdbcUserDetailsManager.loadUserByUsername(s);
return userDetails;
}
public boolean saveUser(String username,String password) {
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
jdbcUserDetailsManager.createUser(User.withUsername(username).password(new BCryptPasswordEncoder().encode(password)).roles("admin").build());
return Boolean.TRUE;
}
}
基于内存存储用户
@Bean
public UserDetailsService userDetailsService() {
//基于内存存储用户
//UserDetails
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
// 使用 用户名 找 user对象
// manager.loadUserByUsername(username)
User user = new User("a", new BCryptPasswordEncoder().encode("1"), true, true, true, true, Collections.singletonList(new SimpleGrantedAuthority("xx")));
manager.createUser(user);
manager.createUser(User.withUsername("yiming").password(new BCryptPasswordEncoder().encode("xx")).roles("xxz").build());
return manager;
}
处理静态页面 登录问题
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().mvcMatchers("/static/**");
}
配置登陆页面的url
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//过滤静态页面的
// .antMatchers().permitAll()
.anyRequest().authenticated().and()
//配置登陆页面的url
//http://localhost/login.html
//自定义登陆页面
.formLogin().loginPage("/login.html")
//跳转的url
.loginProcessingUrl("/login")
//登陆失败的页面
.failureUrl("/error.html")
.defaultSuccessUrl("/ok", true).permitAll()
.passwordParameter("password")
.usernameParameter("username")
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
e.printStackTrace();
//不同的异常做不同的处理
if (e instanceof UsernameNotFoundException) {
httpServletRequest.getRequestDispatcher(httpServletRequest.getRequestURI()).forward(httpServletRequest, httpServletResponse);
}
}
}).and().csrf().csrfTokenRepository(new HttpSessionCsrfTokenRepository());
}
开启csrf安全策略 自定义页面需要配置
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Security login</title>
</head>
<body>
<form action="/login" method="post">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
账号:<input name="username" type="text"><br>
密码:<input name="password" type="text"><br>
<input name="submit" type="submit" value="登录">
</form>
</body>
</html>