Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add support for client certificate password and test with real services that require client certificate auth #32

Merged
merged 13 commits into from
Jun 16, 2017

Conversation

phillee007
Copy link
Contributor

Add support for client certificate password and test with real services that require client certificates. Also update so when proxying, the path and query will be passed to the proxied api.

Please have a look and let me know what you think. I ran a test for it locally, but it's a bit hard to checkin a runnable unit test as it would require a real service (which I have in my environment) plus a valid pfx with password

…ervices that require client certificates. Also update so when proxying, the path and query will be passed to the proxied api.
@codecov
Copy link

codecov bot commented Jun 10, 2017

Codecov Report

Merging #32 into master will decrease coverage by 0.76%.
The diff coverage is 31.57%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #32      +/-   ##
==========================================
- Coverage    50.4%   49.63%   -0.77%     
==========================================
  Files          58       59       +1     
  Lines        1867     1904      +37     
  Branches      252      258       +6     
==========================================
+ Hits          941      945       +4     
- Misses        858      891      +33     
  Partials       68       68
Impacted Files Coverage Δ
...rc/WireMock.Net/Settings/ProxyAndRecordSettings.cs 0% <0%> (ø) ⬆️
src/WireMock.Net/Admin/Mappings/ResponseModel.cs 63.63% <0%> (-6.37%) ⬇️
src/WireMock.Net/Http/CertificateUtil.cs 0% <0%> (ø)
src/WireMock.Net/Server/FluentMockServer.Admin.cs 23.31% <11.11%> (-0.44%) ⬇️
src/WireMock.Net/Http/HttpClientHelper.cs 57.77% <63.15%> (-6.33%) ⬇️
src/WireMock.Net/ResponseBuilders/Response.cs 75.49% <71.42%> (+0.74%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c29b88e...af2a035. Read the comment docs.

Copy link
Collaborator

@StefH StefH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some remarks and questions.

/// <returns>A <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2Filename, string clientX509Certificate2Password)
{
Check.NotEmpty(clientX509Certificate2Filename, nameof(clientX509Certificate2Password));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix this Check --> you check clientX509Certificate2Filename but use nameof(clientX509Certificate2Password)

And add a second check.

/// </summary>
/// <param name="proxyUrl">The proxy url.</param>
/// <param name="clientX509Certificate2Filename">The X509Certificate2 file to use for client authentication.</param>
/// /// <param name="clientX509Certificate2Password">The X509Certificate2 password.</param>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove ///

@@ -285,7 +305,10 @@ public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2

if (ProxyUrl != null)
{
return await HttpClientHelper.SendAsync(requestMessage, ProxyUrl, X509Certificate2Filename);
var requestUri = new Uri(requestMessage.Url);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Why not just add the new parameter (X509Certificate2Password) to the method?

@@ -129,7 +129,11 @@ private void InitProxyAndRecord(ProxyAndRecordSettings settings)

private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, ProxyAndRecordSettings settings)
{
var responseMessage = await HttpClientHelper.SendAsync(requestMessage, settings.Url);
var requestUri = new Uri(requestMessage.Url);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, please explain why this needed.

/// <summary>
/// The X509Certificate2 password.
/// </summary>
public string X509Certificate2Password { get; set; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it safe to return the password?

@StefH
Copy link
Collaborator

StefH commented Jun 11, 2017

I've added some remarks and questions. Can you please take a look?

@StefH StefH changed the title For your review: Add support for client certificate password and test with real services that require client certificate auth [Feature] Add support for client certificate password and test with real services that require client certificate auth Jun 13, 2017
@StefH StefH added the feature label Jun 13, 2017
@phillee007
Copy link
Contributor Author

Hi Stef,

Thanks for all your comments, they're very helpful and I see I missed a few things (inc. updating all tests!)
With regard to client certificates and passwords, the two main options I've seen in the past for reading a client cert to send with a request are:

  1. Read it from a pfx file, and have to specify the password (as generally .pfx are stored with a password, especially if they're production certs we want to use when proxying a live service)
    Pros:
  • Can read from a NAS share or somewhere else, so tests can be run on any machine and read from a common location without having to do any importing of certs into their store
    Cons:
  • Have to send password for reading cert, and store in each request stub mapping and proxyandrecordsettings
  1. Read it from the certificate store on the local machine
    Pros:
  • No need to store passwords in tests or test configuration
    Cons:
  • Have to configure machines on which tests will be run so that certificate is in the store

In this PR, I've done the code for option (1). However, I could update it to do option (2) instead if you think that's preferable? Thoughts?

Thanks,
Phil

@StefH
Copy link
Collaborator

StefH commented Jun 16, 2017

  1. I'll do the review, thanks for taking this up. And provide feedback.
  2. And I will have to read some more on certificates, to see what is possible.
  3. You said you have implemented option 1, is is also possible to ALSO build option 2?

Copy link
Collaborator

@StefH StefH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small comments.

if (matchingCertificates.Count == 0)
{
// No certificates matched the search criteria.
throw new Exception("no cert fount");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw new Exception("No certificate found with Thumbprint or SubjectName '{0}'", thumbprintOrSubjectName);

// Use the first matching certificate.
return matchingCertificates[0];
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line

/// <returns>A <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2Filename)
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add:
[NotNull] string proxyUrl
and
[NotNull] clientX509Certificate2ThumbprintOrSubjectName

@StefH
Copy link
Collaborator

StefH commented Jun 16, 2017

I've added some small comments, can you take a look?

@phillee007
Copy link
Contributor Author

phillee007 commented Jun 16, 2017 via email

@StefH
Copy link
Collaborator

StefH commented Jun 16, 2017

Yes rebasing and merging can be difficult to understand sometimes.

Maybe I can create an organization and add you as a member.

If we then work only from separate branches and review the code and only merge to master, that could also work...

@phillee007
Copy link
Contributor Author

phillee007 commented Jun 16, 2017 via email

@StefH StefH merged commit 49ce2f0 into WireMock-Net:master Jun 16, 2017
@phillee007
Copy link
Contributor Author

phillee007 commented Jun 16, 2017 via email

@StefH
Copy link
Collaborator

StefH commented Jun 16, 2017

I've just created an Github organization, and I will move the code from here to that organization.
After this is done, I will invite you.

@StefH
Copy link
Collaborator

StefH commented Jun 17, 2017

I sent invite to you for joining the organization.

Can you also tell me your full name ? So I can include this in the csproj/nuget.

As discussed ; can you please create a separate branch for new functionality, then we can review and if it's correct, merge back to master.

@phillee007
Copy link
Contributor Author

phillee007 commented Jun 17, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants