diff --git a/Ocelot.sln b/Ocelot.sln index d88020d3..9a34aed2 100644 --- a/Ocelot.sln +++ b/Ocelot.sln @@ -18,6 +18,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution GitVersion.yml = GitVersion.yml global.json = global.json LICENSE.md = LICENSE.md + ocelot.postman_collection.json = ocelot.postman_collection.json README.md = README.md release.ps1 = release.ps1 ReleaseNotes.md = ReleaseNotes.md diff --git a/README.md b/README.md index 7f9a410d..d72f6b01 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,45 @@ This means that when Ocelot tries to match the incoming upstream url with an ups evaluation will be case sensitive. This setting defaults to false so only set it if you want the ReRoute to be case sensitive is my advice! +## Administration + +Ocelot supports changing configuration during runtime via an authenticated HTTP API. The API is authenticated +using bearer tokens that you request from iteself. This is provided by the amazing [IdentityServer](https://github.com/IdentityServer/IdentityServer4) +project that I have been using for a few years now. Check them out. + +In order to enable the administration section you need to do a few things. First of all add this to your +initial configuration.json. The value can be anything you want and it is obviously reccomended don't use +a url you would like to route through with Ocelot as this will not work. The administration uses the +MapWhen functionality of asp.net core and all requests to root/administration will be sent there not +to the Ocelot middleware. + + "GlobalConfiguration": { + "AdministrationPath": "/administration" + } + +This will get the admin area set up but not the authentication. Please note that this is a very basic approach to +this problem and if needed we can obviously improve on this! + +You need to set 3 environmental variables. + + OCELOT_USERNAME + OCELOT_HASH + OCELOT_SALT + +These need to be the admin username you want to use with Ocelot and the hash and salt of the password you want to +use given hashing algorythm. When requesting bearer tokens for use with the administration api you will need to +supply username and password. + +In order to create a hash and salt of your password please check out HashCreationTests.should_create_hash_and_salt() +this technique is based on [this](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/consumer-apis/password-hashing) +using SHA256 rather than SHA1. + +Now if you went with the configuration options above and want to access the API you can use the postman scripts +called ocelot.postman_collection.json in the solution to change the Ocelot configuration. Obviously these +will need to be changed if you are running Ocelot on a different url to http://localhost:5000. + +The scripts show you how to request a bearer token from ocelot and then use it to GET the existing configuration and POST +a configuration. ## Service Discovery @@ -388,43 +427,6 @@ In orde to use caching on a route in your ReRoute configuration add this setting In this example ttl seconds is set to 15 which means the cache will expire after 15 seconds. -## Administration - -Ocelot supports changing configuration during runtime via an authenticated HTTP API. The API is authenticated -using bearer tokens that you request from iteself. This is provided by the amazing [IdentityServer](https://github.com/IdentityServer/IdentityServer4) -project that I have been using for a few years now. Check them out. - -In order to enable the administration section you need to do a few things. First of all add this to your -initial configuration.json. The value can be anything you want and it is obviously reccomended don't use -a url you would like to route through with Ocelot as this will not work. The administration uses the -MapWhen functionality of asp.net core and all requests to root/administration will be sent there not -to the Ocelot middleware. - - "GlobalConfiguration": { - "AdministrationPath": "/administration" - } - -This will get the admin area set up but not the authentication. You need to set 3 environmental variables. - - OCELOT_USERNAME - OCELOT_HASH - OCELOT_SALT - -These need to be the admin username you want to use with Ocelot and the hash and salt of the password you want to -use given hashing algorythm. When requesting bearer tokens for use with the administration api you will need to -supply username and password. - -In order to create a hash and salt of your password please check out HashCreationTests.should_create_hash_and_salt() -this technique is based on [this](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/consumer-apis/password-hashing) -using SHA256 rather than SHA1. - -Now if you went with the configuration options above and want to access the API you can make the following requests. - - - - - - ## Ocelot Middleware injection and overrides Warning use with caution. If you are seeing any exceptions or strange behavior in your middleware diff --git a/ocelot.postman_collection.json b/ocelot.postman_collection.json new file mode 100644 index 00000000..1da66b38 --- /dev/null +++ b/ocelot.postman_collection.json @@ -0,0 +1,117 @@ +{ + "id": "23a49657-e24b-b967-7ec0-943ff1368680", + "name": "Ocelot Admin", + "description": "", + "order": [ + "59162efa-27ce-c230-f523-81d31ead603d", + "e0defe09-c1b2-9e95-8237-67df4bbab284", + "30007c41-565c-5b87-ea34-42170dd386d7" + ], + "folders": [], + "timestamp": 1488042899799, + "owner": "212120", + "public": false, + "requests": [ + { + "id": "30007c41-565c-5b87-ea34-42170dd386d7", + "headers": "Authorization: Bearer {{AccessToken}}\n", + "url": "http://localhost:5000/admin/configuration", + "preRequestScript": null, + "pathVariables": {}, + "method": "GET", + "data": null, + "dataMode": "params", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": "{}", + "time": 1487515927978, + "name": "POST http://localhost:5000/admin/configuration", + "description": "", + "collectionId": "23a49657-e24b-b967-7ec0-943ff1368680", + "responses": [], + "isFromCollection": true, + "collectionRequestId": "59162efa-27ce-c230-f523-81d31ead603d" + }, + { + "id": "59162efa-27ce-c230-f523-81d31ead603d", + "headers": "Authorization: Bearer {{AccessToken}}\nContent-Type: application/json\n", + "url": "http://localhost:5000/admin/configuration", + "preRequestScript": null, + "pathVariables": {}, + "method": "POST", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1488044268493, + "name": "GET http://localhost:5000/admin/configuration", + "description": "", + "collectionId": "23a49657-e24b-b967-7ec0-943ff1368680", + "responses": [], + "rawModeData": "{\n \"reRoutes\": [\n {\n \"downstreamPathTemplate\": \"/\",\n \"upstreamPathTemplate\": \"/identityserverexample\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": \"IdentityServer\",\n \"providerRootUrl\": \"http://localhost:52888\",\n \"scopeName\": \"api\",\n \"requireHttps\": false,\n \"additionalScopes\": [\n \"openid\",\n \"offline_access\"\n ],\n \"scopeSecret\": \"secret\"\n },\n \"addHeadersToRequest\": {\n \"CustomerId\": \"Claims[CustomerId] > value\",\n \"LocationId\": \"Claims[LocationId] > value\",\n \"UserId\": \"Claims[sub] > value[1] > |\",\n \"UserType\": \"Claims[sub] > value[0] > |\"\n },\n \"addClaimsToRequest\": {\n \"CustomerId\": \"Claims[CustomerId] > value\",\n \"LocationId\": \"Claims[LocationId] > value\",\n \"UserId\": \"Claims[sub] > value[1] > |\",\n \"UserType\": \"Claims[sub] > value[0] > |\"\n },\n \"routeClaimsRequirement\": {\n \"UserType\": \"registered\"\n },\n \"addQueriesToRequest\": {\n \"CustomerId\": \"Claims[CustomerId] > value\",\n \"LocationId\": \"Claims[LocationId] > value\",\n \"UserId\": \"Claims[sub] > value[1] > |\",\n \"UserType\": \"Claims[sub] > value[0] > |\"\n },\n \"requestIdKey\": \"OcRequestId\",\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"localhost\",\n \"downstreamPort\": 52876,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/\",\n \"upstreamPathTemplate\": \"/posts\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"www.bbc.co.uk\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/posts/{postId}\",\n \"upstreamPathTemplate\": \"/posts/{postId}\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/posts/{postId}/comments\",\n \"upstreamPathTemplate\": \"/posts/{postId}/comments\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/comments\",\n \"upstreamPathTemplate\": \"/comments\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/posts\",\n \"upstreamPathTemplate\": \"/posts\",\n \"upstreamHttpMethod\": \"Post\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/posts/{postId}\",\n \"upstreamPathTemplate\": \"/posts/{postId}\",\n \"upstreamHttpMethod\": \"Put\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/posts/{postId}\",\n \"upstreamPathTemplate\": \"/posts/{postId}\",\n \"upstreamHttpMethod\": \"Patch\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/posts/{postId}\",\n \"upstreamPathTemplate\": \"/posts/{postId}\",\n \"upstreamHttpMethod\": \"Delete\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/products\",\n \"upstreamPathTemplate\": \"/products\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/products/{productId}\",\n \"upstreamPathTemplate\": \"/products/{productId}\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 0,\n \"durationOfBreak\": 0,\n \"timeoutValue\": 0\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/products\",\n \"upstreamPathTemplate\": \"/products\",\n \"upstreamHttpMethod\": \"Post\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 0\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"products20161126090340.azurewebsites.net\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/products/{productId}\",\n \"upstreamPathTemplate\": \"/products/{productId}\",\n \"upstreamHttpMethod\": \"Put\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"products20161126090340.azurewebsites.net\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/products/{productId}\",\n \"upstreamPathTemplate\": \"/products/{productId}\",\n \"upstreamHttpMethod\": \"Delete\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"products20161126090340.azurewebsites.net\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/customers\",\n \"upstreamPathTemplate\": \"/customers\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"customers20161126090811.azurewebsites.net\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/customers/{customerId}\",\n \"upstreamPathTemplate\": \"/customers/{customerId}\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"customers20161126090811.azurewebsites.net\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/customers\",\n \"upstreamPathTemplate\": \"/customers\",\n \"upstreamHttpMethod\": \"Post\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"customers20161126090811.azurewebsites.net\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/customers/{customerId}\",\n \"upstreamPathTemplate\": \"/customers/{customerId}\",\n \"upstreamHttpMethod\": \"Put\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"customers20161126090811.azurewebsites.net\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/api/customers/{customerId}\",\n \"upstreamPathTemplate\": \"/customers/{customerId}\",\n \"upstreamHttpMethod\": \"Delete\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"customers20161126090811.azurewebsites.net\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n },\n {\n \"downstreamPathTemplate\": \"/posts\",\n \"upstreamPathTemplate\": \"/posts/\",\n \"upstreamHttpMethod\": \"Get\",\n \"authenticationOptions\": {\n \"provider\": null,\n \"providerRootUrl\": null,\n \"scopeName\": null,\n \"requireHttps\": false,\n \"additionalScopes\": [],\n \"scopeSecret\": null\n },\n \"addHeadersToRequest\": {},\n \"addClaimsToRequest\": {},\n \"routeClaimsRequirement\": {},\n \"addQueriesToRequest\": {},\n \"requestIdKey\": null,\n \"fileCacheOptions\": {\n \"ttlSeconds\": 15\n },\n \"reRouteIsCaseSensitive\": false,\n \"serviceName\": null,\n \"downstreamScheme\": \"http\",\n \"downstreamHost\": \"jsonplaceholder.typicode.com\",\n \"downstreamPort\": 80,\n \"qoSOptions\": {\n \"exceptionsAllowedBeforeBreaking\": 3,\n \"durationOfBreak\": 10,\n \"timeoutValue\": 5000\n },\n \"loadBalancer\": null\n }\n ],\n \"globalConfiguration\": {\n \"requestIdKey\": \"OcRequestId\",\n \"serviceDiscoveryProvider\": {\n \"provider\": null,\n \"host\": null,\n \"port\": 0\n },\n \"administrationPath\": \"/admin\"\n }\n}" + }, + { + "id": "e0defe09-c1b2-9e95-8237-67df4bbab284", + "headers": "", + "url": "http://localhost:5000/admin/connect/token", + "preRequestScript": null, + "pathVariables": {}, + "method": "POST", + "data": [ + { + "key": "client_id", + "value": "admin", + "type": "text", + "enabled": true + }, + { + "key": "client_secret", + "value": "secret", + "type": "text", + "enabled": true + }, + { + "key": "scope", + "value": "admin", + "type": "text", + "enabled": true + }, + { + "key": "username", + "value": "admin", + "type": "text", + "enabled": true + }, + { + "key": "password", + "value": "secret", + "type": "text", + "enabled": true + }, + { + "key": "grant_type", + "value": "password", + "type": "text", + "enabled": true + } + ], + "dataMode": "params", + "version": 2, + "tests": "var jsonData = JSON.parse(responseBody);\npostman.setGlobalVariable(\"AccessToken\", jsonData.access_token);\npostman.setGlobalVariable(\"RefreshToken\", jsonData.refresh_token);", + "currentHelper": "normal", + "helperAttributes": "{}", + "time": 1487515922748, + "name": "POST http://localhost:5000/admin/connect/token", + "description": "", + "collectionId": "23a49657-e24b-b967-7ec0-943ff1368680", + "responses": [], + "rawModeData": null, + "descriptionFormat": null, + "isFromCollection": true, + "collectionRequestId": "e23e29a1-6abb-abd3-141a-f2202e3f582b" + } + ] +} \ No newline at end of file