Mocking HTTPS request using mountebank - https

Hi I have created one HTTPS service using mountebank tool - however I am getting "Socket Hang Up " error during impostor creation. Below are the steps followed
Added the CA authorized certificate in postman tool under 'Settings under that Certificates tab'.
Impostor creation
Impostor config:
{
"port": 4549,
"protocol": "https",
"mutualAuth": true,
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDDvLC9pnYOPJ54\nWrATkuuA7c41aVOy6nBnbK7ogIn/H+p2Fl8Xubqov1vkoIbo3mktM07G1cOGGPhD\nh3UXQl8+xjlPO+VBGT9H80eR+1G8VcBLPxuPHtua/CfLX2g4AzNeSoHPw89o5Xkv\nWhXjadyg7RDt80dfYKzXoElHBvM4nR1ngIRGFrin+PPavVZp/LTRsHWHSp8EOsLy\nf/+RHYYoNDDt/Yhla2sfFRJz5Sqzpmerzeaww1kZg2f9uuJoTT+NzNfmQ+jdnyW/\nMbtG2O0aXit+wRzBOVhcOqn2pYL4kvDXsVOWhTt4J3j1F+3rXXDWrUtKOV/WdE3z\nnqBQOT91AgMBAAECggEAdrR7Nzi5hd7LeE//Uo+aVUFi+k9bHDlDW+W0mXpCtj9j\n0KO2ncvcYLRUhW25A4bGoEvqbXl8L1n7TfDbWPS+kHJklSHM4dLu5rKqZ+TTZ/VV\nPg0SqJRdODvN4m+E49tFDtz+psKoiYQJH2dxuM4dqFa9GqGcWkJl8ArcBcA4Rs8q\nSij1fpqoVHCM0iELJZdWgZrsTHwZ07BJ057+GUbYrirXa5lYvM3/i0HafirWxJBT\nAGxdMw+bGcKsxYaIlwq4jGOKb/3txwIOgZJ6PG1XCqiiEjVhbNDEvwLhgSIEnkct\n14bhylRupKDWU425pnKWPFiek6ucEwMzzDqr6fj6gQKBgQDlhFhnITKd7YoHirwP\nLLmI8JNrxrMlWqoRimXtVVknlV60byIULBOigPDK1nMnC2kfGmXWueR1SQd6nXhE\na2r0sPqHX7AL2mzYYph8endTwKv1DQLLF25Hw2ht90pSaT70SRjc5GtVDVGA0tp6\nQYiRnmSYpd2fOTPBVRQn0VFU1QKBgQDaUocJuiRwKxaWtNjdgvoxjD/qxKdHk/lZ\nuZ1ZKsntp7z+XSPI8uEfyhfMb58by7JkJnaTla7H01u2Sm+ZzCR2zyp5d9TmdJr3\nVLIOuQ+QCV8reEJF3/YYDPmtFUc5V/SgOEfaCpFWO9hdmo1j+Mwj0U4ic1c52bF7\nTY3tubAQIQKBgQC4pB7GYLOqz3Uymg6umolsPDYtBz4JuAWHdPKI2xeNO6Jjv+AH\noGnvWpHcbGdZKtnX1tHEy+mZ3TVyFAqz6EK0NUhm7bjf4EmeTrtjsNYcf60Wx+/O\nWLw0aWSyyrV01Qx7U+73jZ83Xi6KV5bBscTfeTBuiUlglZEoYHyFh+RJPQKBgDcP\nOR8q4qWnODspwMeckJyOUlBS6B0VJH2MYjJqqCJXe0JrGutC1aO+w+G7BNVtub+o\nM59k0H90vlxqyVpwMYIFHSElJ3w3TB20LnOoGFSrCGVeHtigct/95bnQ8/VySS9f\nAj/rClxFG3v/zki4JkOiNaJalFTyoeAG3xRlEBIBAoGASC4gdy+tSZMS9420Rj4b\nYoLwA3zTGkkefg0//4tO0RP2UhisnK9GxDLBP3PMnXGileJJ/fcHznWTj2ISVKW7\n3HjHjSDvUS8aaQ201QH8p+9bljYZ4L7pU5cbGWeMMZKp6wn08tx7XSB8qhDPhjeR\nKLBP7HSOBEeH1oKdp5tCIa8=\n-----END RSA PRIVATE KEY-----",
"cert": "-----BEGIN CERTIFICATE-----\nMIIGZDCCBUygAwIBAgIRAIjdWBd3Fgl0ufH3IMCU9YYwDQYJKoZIhvcNAQELBQAw\ngZAxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\nBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTYwNAYD\nVQQDEy1DT01PRE8gUlNBIERvbWFpbiBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIg\nQ0EwHhcNMTgwNDA1MDAwMDAwWhcNMTkwMzIxMjM1OTU5WjBeMSEwHwYDVQQLExhE\nb21haW4gQ29udHJvbCBWYWxpZGF0ZWQxHTAbBgNVBAsTFFBvc2l0aXZlU1NMIFdp\nbGRjYXJkMRowGAYDVQQDDBEqLmluZm9zdHJldGNoLmNvbTCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMRSsjPxJWiRwJlSy3W1GLbzmddtvO6tfUVLfBTo\nQZgv6rLpbs63SM4lp0xK9lmCCHUXEWhipK0xB5IuuYQsxlW78V9lyZl+cnMUlr6M\n/XtKlv/IpSkxMD8YNJbLbhFhbRe66LEE8de/M8u7i3mxAbaSDNKyjKugJ/FyLvTy\nHWF5hbQGIfdz+57l9QH8OTYtsI7nmS+sZmwYDDjAerZKKTYLwZG7llixmL1ej6wU\nKOd6wuV0hc4dOZqUJ8fuylYE5yZ/7GIY/P1R8NPKjsA3YWhVxc2nMRzTihQyA6R5\nK+nWxkUGGGW7V29nclaAwrTQyY53bYaO/5E6G1j9cY73CHUCAwEAAaOCAugwggLk\nMB8GA1UdIwQYMBaAFJCvajqUWgvYkOoSVnPfQ7Q6KNrnMB0GA1UdDgQWBBScle59\nt6iD7IBAUZKRlKoGP4A/GzAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAd\nBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA6BgsrBgEE\nAbIxAQICBzArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29t\nL0NQUzAIBgZngQwBAgEwVAYDVR0fBE0wSzBJoEegRYZDaHR0cDovL2NybC5jb21v\nZG9jYS5jb20vQ09NT0RPUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNB\nLmNybDCBhQYIKwYBBQUHAQEEeTB3ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LmNv\nbW9kb2NhLmNvbS9DT01PRE9SU0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVy\nQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wLQYD\nVR0RBCYwJIIRKi5pbmZvc3RyZXRjaC5jb22CD2luZm9zdHJldGNoLmNvbTCCAQUG\nCisGAQQB1nkCBAIEgfYEgfMA8QB3AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDE\ne4l6qP3LAAABYpSbyqIAAAQDAEgwRgIhAJUu1vCoNhXPYiPnBOLCmPBCbCSgru9t\n5lLfAkXWwm/vAiEAy8WAtA2+ZTjYNXboJlVjkXaSeaYmVgU9bseV2NGCqesAdgB0\nftqDMa0zEJEhnM4lT0Jwwr/9XkIgCMY3NXnmEHvMVgAAAWKUm8rkAAAEAwBHMEUC\nIG85+amRuKn/dEygyPSWSeSHq+tHA3UPwa/DXtuzRlgqAiEA7d4N0zQZ/611p5yA\nmnIPs+LRV/JcvafXHQTkaNA+7KQwDQYJKoZIhvcNAQELBQADggEBAIM1pD3NRA5c\nQo8tPWF2qq+mA4cPULpt/XJsFrKFqcDf14XTGML0adS06ZpjvnjMmUoIt3gpuXgf\n1t+mtJ8Ze7vBz1gUpB5eBIvcU10IHVUTbqVv2PlnadQZ6yDy+4SPEfwdJelMDt6d\nTcvFDWB+KqUKz5a2YvCif/WGGWmQ09sVuZ7QCMK3JD7ym+L1k9G5cFfm9Kf7pAQE\n4PO/4kYM8+DN4ujqkaT20DN4Zh+jZVM/p5CwvqPe0HFv7zYiukFENJeFcMMtwS+n\n8XI3MU3VWT1L2+PbdPJ+sKd6fDwIIJmWVMsOT5tFwB/zIkwXv1aEjHfHprDuLPi4\nRKBzyPQF3Ts=\n-----END CERTIFICATE-----",
"stubs": [
{
"responses": [
{
"is": {
"body": {
"accountNum": "123456789",
"statusCode": 200
}
}
}
],
"predicates": [
{
"equals": {
"method": "GET",
"path": "/test",
"headers": {
"Accept": "text/plain",
"Name": "abc"
}
}
}
]
}
]
}

Related

Wiremock request.query not working with a paramter that contains dots

I'm using sprint-boot with wiremock-jre8, what i'm trying to to is to get a value from URL params, but this value contains dots "product.productCharacteristic.value"
{
"request": {
"urlPath": "/exampleOfPath",
"method": "GET",
"queryParameters": {
"product.productCharacteristic.name": {
"equalTo": "MSISDN"
},
"product.productCharacteristic.value": {
"matches": ".*"
}
}
},
"response": {
"status": 200,
"jsonBody": {
"key": "the value should be here {{request.query['product.productCharacteristic.value']}}"
},
"transformers": [
"response-template"
],
"headers": {
"Content-Type": "application/json"
}
}
}
i have tested all of those
{{request.query.['product.productCharacteristic.value']}}
{{request.query['product.productCharacteristic.value']}}
{{request.query['product%2EproductCharacteristic%2Evalue']}}
{{request.query.['product%2EproductCharacteristic%2Evalue']}}
{{request.query.product%2EproductCharacteristic%2Evalue}}
{{request.query.product.productCharacteristic.value}}
{{lookup request.query 'product.productCharacteristic.value'}}
{{lookup request.query 'product%2EproductCharacteristic%2Evalue'}}
You can use this format:
{{request.query.[product.productCharacteristic.value]}}
See WireMock - Response Templating - The request model:
request.headers.[<key>] - Header with awkward characters e.g. request.headers.[$?blah]

