访问权限
访问权限可以配置URL匹配用户角色或权限
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin")
.antMatchers("/user/**").hasRole("user")
对应HiController
@RestController
public class HiController {
@GetMapping("/hi")
public String hi() {
return "hi";
}
@GetMapping("/admin/hi")
public String adminHi() {
return "adminHi";
}
@GetMapping("/user/hi")
public String userHi() {
return "userHi";
}
}
匹配顺序
security像shiro一样,权限匹配有顺序,比如不能把.anyRequest().authenticated()写在其他规则前面
角色匹配
配置类
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
securedEnabled = true
方法验证
@GetMapping("/hi")
@Secured({"ROLE_admin","ROLE_user"})
public String hi() {
return "hi";
}
@GetMapping("/admin/hi")
@Secured("ROLE_admin")
public String adminHi() {
return "adminHi";
}
@GetMapping("/user/hi")
@Secured("ROLE_user")
public String userHi() {
return "userHi";
}
开启简单验证,之验证单一角色是否持有
prePostEnabled = true
支持更复杂的角色匹配,比如必须同时包含两个角色
需包含user角色
@PreAuthorize("hasRole('ROLE_user')")
需包含user或admin角色
@PreAuthorize("hasAnyRole('ROLE_admin','ROLE_user')")
同时需包含user和admin角色
@PreAuthorize("hasRole('ROLE_admin') AND hasRole('ROLE_user')")
根据方法返回值判断是否有权限
@PostAuthorize("returnObject==1")
图形验证码
目的:防机器暴力登陆
Kaptcha
依赖
<!-- https://mvnrepository.com/artifact/com.github.penggle/kaptcha -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
添加一个前置Filter
http.addFilterBefore(new CodeFilter(), UsernamePasswordAuthenticationFilter.class);
CodeFilter
public class CodeFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)servletRequest;
HttpServletResponse resp = (HttpServletResponse)servletResponse;
String uri = req.getServletPath();
if(uri.equals("/login") && req.getMethod().equalsIgnoreCase("post")) {
String sessionCode = req.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY).toString();
String formCode = req.getParameter("code").trim();
if(StringUtils.isEmpty(formCode)) {
throw new RuntimeException("验证码不能为空");
}
if(sessionCode.equalsIgnoreCase(formCode)) {
System.out.println("验证通过");
}else {
System.out.println(req.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY));
throw new AuthenticationServiceException("验证不通过");
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
Kaconfig 验证码配置
@Configuration
public class Kaconfig {
@Bean
public DefaultKaptcha getDefaultKaptcha(){
DefaultKaptcha captchaProducer = new DefaultKaptcha();
Properties properties = new Properties();
properties.setProperty("kaptcha.border", "yes");
properties.setProperty("kaptcha.border.color", "105,179,90");
properties.setProperty("kaptcha.textproducer.font.color", "blue");
properties.setProperty("kaptcha.image.width", "310");
properties.setProperty("kaptcha.image.height", "240");
properties.setProperty("kaptcha.textproducer.font.size", "30");
properties.setProperty("kaptcha.session.key", "code");
properties.setProperty("kaptcha.textproducer.char.length", "4");
// properties.setProperty("kaptcha.textproducer.char.string", "678");
properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.ShadowGimpy");
properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
Config config = new Config(properties);
captchaProducer.setConfig(config);
return captchaProducer;
}
}
生成验证码方法
@Resource
private Producer captchaProducer;
@GetMapping("/kaptcha")
public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
String capText = captchaProducer.createText();
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
BufferedImage bi = captchaProducer.createImage(capText);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
out.close();
}
}
忽略请求验证码接口的身份验证
http.authorizeRequests()
.antMatchers("/kaptcha").permitAll()
.anyRequest().authenticated()