HarmonyOS鸿蒙Next中web中的网络请求怎么添加https证书验证

HarmonyOS鸿蒙Next中web中的网络请求怎么添加https证书验证 加载的是本地的html地址,加上了

.onSslErrorEventReceive((event) => {
  event.handler.handleConfirm();
})
.onSslErrorEvent((event) => {
  event.handler.handleConfirm();
})

页面可以正常加载,但页面中的接口报400 Norequired SSL certificate was sent。

请问怎么给网络请求加上证书认证?

8 回复

400 Norequired SSL certificate was sent 错误的核心原因是:

服务器启用了「双向 TLS 认证(mTLS)」,要求客户端在发起 HTTPS 请求时,必须提供有效的客户端TLS证书用于身份验证,但 WebView 未配置该证书,导致服务器拒绝请求。

1、如果能修改服务端代码改为单项认证,则不用改客户端。

2、参考官方文档实现客户端双向认证

https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-basic-components-web-events#onclientauthenticationrequest9

核心方法是:

onClientAuthenticationRequest(callback: Callback<OnClientAuthenticationEvent>)

通知用户收到SSL客户端证书请求事件。

.onClientAuthenticationRequest((event) => {
  console.info("onClientAuthenticationRequest ");

  this.certManager.grantAppPm().then(result => {
    console.info(`grantAppPm, URI==========${result}`);
    event.handler.confirm(result);
  })
  return true;
})

更多关于HarmonyOS鸿蒙Next中web中的网络请求怎么添加https证书验证的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


老师,我按照您指示的文档增加了onClientAuthenticationRequest,现在一到网络请求会自动跳转到证书管理,点击授权后跳转回来,但还是加载失败而且接口的相应code变成了0。请问跳转到证书管理中是正规证书颁发机构颁发的证书才可以这样使用吗?

我现在使用的是个人自签的证书,然后也尝试了 https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-basic-components-web-events#onclientauthenticationrequest9 中的第一种方式“安装私有凭证以实现双向认证”,然后有报错:Certificate verify error: 20, Certificate verify info: unable to get local issuer certificate, Total number of server certificate: 1,请问这是我的证书文件有问题吗?

在终端验证下证书是否正确:

curl -v -k \  # -k 跳过服务器证书验证(调试用)
  --cert ./client.crt \
  --key ./client.key \
  https://localhost:8443

安装私有凭证以实现双向认证:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';
import { certificateManager } from '@kit.DeviceCertificateKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Index {
  controller: WebviewController = new webview.WebviewController();
  uiContext : UIContext = this.getUIContext();
  context : Context | undefined = this.uiContext.getHostContext() as common.UIAbilityContext;
  uri: string = ''
  aboutToAppear(): void {
    webview.WebviewController.setRenderProcessMode(webview.RenderProcessMode.MULTIPLE)
  }
  build() {
    Column() {
      Button("installPrivateCertificate").onClick(() => {
        if (!this.context) {
          return;
        }
        //注:badssl.com-client.p12需要替换为实际使用的证书文件
        let value: Uint8Array = this.context.resourceManager.getRawFileContentSync("badssl.com-client.p12");
        certificateManager.installPrivateCertificate(value, 'badssl.com', "1",
          async (err: BusinessError, data: certificateManager.CMResult) => {
            console.info(`installPrivateCertificate, uri==========${JSON.stringify(data.uri)}`)
            if (!err && data.uri) {
              this.uri = data.uri;
            }
          });
      })
      Button('加载需要客户端SSL证书的网站')
        .onClick(() => {
          this.controller.loadUrl("https://client.badssl.com")
        })
      Web({
        src: "https://www.bing.com/",
        controller: this.controller,
      }).domStorageAccess(true)
        .fileAccess(true)
        .onPageBegin(event => {
          console.info("extensions onpagebegin url " + event.url);
        })
        .onClientAuthenticationRequest((event) => {
          console.info("onClientAuthenticationRequest ");
          event.handler.confirm(this.uri);
          return true;
        })
        .onSslErrorEventReceive(e => {
          console.info(`onSslErrorEventReceive->${e.error.toString()}`);
        })
        .onErrorReceive((event) => {
          if (event) {
            this.getUIContext().getPromptAction().showToast({
              message: `ErrorCode: ${event.error.getErrorCode()}, ErrorInfo: ${event.error.getErrorInfo()}`,
              alignment: Alignment.Center
            })
            console.info('getErrorInfo:' + event.error.getErrorInfo());
            console.info('getErrorCode:' + event.error.getErrorCode());
            console.info('url:' + event.request.getRequestUrl());
          }
        })
        .onTitleReceive(event  => {
          console.info("title received " + event.title);
        })
    }
  }
}

如果你在Chrome浏览器上可以访问你的网页,那就是证书没问题的。

私有证书都是自己生成的。不会有问题的。

确定是我的证书链不完整导致的,重新签了个证书就可以了

在HarmonyOS Next中,可通过以下方式添加HTTPS证书验证:

  1. module.json5中配置网络安全权限:
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
  }
}
  1. 使用@ohos.net.http模块创建HTTP请求时,通过sslCA属性指定证书:
import http from '@ohos.net.http';

let httpRequest = http.createHttp();
httpRequest.on('headersReceived', (event) => {
  // 证书验证回调
});

let options = {
  method: http.RequestMethod.GET,
  sslCA: 'base64编码的证书数据', // 或证书文件路径
  // 其他请求参数
};

httpRequest.request('https://example.com', options, (err, data) => {
  // 处理响应
});

证书需为Base64编码格式或系统可识别的证书文件路径。

在HarmonyOS Next中,当Web组件加载本地HTML并遇到HTTPS证书验证问题时,可以通过以下方式处理:

  1. 使用onSslErrorEventReceive回调:该回调用于处理SSL证书错误。你可以在回调中调用event.handler.handleConfirm()来忽略证书错误并继续加载,但这会降低安全性。

  2. 添加证书验证:如果需要严格验证证书,可以通过WebStoragesetHttpAuthCredentials方法设置证书信息。例如:

    webStorage.setHttpAuthCredentials({
      host: "your-domain.com",
      realm: "your-realm",
      username: "cert-user",
      password: "cert-data"
    });
    

    将证书数据作为password参数传入,系统会自动在请求中添加证书验证。

  3. 检查证书格式:确保证书为PEM或DER格式,并与服务器要求的证书匹配。错误"400 No required SSL certificate was sent"通常是因为客户端未发送要求的证书。

建议优先使用证书验证方式,避免直接忽略SSL错误,以保障通信安全。

回到顶部