Springdoc + OpenId Connect = missing client_id from Swagger request

I am integrating a Spring Boot application with OIDC. The customer has an OIDC manifest file, at https://example.biz/.well-known/openid-configuration, which is redacted as displayed later.
Problem
When I attempt to authenticate via Swagger, the authorization endpoint complains that a parameter is missing. I could see that Swagger does not send the client_id parameter in (it's actually empty).
Please note, I expect that 99% of the configuration is handled by Springdoc after the OIDC configuration URL.
Question
Why doesn't Springdoc/Swagger OIDC setup work according to the existing setup and OIDC manifest?
Set up
OIDC manifest I can retrieve from authorization endpoint
{
"client_id": "the-clientid",
"issuer": "https://...",
"authorization_endpoint": "https://...",
"token_endpoint": "https://...",
"userinfo_endpoint": "https://...",
"jwks_uri": "https://...",
"end_session_endpoint": "https://...",
"registration_endpoint": null,
"scopes_supported": [
"openid"
],
"response_types_supported": [
"token",
"id_token",
"id_token token"
],
"response_modes_supported": [
"form_post",
"fragment"
],
"grant_types_supported": [
""
],
"subject_types_supported": [
"pairwise"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"token_endpoint_auth_methods_supported": [
"client_secret_basic"
],
"claims_supported": [
"sub",
"iss",
"aud",
"exp",
"iat",
"auth_time",
"nonce"
]
}
I import this scheme using Springdoc's #SecurityScheme annotation
#ConditionalOnProperty(...) // I can switch between basic (dev) and oidc authentication (test, uat, prod)
#SecurityScheme(
name = "secured",
type = OPENIDCONNECT,
openIdConnectUrl = "${oidc-url}/.well-known/openid-configuration" //Parameterized URL works here
)
public class OidcConfiguration {
}
Swagger displays me the Authorize button on top of the page.
However, when I see the generated Swagger OpenAPI v3 schema, it looks like the following
{
"openapi": "3.0.1",
"info": {
"title": "API",
"version": "v1"
},
"servers": [
{
"url": "http://localhost:8080",
"description": "Generated server url"
}
],
"paths": {
"/api/v1/.....": {
"patch": {
"tags": [
"...."
],
"operationId": "...",
"responses": {
"200": {
"description": "OK"
}
},
"security": [
{
"secured": []
}
]
}
},
"/health.check": {
"get": {
"tags": [
"probe-controller"
],
"operationId": "healthCheckProbe",
"responses": {
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"type": "boolean"
}
}
}
}
},
"security": [
{
"open": []
}
]
}
}
},
"components": {
"securitySchemes": {
"secured": {
"type": "openldConnect",
"openldConnectUrl": "https://...."
}
}
}
}
As you can see, the JSON file points to the remote OIDC configuration, and Swagger retrieves it.
But when I click on the Authentication button, I can see in the popup
secured (OAuth2, )
OpenId Connect URL: https://.....
Flow:
Scopes (select all, select none)
[ ] openid
According to this, I am not prompted with any client id. Clicking on Authorize opens a new window where I can't debug the original URL, as I am immediately redirected and DevTools is not open yet.
But after login request, I could see that the next URL displays ?client_id=&.....
If I manually navigate the URL with the client ID set, I can be redirected.
I also tried to set springdoc.swagger-ui.oauth.clientId=some client id according to linked issue, but it didn't display the input box.

