SpringSecurity是基于Spring应用提供的声明式的安全保护性的框架,它可以在web请求级别的和方法调用级别处理身份和授权。
1.引入SpringSecurity
创建maven项目引入依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
2.UserDetailsService的使用
当登录时,需要对传来的的参数进行验证,检测传来的用户名及密码是否正确,这时候就需要用UserDetailsService验证用户名、密码和授权。
@Service public class UserDetailServiceImpl implements UserDetailsService { @Autowired private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { //根据用户名进行查询 查询不到则报错 if (!"admin".equals(userName)){ throw new UsernameNotFoundException("用户名错误"); } //模拟从数据库中取出加密后的密码 String password=passwordEncoder.encode("123456"); //返回查询结果 返回的User是springsecurity的类, return new User(userName,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_abc")); }
实现UserDetailsService接口,根据用户名查出密码和权限等其他信息,封装成User类返回,若用户名和密码等信息和前端传来的信息一致,则登陆成功,否则失败。
3.WebSecurityConfigurerAdapter类参数设置
登录成功或者失败,我们都需要设置跳转页面或者给某个页面能否访问设置权限。这就需要WebSecurityConfigurerAdapter类进行参数设置,一些常用的设置参数如下:
@Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AccessDeniedHandler accessDeniedHandler; @Bean public PasswordEncoder getPe(){ return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { //表单提交 http.formLogin() //自定义入参:设置表单的参数名称 .usernameParameter("userName") .passwordParameter("password") //自定义登陆页面 确定哪个页面是登陆页面 .loginPage("/login.html") //自定义登录逻辑,必须和表单提交接口一样,执行自定义登录逻辑 .loginProcessingUrl("/login") //登陆成功后跳转页面,必须为post请求 .successForwardUrl("/toMain") //自定义的登录成功处理器 // .successHandler(new MySuccessUrlHandler("http://www.baidu.com")) //失败跳转登陆页面 post请求 .failureForwardUrl("/toError"); //授权 所有请求必须经过认证 //设置不需要认证的页面 http.authorizeRequests().antMatchers("/login.html").permitAll() .antMatchers("/error.html").permitAll() //基于权限认证 若有叫做“admin”的权限才可访问该页面 //.antMatchers("/main1.html").hasAnyAuthority("admin") //基于角色认证 .antMatchers("/main1.html").hasRole("abcd") //基于ip地址认证 //.antMatchers().hasIpAddress(""); //上述各种方法都是基于access //.antMatchers().access("hasRole('abc')") //设置除了上述页面外,其他页面的访问皆需权限认证 .anyRequest().authenticated(); http.csrf().disable(); //自定义异常处理器 http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); } }
自定义的登录成功处理器如下,登陆成功后会执行该方法:
public class MySuccessUrlHandler implements AuthenticationSuccessHandler { private String url; public MySuccessUrlHandler(String url) { this.url = url; } @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { httpServletResponse.sendRedirect(url); } }
自定义的异常处理器如下:
@Component public class MyAccessDenisHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException { httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); httpServletResponse.setHeader("Context-Type","application/json"); PrintWriter printWriter=httpServletResponse.getWriter(); printWriter.write("{\"msg\":\"权限不足\"}"); printWriter.flush(); printWriter.close(); } }