【SpringBoot学习九】springboot+spring-security实现登录验证

Spring Security介绍
*
Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完整的安全性解决方案,能够在web请求级别和方法调用级别
处理身份证验证和授权.它充分使用了依赖注入和面向切面的技术.
Spring security主要是从两个方面解决安全性问题:

web请求级别:使用servlet过滤器保护web请求并限制URL级别的访问
方法调用级别:使用Spring AOP保护方法调用,确保具有适当权限的用户采用访问安全保护的方法.*
下面介绍springboot2.0如何集成spring security

1.pom.xml引入依赖


    org.springframework.boot
    spring-boot-starter-security

2.创建验证成功返回处理类

@Component("authenticationSuccess")
public class AuthenticationSuccess implements AuthenticationSuccessHandler {
    //验证成功后进入系统前进行的处理,比如初始化权限用户信息等
    @Autowired
    private ILoginService loginService;
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        //authentication.getName()这个是认证通过的账号
        UserLogin ul=loginService.findUserLoginByName(authentication.getName());
        //例如把用户信息存入session
        request.getSession().setAttribute("USERSESSION", ul);
        //处理完成后重定向到系统主页面的链接
        new DefaultRedirectStrategy().sendRedirect(request, response, "/main");
    }
}

3.创建验证失败的处理类

@Component("authenticationFailure")
public class AuthenticationFailure implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {
        String meg="登录失败";
        //重定向到失败页面
        request.getRequestDispatcher("/authority/login?meg="+meg).forward(request, response);
    }

}

4.实现springsecurity获取用户信息接口,将业务数据封装成security的用户对象提供给security验证

@Component
@Transactional//需要事务就加,不需要就去掉该注解即可
public class AuthUserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private ILoginService loginService;
    //通过登录账号加载业务用户信息,参数为用户账号
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        通过业务账号获取业务系统的用户信息
        UserLogin userLogin= loginService.findUserLoginByName(s);
        if(userLogin==null) {
            throw new BadCredentialsException("no user");
        }
        //创建security的权限实体,用于存放用户权限的
        List authorities = new ArrayList<>();
        //可以放入多个权限
        authorities.add(new SimpleGrantedAuthority("SYSTEM"));
        //将业务系统的用户信息以及权限信息封装到security的用户实体中
        return new User(user.getUsername(), user.getPassword(), authorities);
    }
}

5.创建security的配置类

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //引入成功与失败的处理类
    @Autowired
    private AuthenticationSuccess authenticationSuccess;
    @Autowired
    private AuthenticationFailure authenticationFailure;

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 密码加密方法;
        return new BCryptPasswordEncoder();
    }
    //注入封装账号信息的处理bean
    @Bean
    UserDetailsService detailsService() {
        return new AuthUserDetailsServiceImpl();
    }

    //配置不拦截的静态资源请求
    @Override
    public void configure(WebSecurity web) throws Exception {
        // TODO Auto-generated method stub
        web.ignoring().antMatchers("/css/", "/img/", "/js/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
         http.authorizeRequests()
         //antMatchers无需权限 即可访问,permitAll面向全部用户开放
        .antMatchers("/login").permitAll()
        //除了antmatchers中的例外,其他任何请求都需要权限认证
        .anyRequest().authenticated()
        //formlogin登录配置,and()是链接符,and之间的内容有相同的作用域
        .and().formLogin().loginPage("/login")
        .successHandler(authenticationSuccess)//登陆成功处理
        .failureHandler(authenticationFailure)//登录失败的处理
        //登录验证处理请求,请求逻辑是security内置的,此处只设置自己喜欢的请求就可以了,然后在表单中提交的请求要与此处设置的一致即可
        .loginProcessingUrl("/login")
       //设置security内置的请求表单元素的name名称,此处设置的要与登录表单的用户名密码的name一致 .usernameParameter("loginname").passwordParameter("password").permitAll()
        .and().headers().frameOptions().disable()
        //设置登出后跳转的链接,一般设置登录页面,登录请求也是security内置的默认为logout,自定义登录链接用.logoutUrl(logoutUrl)
        .and().logout().logoutSuccessUrl("/login").permitAll()
        .and().csrf().disable();// 关闭csrf防护
    }

     //设置用户信息获取方法,获取方法是自定义的实现security提供的接口即可
     //就是通过自定义接口实现获取业务用户的信息包括用户名,密码,权限,交给security处理
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {    auth.userDetailsService(detailsService()).passwordEncoder(passwordEncoder());
    }
    @Bean
    public SecurityContextRepository securityContextRepository() {
      //设置对spring security的UserDetails进行session保存,这个必须要有,不然不会保存至session对应的缓存redis中
        HttpSessionSecurityContextRepository httpSessionSecurityContextRepository =
            new HttpSessionSecurityContextRepository();
        return httpSessionSecurityContextRepository;
    }
}

至此springboot2.0对spring security的集成就完成了!试试吧

你可能感兴趣的:(SpringBoot学习)