Spring boot OpenAPI 3 download multipart with JSON content and attachment

I am seeing a 406 error when I try to download a file with Swagger 3.0 schema definition. The schema definition for a multipart file download which looks something like the below.
"get": {
"operationId": "getAttachment",
"summary": "Retrieve attachments to a existing Ticket",
"tags": [
"changeRequest"
],
"parameters": [
{
"required": true,
"name": "id",
"in": "path",
"description": "Identifier of the Change Request",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Ok",
"headers": {
},
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"metadata": {
"$ref": "#/components/schemas/Attachment"
},
"file": {
"type": "string",
"format":"binary",
"description": "Actual File Attachment"
}
}
}
}
}
}
}
}
It generates the following class when built using the swagger plugin which seems to be apt:
public class InlineResponse200 {
#JsonProperty("metadata")
private Attachment metadata = null;
#JsonProperty("file")
private Resource file;
Following is the implementation generated:
#ApiOperation(value = "Retrieve attachments to a existing Ticket", nickname = "getAttachment", notes
= "", response = InlineResponse200.class, tags={ "changeRequest", })
#RequestMapping(value = "/changeRequest/attachment/{id}",
produces = { "multipart/form-data", "application/json" },
method = RequestMethod.GET)
public ResponseEntity<InlineResponse200> getAttachment(#PathVariable("id") String id) {
Attachment lAttachmentMetadata = new Attachment();
lAttachmentMetadata.setDescription("This is a sample description");
lAttachmentMetadata.setSize(2000);
FileSystemResource fileSysResource = new FileSystemResource(new File("C:\\Projects\\Service Assurance\\Chnage Mgmt\\Attachments\\attachment.txt"));
InlineResponse200 responseObject = new InlineResponse200();
responseObject.setFile(fileSysResource);
responseObject.setMetadata(lAttachmentMetadata);
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + fileSysResource.getFilename() + "\"").header("Content-Type", "multipart/form-data").body(responseObject);
}
When I invoke the service I see a 406 error returned
Thu Oct 15 03:46:39 IST 2020:DEBUG:<< "{"timestamp":"2020-10-14T22:16:39.258Z","status":406,"error":"Not Acceptable","message":"Could not find acceptable representation","path":"/changeManagement/api/v1/changeRequest/attachment/1234"}"
SOAPUI REST SERVICE TEST
Any help or pointers in the right direction would be much appreciated.

CloudFront doesn't fetch from custom origin for root url using Lambda#Edge

