直捣黄龙,我直接攻破公司的认证框架调用系统的接口

简介: 直捣黄龙,我直接攻破公司的认证框架调用系统的接口

公司使用的安全架构是Shiro,所以每访问一个请求都需要带一个令牌去访问这个接口,否则就是被拦截,其实我们可以在配置类中把要访问的接口给放开,允许通行:


public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // Shiro的核心安全接口,这个属性是必须的
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        filterChainDefinitionMap.put("/user_curriculum_vitae/pull", "anon");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }


类似上面这样我们就把user_curriculum_vitae这个接口给放开了。

但是!!这就意味着他获取不到令牌了,没有令牌只有也意味着获取不到用户的信息,这样系统在进行用户信息的时候就会报错,这样我们有什么更好的方法呢?类似想实现一个免登录的功能?只需要账号即可跳过验证,拿到用户的信息。

这里我们就要请出今天的主角:Filter

这里类是在javax.servlet包下,也就是说是java提供的最原始的过滤器接口,所以我们可以实现这个接口:

@WebFilter
@Component
public class AuthFilter implements Filter {
    @Autowired
    private CmcServerFeigin cmcServerFeigin;
    /**
     * 要拦截的请求
     *
     * @Param:
     * @return:
     * @Author: MaSiyi
     * @Date: 2022/2/11
     */
    private final String[] filter = {
            "/ddqr/autoCreatedFlow",
            "/autoCreateFlow/handleCreateFlow",
            "/autoCreateFlow/normalCreateFlow"
    };
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestURI = request.getRequestURI();
        List<String> list = Arrays.asList(filter);
        if (list.contains(requestURI)) {
            filterChain.doFilter(setKeyId(request), response);
        } else {
            filterChain.doFilter(request, response);
        }
    }
    /**
     * 往请求头添加 keyId
     *
     * @param request
     * @return
     */
    public RHttpServletRequest setKeyId(HttpServletRequest request) {
        RHttpServletRequest rHttpServletRequest = new RHttpServletRequest(request);
        //获取
        JSONObject obj = new JSONObject();
        ResultUtils res;
        String psnCode = rHttpServletRequest.getHeader("psnCode");
        if (!StringUtils.isEmpty(psnCode)) {
            obj.put("signature", psnCode);
        }
        res = cmcServerFeigin.getToken(obj);
        String keyId = "";
        if (CodeEnums.SUCCESS_CODE.getCode().equals(res.getCode())) {
            JSONObject jsonObject = JsonUtils.toJsonObject(res.getData());
            String token = jsonObject.getString("token");
            keyId = token == null ? jsonObject.getString("keyId") : token;
        } else {
            System.out.println("获取keyId失败:" + JsonUtils.toJsonObject(res));
        }
        rHttpServletRequest.addHeader("keyId", keyId);
        return rHttpServletRequest;
    }
    @Override
    public void destroy() {
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
}

这里我们一个要实现三个抽象方法:

doFilter //过滤器 destroy //销毁的时候调用 init // 初始化的时候调用

在doFilter方法中我们,可以对请求头和返回体做响应,其实可以理解为一个拦截器

而在

    private final String[] filter = {
            "/autoCreateFlow/handleCreateFlow",
            "/autoCreateFlow/normalCreateFlow"
    };


这个数组中,我们可以理解他为过滤器,这里有一个面试官常常问的问题:


你了解过拦截器和过滤器吗?


其实按照我的理解就是拦截器就是对请求在进入方法之前我们可以对他们进行一些特殊的操作,例如修改请求体等等,而过滤器呢就是可以过滤掉一些请求去访问我们的方法,例如过滤掉某些不需要认证的接口,如springsecurity中放行的接口。


所以上面这个类的作用就是,凡是在我filter数组中的请求我们就可以对他们进行一些操作,这里的操作就是在他们的request中添加对应的授权信息,这样就使得别人调用接口的时候就可以实现权限的认证了。


但是!在上面的HttpServletRequest类中他是没有添加请求头的方法的,所以这里我们要重写一个类用来给请求头添加信息:

