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

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

公司使用的安全架构是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);
    }
}


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

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


相关文章
|
云计算
为什么一定要考阿里云认证?对工作有什么帮助?
考证对工作的帮助并不是短时间内见效的,而是长期的回报,在同等的技术下选择拥有证书的,在拥有证书的人群中选择技术更好的,这是职场永远不变的铁律。
|
存储 监控 安全
关于 API 安全你需要知道的那些事,不知道会后悔!接口被恶意调用,数据被篡改等问题
回到正题,不管是 app,还是各个访问终端的入口,作为最终承载交互数据的来源 — API 接口,无疑需要对数据的安全访问提供最终的支撑和保障。接下来,让我们花点时间来聊聊关于 API 接口安全的那些事吧。
|
数据安全/隐私保护
带你读《商用密码技术最佳实践白皮书》——委托凭证(2)
带你读《商用密码技术最佳实践白皮书》——委托凭证(2)
|
数据安全/隐私保护
带你读《商用密码技术最佳实践白皮书》——委托凭证(1)
带你读《商用密码技术最佳实践白皮书》——委托凭证(1)
|
云安全 监控 安全
只想着一直调用一直爽, 那API凭证泄漏风险如何破?
如今各家云厂商都通过给用户提供API调用的方式来实现一些自动化编排方面的需求。为了解决调用API过程中的通信加密和身份认证问题,大多数云厂商会使用同一套技术方案—基于非对称密钥算法的鉴权密钥对,这里的“密钥对”即API凭证,是云上用户调用云服务API、访问云上资源的唯一身份凭证。
2415 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中分别声明使用相应的权限。
1448 0
|
XML 安全 Android开发
安卓应用安全指南 5.3.1 将内部账户添加到账户管理器 示例代码
5.3.1 将内部账户添加到账户管理器 示例代码 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 “5.3.1.1 创建内部帐户”是认证器应用的示例,“5.3.1.2 使用内部帐户”是请求应用的示例。
1179 0