什么是Spring Security?
Spring Security是一个能够为基于Spring的企业应用系统提供描述性安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(依赖注入,也称控制反转)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
Spring Security的使用
1.基于Spring boot创建Spring Security 项目
2.填写项目信息
3.选择web和Spring Security
4.写一个controller测试
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @RequestMapping("test") public String index() { return "Hello Word"; } }
5.启动项目
输入localhost:8080会进入页面
默认情况下,登录的用户名是 user,密码则是项目启动时随机生成的字符串,可以从启动的控制台日志中看到默认密码:
这个随机生成的密码,每次启动时都会变。对登录的用户名/密码进行配置,有三种不同的方式:
- 在 application.properties 中进行配置
- 通过 Java 代码配置在内存中
- 通过 Java 从数据库中加载
6.登录成功测试
这里是正确的,不是出错
输入test,可以看到测试时正确的
用户名和密码配置
1.配置文件配置用户名/密码
在application.properties 文件中配置
spring.security.user.name=lmc
spring.security.user.password=123
2.Java 配置用户名/密码
自己写一个config类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //下面这两行配置表示在内存中配置了两个用户 auth.inMemoryAuthentication() .withUser("lmc").roles("admin").password("123") .and() .withUser("lingmeng").roles("user").password("123"); } @Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
登录配置
对于登录接口,登录成功后的响应,登录失败后的响应,我们都可以在 WebSecurityConfigurerAdapter 的实现类中进行配置
@Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired VerifyCodeFilter verifyCodeFilter; @Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class); http .authorizeRequests()//开启登录配置 .antMatchers("/test").hasRole("admin")//表示访问 /hello 这个接口,需要具备 admin 这个角色 .anyRequest().authenticated()//表示剩余的其他接口,登录之后就能访问 .and() .formLogin() //定义登录页面,未登录时,访问一个需要登录之后才能访问的接口,会自动跳转到该页面 .loginPage("/login_p") //登录处理接口 .loginProcessingUrl("/doLogin") //定义登录时,用户名的 key,默认为 username .usernameParameter("uname") //定义登录时,用户密码的 key,默认为 password .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(); out.write("success"); out.flush(); } }) .failureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException { resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); out.write("fail"); out.flush(); } }) .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(); out.write("logout success"); out.flush(); } }) .permitAll() .and() .httpBasic() .and() .csrf().disable(); } }
忽略拦截
如果某一个请求地址不需要拦截的话,有两种方式实现:
- 设置该地址匿名访问
- 直接过滤掉该地址,即该地址不走 Spring Security 过滤器链
推荐使用第二种方案:
@Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/vercode"); } }