public class RHttpServletRequest extends HttpServletRequestWrapper {
    private Map<String, String> headerMap = new HashMap<>();
    public RHttpServletRequest(HttpServletRequest request) {
        super(request);
    }
    @Override
    public String getParameter(String name) {
        return super.getParameter(name);
    }
    /**
     *
     * 添加具有给定名称和值
     * @param name
     * @param value
     */
    public void addHeader(String name, String value) {
        headerMap.put(name, value);
    }
    @Override
    public String getHeader(String name) {
        String headerValue = super.getHeader(name);
        if (headerMap.containsKey(name)) {
            headerValue = headerMap.get(name);
        }
        return headerValue;
    }
    @Override
    public Enumeration<String> getHeaderNames() {
        List<String> names = Collections.list(super.getHeaderNames());
        for (String name : headerMap.keySet()) {
            names.add(name);
        }
        return Collections.enumeration(names);
    }
    @Override
    public Enumeration<String> getHeaders(String name) {
        List<String> values = Collections.list(super.getHeaders(name));
        if (headerMap.containsKey(name)) {
            values = Arrays.asList(headerMap.get(name));
        }
        return Collections.enumeration(values);
    }
}


这样就能够实现对于请求头的相关操作啦!

如果你看到这里,希望给博主一个点赞收藏加关注哦!!


相关文章
|
存储 前端开发 安全
强化用户体验与安全性:前端单点登录和统一认证的最佳实践与区别
互联网发展了这么多年,各种更新皆为了提供更好更安全的上网环境。同时为了提供更好的用户体验、减少用户反复输入用户名和密码的繁琐操作,并确保账户安全,前端领域中的单点登录(SSO)和统一认证(Unified Authentication)成为了重要概念。
强化用户体验与安全性:前端单点登录和统一认证的最佳实践与区别
|
6月前
|
机器学习/深度学习 人工智能 安全
【亮剑】无密码身份验证的概念,它通过生物识别、安全令牌等替代技术验证身份,旨在提高安全性和用户体验。
【4月更文挑战第30天】本文探讨了无密码身份验证的概念,它通过生物识别、安全令牌等替代技术验证身份,旨在提高安全性和用户体验。无密码验证简化登录、增强安全性,但也面临实施成本、技术兼容性和用户适应性的挑战。随着技术发展,无密码验证有望成为更广泛的安全认证方式,但实施时需综合考虑多种因素。
108 0
|
云计算
为什么一定要考阿里云认证?对工作有什么帮助?
考证对工作的帮助并不是短时间内见效的,而是长期的回报,在同等的技术下选择拥有证书的,在拥有证书的人群中选择技术更好的,这是职场永远不变的铁律。
|
数据安全/隐私保护
带你读《商用密码技术最佳实践白皮书》——委托凭证(2)
带你读《商用密码技术最佳实践白皮书》——委托凭证(2)
|
数据安全/隐私保护
带你读《商用密码技术最佳实践白皮书》——委托凭证(1)
带你读《商用密码技术最佳实践白皮书》——委托凭证(1)
拒绝接口裸奔!开放API接口签名验证
接口安全问题 请求身份是否合法? 请求参数是否被篡改? 请求是否唯一?
|
前端开发 数据挖掘 API
【服务器开发系列】极验证怎么玩的?
【服务器开发系列】极验证怎么玩的?
291 0
【服务器开发系列】极验证怎么玩的?
|
安全 算法 Java
安卓应用安全指南 5.7 使用指纹认证功能
5.7 使用指纹认证功能 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 目前正在研究和开发的各种用于生物认证的方法中,使用面部信息和声音特征的方法尤其突出。
1437 0
|
安全 Android开发 开发者
安卓应用安全指南 5.3.3 将内部账户添加到账户管理器 高级话题
5.3.3 将内部账户添加到账户管理器 高级话题 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 5.3.3.1 账户管理和权限的使用 要使用AccountManager类的每种方法,都需要在应用的AndroidManifest.xml中分别声明使用相应的权限。
1447 0