I have a Lambda#Edge function that decides which origin to use on the origin request, depending on a header value.
It doesn't work for the root url (mysite.com), but it works for subroutes (mysite.com/sth/abc). I am looking for help while trying to figure out why it doesn't work for the root url.
It looks like this:
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const isBot = headers['formaviva-agent'] && headers['formaviva-agent'][0].value === 'bot';
console.log("request before" + JSON.stringify(request));
console.log("isBot:" + isBot);
const shouldPrerender = isBot;
if (shouldPrerender) {
request.origin = {
custom: {
domainName: 'fast.formaviva.com',
port: 80,
protocol: 'http',
path: '',
sslProtocols: ['TLSv1', 'TLSv1.1'],
readTimeout: 5,
keepaliveTimeout: 5,
customHeaders: {}
}
};
request.headers['host'] = [{ key: 'host', value: 'fast.formaviva.com'}];
console.log("request after" + JSON.stringify(request));
}
callback(null, request);
};
The default origin is S3 static page hosting. formaviva-agent is set in a Viewer Request Lambda function that checks whether User-Agent belongs to a bot.
Formaviva-agent is whitelisted.
Judging by the logs, all goes well, the bot is recognized and the origin gets changed to a custom origin:
2019-05-07T09:56:45.627Z 3a2831f4-2a6b-46ea-8850-d89651a9b19e request after
{
"clientIp": "92.37.21.9",
"headers": {
"if-modified-since": [
{
"key": "If-Modified-Since",
"value": "Mon, 06 May 2019 10:50:39 GMT"
}
],
"if-none-match": [
{
"key": "If-None-Match",
"value": "W/\"41cc-16a8cc45892\""
}
],
"user-agent": [
{
"key": "User-Agent",
"value": "Amazon CloudFront"
}
],
"via": [
{
"key": "Via",
"value": "1.1 b38e161751a953866db739b688c09996.cloudfront.net (CloudFront)"
}
],
"formaviva-agent": [
{
"key": "formaviva-agent",
"value": "bot"
}
],
"x-forwarded-for": [
{
"key": "X-Forwarded-For",
"value": "92.37.21.9"
}
],
"host": [
{
"key": "host",
"value": "fast.formaviva.com"
}
]
},
"method": "GET",
"origin": {
"custom": {
"domainName": "fast.formaviva.com",
"port": 80,
"protocol": "http",
"path": "",
"sslProtocols": [
"TLSv1",
"TLSv1.1"
],
"readTimeout": 5,
"keepaliveTimeout": 5,
"customHeaders": {}
}
},
"querystring": "",
"uri": "/index.html"
}
In this case, Cloudfront still serves the content from S3 origin. The custom origin server does not get hit (confirmed). Even though the custom origin is specified. Why?

Accessing VSTS service endpoints from javascript

I am trying to access the service endpoint setup in my extension code.
The extension is as follows:
{
"manifestVersion": 1,
"id": "vsts-extensions-myExtensions",
"version": "0.5.1",
"name": "xxx Projects Time Entry",
"description": "Record time spent in xxx Projects",
"publisher": "xxx",
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"icons": {
"default": "img/logo.png"
},
"contributions":
[
{
"id": "xxTimeEntry",
"type": "ms.vss-dashboards-web.widget",
...
},
{
"id": "service-endpoint",
"description": "Service Endpoint type for xx connections",
"type": "ms.vss-endpoint.service-endpoint-type",
"targets": [ "ms.vss-endpoint.endpoint-types" ],
"properties": {
"name": "xxxyyy",
"displayName": "xx server connection",
"url": {
"displayName": "Server Url",
"helpText": "Url for the xxx server to connect to."
},
"dataSources": [
{
"name": "xxx Projects",
"endpointUrl": "{{endpoint.url}}api/timesheetwidgetprojects",
"resultSelector": "jsonpath:$[*].nm"
}
],
"authenticationSchemes": [
{
"type": "ms.vss-endpoint.endpoint-auth-scheme-basic",
"inputDescriptors": [
{
"id": "username",
"name": "Username",
"description": "Username",
"inputMode": "textbox",
"validation": {
"isRequired": false,
"dataType": "string"
}
},
{
"id": "password",
"name": "Password",
"description": "Password",
"inputMode": "passwordbox",
"isConfidential": true,
"validation": {
"isRequired": false,
"dataType": "string"
}
}
]
}
]
}
}
],
...
The code to access the service endpoint is something like :
VSS.require(["VSS/Service", "VSS/WebApi/RestClient"],
function (VSS_Service, RestClient) {
var webContext = VSS.getWebContext();
var client = VSS_Service.getCollectionClient(DistributedTask.TaskAgentRestClient);
client.getServiceEndpoints(webContext.project.id).then(
function (endpoints) {
alert('endpoints')
}
);
}
);
however I am not using a task and just have my endpoint in the main vss-extension.json.
Any ideas?
Thanks
Martin
Based on the supported scopes, there isn’t the scope for service endpoint, so you can’t do it.
I submit a user voice here: VSTS extension service endpoint scope, you can vote and follow up.
The workaround is that you can call REST API by using JS code with Personal Access Token in your extension.
Simple code to call REST API:
$.ajax({
url: 'https://fabrikam.visualstudio.com/defaultcollection/_apis/projects?api-version=1.0',
dataType: 'json',
headers: {
'Authorization': 'Basic ' + btoa("" + ":" + myPatToken)
}
}).done(function( results ) {
console.log( results.value[0].id + " " + results.value[0].name );
});
The scope has been added now and it is "vso.serviceendpoint"

Resources