spring security
在01中实现了默认登录功能,在项目中也可以配置自己的默认登录界面
修改webSecurityConfig
@Configuration
public class webSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception{
http.formLogin()//表单认证
.loginPage("/login.html")
.loginProcessingUrl("/login")
.and()
.authorizeRequests()//授权配置
.antMatchers("/login.html").permitAll()
.anyRequest()//所有请求
.authenticated()//都需要认证
.and()
.csrf().disable();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
方法中的loginpage对应的就是我们自定义的登陆界面
在static下增加login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form class="login-page" action="/login" method="post">
<div class="form">
<h3>账户登录</h3>
<input type="text" placeholder="用户名" name="username" required="required" />
<input type="password" placeholder="密码" name="password" required="required" />
<button type="submit">登录</button>
</div>
</form>
</body>
</html>
.loginProcessingUrl("/login")登录处理的url地址
.antMatchers("/login.html").permitAll()一定要设置登录界面不进行校验,要不然会一直得不到响应
.csrf().disable();取消跨域攻击验证
实现UserDetailsService
/**
* *@ClassName MyUserDetailService
* *@Author yyc
* *@Date 2020/5/20 17:16
**/
@Configuration
public class MyUserDetailService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
MyUser myUser=new MyUser();
myUser.setUserName(username);
myUser.setPassword(this.passwordEncoder.encode("123456"));
System.out.println(myUser.getPassword());
return new User(username,myUser.getPassword(),myUser.isEnabled(),myUser.isAccountNonExpired(),myUser.isCredentialsNonExpired(),myUser.isAccountNonLocked(),
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
通过loadUserByUsername
方法来获取登陆界面上的username
。
通过username去数据库获取到登陆人的信息,这里直接是模拟了,没有去数据库获取。
然后将密码设置为123456。这里必须进行加密处理,要不然会匹配不上密码。
注意类上一定要加上@Configuration,
把这个类加入到容器中。
增加一个测试方法
@RequestMapping("/user")
public MyUser getUser(){
MyUser user=new MyUser();
user.setPassword("2312313");
user.setUserName("zhangsan ");
return user;
}
测试
浏览器输入localhost:8082/user
会弹出自定义的登录界面
输入用户名(任意值),密码123456
登录后就显示访问资源的值了。
使用自定义成功验证
/**
* *@ClassName CustomAuthSuccessHandler
* *@Author yyc
* *@Date 2020/5/21 17:29
* *配置自定义成功处理界面,登录用户名和密码配置成功后,增加处理功能
**/
@Component
public class CustomAuthSuccessHandler implements AuthenticationSuccessHandler {
private RequestCache requestCache= new HttpSessionRequestCache();
private RedirectStrategy redirectStrategy=new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
/*response.setContentType("application/json;charset=utf-8");
ObjectMapper objectMapper=new ObjectMapper();
response.getWriter().write(objectMapper.writeValueAsString(authentication));*/
SavedRequest savedRequest=requestCache.getRequest(request,response);
redirectStrategy.sendRedirect(request,response,"/user");
}
}
使用redirectStrategy.sendRedirect(request,response,"/user");
实现验证通过后访问/user资源
在web配置中配置自定义校验
@Autowired
private CustomAuthSuccessHandler customAuthSuccessHandler;
protected void configure(HttpSecurity http) throws Exception{
http.formLogin()//表单认证
.loginPage("/auth/require")
.loginProcessingUrl("/login")
.successHandler(customAuthSuccessHandler)
.failureHandler(customAuthFailHandler)
.and()
.authorizeRequests()//授权配置
.antMatchers("/login.html","/auth/require").permitAll()
.anyRequest()//所有请求
.authenticated()//都需要认证
.and()
.csrf().disable();
}
测试
总结:
通过实现AuthenticationSuccessHandler
接口的onAuthenticationSuccess
方法来实现认证通过的处理逻辑。
通过实现AuthenticationFailureHandler
接口的onAuthenticationFailure
方法来实现认证失败的处理逻辑。