0
点赞
收藏
分享

微信扫一扫

安全框架--SpringSecurity

上一篇 <<<安全技术--接口幂等性设计
下一篇 >>>安全框架--JWT


Spring Security:一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
Spring Security思想和Shiro一致,具体介绍参考:https://baike.baidu.com/item/spring%20security/8831652?fr=aladdin

2种实现方式

  • a、Basic认证--基于HTTP协议的认证方式
.and().httpBasic()

  • b、form表单模式
.and().formLogin()

应用场景

  • 后台角色权限框架
  • 授权认证oauth2.0
  • 安全防护(防止跨站点请求)
  • Session攻击
  • 非常容易融合SpringMVC使用等

搭配RBAC权限模型核心代码

  • 账号及权限配置
// 配置认证用户信息和权限
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

    // 查询数据库
    auth.userDetailsService(myUserDetailsService).passwordEncoder(new PasswordEncoder() {

        // 加密的密码与数据库密码进行比对CharSequence rawPassword 表单字段 encodedPassword
        // 数据库加密字段
        @Override
        public boolean matches(CharSequence rawPassword, String encodedPassword) {
            System.out.println("rawPassword:" + rawPassword + ",encodedPassword:" + encodedPassword+"---");
            // 返回true 表示认证成功 返回fasle 认证失败
            System.out.println(MD5Util.encode((String) rawPassword));
            System.out.println(MD5Util.encode((String) rawPassword).equals(encodedPassword));
            return MD5Util.encode((String) rawPassword).equals(encodedPassword);
        }

        // 对表单密码进行加密
        @Override
        public String encode(CharSequence rawPassword) {
            return MD5Util.encode((String) rawPassword);
        }
    });
}

// 设置动态用户信息
@Service
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 1.根据用户名称查询数据用户信息
        User user = userMapper.findByUsername(username);
        if(null==user){
            return null;
        }
        // 2.底层会根据数据库查询用户信息,判断密码是否正确交给框架内

        // 3. 给用户设置权限
        List<Permission> listPermission = userMapper.findPermissionByUsername(username);
        System.out.println("username:" + username + ",对应权限:" + listPermission.toString());

        //利用lanmda表达式将权限设置进去
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        listPermission.forEach(p -> {
            authorities.add(new SimpleGrantedAuthority(p.getPermTag()));
        });
        user.setAuthorities(authorities);
        return user;
    }

}
  • 所有权限配置
// 配置拦截请求资源
protected void configure(HttpSecurity http) throws Exception {

    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http
            .authorizeRequests();
    // 1.读取数据库权限列表
    List<Permission> listPermission = permissionMapper.findAllPermission();
    for (Permission permission : listPermission) {
        // 设置权限
        authorizeRequests.antMatchers(permission.getUrl()).hasAnyAuthority(permission.getPermTag());
    }
    /**
     * 登录页面、登录成功或失败的跳转处理器,及关闭csrf模拟等
     */
    authorizeRequests.antMatchers("/login").permitAll()
            .antMatchers("/**").fullyAuthenticated()
            .and().formLogin()
            .loginPage("/login")
            .successHandler(successHandler)
            .failureHandler(failureHandler)
            .and().csrf().disable();

}
  • 重写错误页面配置
@Configuration
public class WebServerAutoConfiguration {
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        ErrorPage errorPage400 = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400");
        ErrorPage errorPage401 = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401");
        ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN, "/error/403");
        ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
        ErrorPage errorPage415 = new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "/error/415");
        ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
        factory.addErrorPages(errorPage400, errorPage401, errorPage403, errorPage404, errorPage415, errorPage500);
        return factory;
    }
}
  • 成功或失败后的跳转处理
// 认证成功
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication arg2)
            throws IOException, ServletException {
        System.out.println("用户认证成功");
        res.sendRedirect("/");
    }

}
//认证失败
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse res, AuthenticationException auth)
            throws IOException, ServletException {
        System.out.println("登陆失败!");
        res.sendRedirect("/loginError");

    }

}

关键源码图示





相关文章链接:
<<<Web常用攻击手段-XSS攻击
<<<Web常用攻击手段-SQL注入
<<<Web常用攻击手段-Http请求防盗链
<<<Web常用攻击手段-CSRF攻击
<<<Web常用攻击手段-上传文件漏洞
<<<Web常用攻击手段-忘记密码
<<<Web常用攻击手段-其他漏洞
<<<安全技术--数据加密/认证技术
<<<安全技术--Https相关知识
<<<安全技术--接口幂等性设计
<<<安全框架--JWT
<<<安全框架--OAuth2
<<<安全架构整体设计方案

举报

相关推荐

0 条评论