Reputation: 403
I'm trying to load a client certificate to a http.client from the http.dart package.
I'v seen multiple answers on how to do it using the HttpClient class, like this answer: Flutter add self signed certificate from asset folder, which basicaly suggests to do the following code
ByteData data = await rootBundle.load('assets/raw/certificate.pfx');
SecurityContext context = SecurityContext.defaultContext;
context.useCertificateChainBytes(data.buffer.asUint8List());
context.usePrivateKeyBytes(data.buffer.asUint8List());
client = HttpClient(context: context);
But I must use the http.dart package since i have a function that accepts a http.client
something like this
import 'package:http/http.dart' as http;
var httpClient = http.Client();
// i'd like to configure this httpClient to use a specific client certificate
var client = MyClient(httpClient);
....
MyClient (http.Client? httpClient) {
-- some constructor logic --
}
Is there any way to configure a http.client
to use a client certificate?
Thanks.
Upvotes: 6
Views: 7986
Reputation: 111
you can use client certificates from a flutter client, thanks to DIO, which use dart.https instead of dart.http with this kind of code,
from my repo : https://github.com/ysimonx/mtls-ssl-generator
void getHttp() async {
Dio dio = new Dio();
ByteData clientCertificate = await rootBundle.load("assets/clientCrt.pem");
ByteData privateKey = await rootBundle.load("assets/clientKey.pem");
String rootCACertificate = await rootBundle.loadString("assets/caCrt.pem");
dio.httpClientAdapter = IOHttpClientAdapter()
..onHttpClientCreate = (_) {
final SecurityContext context = SecurityContext(withTrustedRoots: false);
context.setTrustedCertificatesBytes(utf8.encode(rootCACertificate));
context.useCertificateChainBytes(clientCertificate.buffer.asUint8List());
context.usePrivateKeyBytes(privateKey.buffer.asUint8List());
HttpClient httpClient = HttpClient(context: context);
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) {
if (cert.pem == rootCACertificate) {
return true;
}
return false;
};
return httpClient;
};
final response = await dio.get('https://localhost:3000/');
print(response);
}
Upvotes: 2
Reputation: 51682
Don't use the http.Client()
constructor. Instead, construct an IOClient
(which is a subclass of Client
as can be used instead). Pass in your HttpClient
.
import 'dart:io';
import 'package:http/io_client.dart';
void main() async {
final context = SecurityContext.defaultContext;
// modify context as needed
final httpClient = HttpClient(context: context);
final client = IOClient(httpClient);
await client.get(Uri.parse('https://somewhere.io'));
}
Upvotes: 6