1.pom加载
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
加载进去后,自动拦截所有路径,需要先登录。默认账号为user,密码后台生成。
2.配置类
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//因为sping5以后不能明文密码所以得加密
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()//缓存中配置
//账号配置,拥有admin权限
.withUser("lee").password("123").roles("admin")
.and()
//账号配置,拥有user权限
.withUser("wang").password("123").roles("user");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//路径拦截,与访问权限
.antMatchers("/admin/**").hasRole("admin")
.antMatchers("/user/**").hasAnyRole("admin","user")
.anyRequest().authenticated()//表示剩余的其他接口,登录之后就能访问
.and()
//路径登录路径
.formLogin()
.loginProcessingUrl("/doLogin")
.permitAll()//和表单登录相关的接口统统都直接通过
.and()
.csrf().disable();//关闭csrf
}
}
3.controller
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "say hello";
}
@GetMapping("/admin/hello")
public String admin(){
return "say admin";
}
@GetMapping("/user/hello")
public String user(){
return "say user";
}
}
Lee 可以访问所有路径。王只可以访问user/hello,和hello。
4.配置类2.0
页面登录成功与登录失败的操作。并注销
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin")
.antMatchers("/user/**").access("hasAnyRole('user','admin')")
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/doLogin")
.loginPage("/login")
.usernameParameter("uname")
.passwordParameter("passwd")
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
Map<String, Object> map = new HashMap<>();
map.put("status", 200);
map.put("msg", authentication.getPrincipal());
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
out.close();
}
})
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
Map<String, Object> map = new HashMap<>();
map.put("status", 401);
if (e instanceof LockedException) {
map.put("msg", "账户被锁定,登录失败!");
} else if (e instanceof BadCredentialsException) {
map.put("msg", "用户名或密码输入错误,登录失败!");
} else if (e instanceof DisabledException) {
map.put("msg", "账户被禁用,登录失败!");
} else if (e instanceof AccountExpiredException) {
map.put("msg", "账户过期,登录失败!");
} else if (e instanceof CredentialsExpiredException) {
map.put("msg", "密码过期,登录失败!");
} else {
map.put("msg", "登录失败!");
}
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
out.close();
}
})
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
Map<String, Object> map = new HashMap<>();
map.put("status", 200);
map.put("msg", "注销登录成功!");
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
out.close();
}
})
.and()
.csrf().disable();
}