Spring Boot 安全管理
一、Spring Boot 基本配置
1.添加 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
2.添加测试方法
@RestController public class SecurityController { @RequestMapping("/test") public String securityTest() { return "test"; } }
3.启动项目进行访问
系统产生随机的密码
默认用户名为user ,登录成功后
4.配置用户名和密码
spring.security.user.password=kxg11 spring.security.user.name=kxg spring.security.user.roles=admin//用户角色
5.基于内存的认证
@Configuration public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter { @Bean PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin").password("123").roles("ADMIN","USER") .and() .withUser("san").password("123").roles("USER"); } }
6.HttpSecuity
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**") .hasRole("ADMIN") .antMatchers("/user/**") .access("hasAnyRole('ADMIN','USER')") .antMatchers("/db/**") .access("hasRole('ADMIN') and hasRole('DBA')") .anyRequest() .authenticated() .and() .formLogin() .loginProcessingUrl("/login") .permitAll() .and() .csrf() .disable(); }
控制器中加入
@GetMapping("/admin/hello") public String admin() { return "hello admin"; } @GetMapping("/user/hello") public String user() { return "hello user!"; } @GetMapping("/db/hello") public String dba() { return "hello dba!"; } @GetMapping("/hello") public String hello() { return "hello!"; }
7.登录表单详情配置
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**") .hasRole("ADMIN") .antMatchers("/user/**") .access("hasAnyRole('ADMIN','USER')") .antMatchers("/db/**") .access("hasRole('ADMIN') and hasRole('DBA')") .anyRequest() .authenticated() .and() .formLogin() .loginPage("/login_page") .loginProcessingUrl("/login") .usernameParameter("name") .passwordParameter("password") .successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { Object principal = authentication.getPrincipal(); httpServletResponse.setContentType("application/json;charset=utf-8"); PrintWriter out = httpServletResponse.getWriter(); httpServletResponse.setStatus(200); Map<String,Object> map = new HashMap<>(); map.put("status",200); map.put("msg",principal); ObjectMapper om = new ObjectMapper(); out.write(om.writeValueAsString(map)); out.flush(); out.close(); } }) .failureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { httpServletResponse.setContentType("application/json;charset=utf-8"); PrintWriter out = httpServletResponse.getWriter(); httpServletResponse.setStatus(200); 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","登录失败!"); } ObjectMapper om = new ObjectMapper(); out.write(om.writeValueAsString(map)); out.flush(); out.close(); } }) .permitAll() .and() .csrf() .disable(); }
8 注销登录配置
.and() .logout() .logoutUrl("/logout") .clearAuthentication(true) .invalidateHttpSession(true) .addLogoutHandler(new LogoutHandler() { @Override public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) { } }) .logoutSuccessHandler(new LogoutSuccessHandler() { @Override public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { httpServletResponse.sendRedirect("/login_page"); } }) .and()
9.多个HttpSeurity
@Configuration public class MutiHttpSecurityConfig { @Bean PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } @Autowired protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin").password("123").roles("ADMIN","USER") .and() .withUser("san").password("123").roles("USER"); } @Configuration @Order(1) public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http.antMatcher("/admin/**") .authorizeRequests() .anyRequest().hasRole("ADMIN"); } } @Configuration public static class OtherSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest() .authenticated() .and() .formLogin() .loginProcessingUrl("/login") .permitAll() .and() .csrf() .disable(); } } }
Order 数字越小优先级越多,不加优先级最小