忽略静态请求
1、
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//指令请求
.authorizeRequests()
//满足以下路径的无条件允许访问
.antMatchers("/css/**", "/js/**", "/fonts/**").permitAll()
//全部请求 需要认证
.anyRequest().authenticated();
}
2、
@Override
public void configure(WebSecurity web) throws Exception {
web
//忽略以下路径身份校验
.ignoring().antMatchers("/css/**")
.and()
.ignoring().antMatchers("/js/**")
.and()
.ignoring().antMatchers("/fonts/**");
}
二者区别
顾名思义,WebSecurity主要是配置跟web资源相关的,比如css、js、images等等,但是这个还不是本质的区别,关键的区别如下:
- ingore是完全绕过了spring security的所有filter,相当于不走spring security,web ignore比较适合配置前端相关的静态资源,它是完全绕过spring security的所有filter的。
- permitall没有绕过spring security,其中包含了登录的以及匿名的,permitAll,会给没有登录的用户适配一个AnonymousAuthenticationToken,设置到SecurityContextHolder,方便后面的filter可以统一处理authentication。
所以如果想要忽略静态请求,建议使用第二种方法。不过我们公司之前项目使用的就是第一种方法。
自定义登陆页面
使用thymeleaf,所以还需要写Controller和login.html
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//所有请求都需要验证
.anyRequest().authenticated()
.and()
//permitAll 给没登录的 用户可以访问这个地址的权限
.formLogin().loginPage("/login.html")
.loginProcessingUrl("/login")
.failureUrl("/login.html?error")
.defaultSuccessUrl("/").permitAll()
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
e.printStackTrace();
}
})
.and()
.csrf().csrfTokenRepository(new HttpSessionCsrfTokenRepository())
;
}
MainController
@Controller
public class MainController {
@GetMapping("/login.html")
public String login() {
return "login";
}
@GetMapping("/ok")
public String ok() {
return "ok";
}
}
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form name="f" action="/login" method="post">
用户名 <input name="username" type="text">
<br>
密码 <input name="password" type="password">
<br>
<input th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
<input type="submit" value="登录">
</form>
</body>
</html>
密码加密
PasswordEncoder 接口
对应的三个使用到的方法
/**
* Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or
* greater hash combined with an 8-byte or greater randomly generated salt.
* 对原始密码进行编码。通常,好的编码算法应用 SHA-1 或更大的哈希值与 8 字节或更大的随机生成的盐值相结合。
* 用来加密
*/
String encode(CharSequence rawPassword);
/**
* Verify the encoded password obtained from storage matches the submitted raw
* password after it too is encoded. Returns true if the passwords match, false if
* they do not. The stored password itself is never decoded.
* 验证从存储中获取的编码密码是否与提交的原始密码匹配后也被编码。如果密码匹配,则返回 true,否则返回 false。存储的密码本身永远不会被解码
* @param rawPassword the raw password to encode and match 要编码和匹配的原始密码
* @param encodedPassword the encoded password from storage to compare with 存储中的编码密码
* @return true if the raw password, after encoding, matches the encoded password from
* storage 匹配结果
* 校验密码
*/
boolean matches(CharSequence rawPassword, String encodedPassword);
/**
* Returns true if the encoded password should be encoded again for better security,
* else false. The default implementation always returns false.
* 如果为了更好的安全性应该再次对编码的密码进行编码,则返回 true,否则返回 false。默认实现始终返回 false。
* @param encodedPassword the encoded password to check 用于检查的编码密码
* @return true if the encoded password should be encoded again for better security,
* else false. 如果编码密码应再次编码以提高安全性,否则为 false。
* 是否需要再次加密
*/
default boolean upgradeEncoding(String encodedPassword) {
return false;
}