Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
{
  "session": {},
  "destinations": ],
  "locations": [
    {
      "location.enabled": true,
      "location.enabled": true,
      "enable.dynatrace": false,
      "plugin": {},
      "session.needed": false,
      "response.compress": true,
      "response.redirect": "https://%{HTTP_HOST}:8443%{PATH_WITH_QUERY}",
      "name": "Unsecured requests",
      "action": "respond",
      "description": "Redirect http to https",
      "conditions": [
        {
          "values": ["http"],
          "type": "scheme"
        },
        {
          "deny": true,
          "values": [
            "127.0.0.1",
            "localhost",
            "::1",
            "0:0:0:0:0:0:0:1"
          ],
          "type": "remoteip"
        }
      ],
      "response.status": 307,
      "cookiesnapper": {}
    },
    {
      "name": "OpenID Connect Google",
      "description": "OpenID Connect authorization code flow example using Google",
      "conditions": [{
        "deny": false,
        "values": ["/openid"],
        "type": "path"
      }],
      "authentication": {
        "plugins": ["io.ceptor.authentication.AuthenticatorOpenIDConnect"],
        "openidconnect": {
          "response.contenttype": "text/html",
          "identityprovider.name": "google",
          "authenticationplugin": 48,
          "redirecturl": "https://%{HTTP_HOST}/openid",
          "scope": "openid email profile",
          "authorize.url": "https://accounts.google.com/o/oauth2/auth",
          "response.status": 200,
          "response.content": "<html>\n<head><title>Success<\/title>\n<body>\n<h1>Success<\/h1>\nWelcome %{statevariable:email} - authentication succeeded using google.\n<\/body>\n<\/html>",
          "parameters": "access_type=online",
          "client.id": "371213948273-79eceu24cm64ft69pln0hk2lfapok1bq.apps.googleusercontent.com"
        }
      }
    },
    {
      "name": "OpenID Connect Microsoft",
      "description": "OpenID Connect authorization code flow example using Microsoft",
      "conditions": [{
        "deny": false,
        "values": ["/openidmicrosoft"],
        "type": "path"
      }],
      "authentication": {
        "plugins": ["io.ceptor.authentication.AuthenticatorOpenIDConnect"],
        "openidconnect": {
          "response.contenttype": "text/html",
          "identityprovider.name": "microsoft",
          "authenticationplugin": 48,
          "redirecturl": "https://%{HTTP_HOST}/openidmicrosoft",
          "scope": "openid email profile",
          "authorize.url": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
          "response.status": 200,
          "response.content": "<html>\n<head><title>Success<\/title>\n<body>\n<h1>Success<\/h1>\nWelcome %{REMOTE_USER} - authentication succeeded using Microsoft Online.\n<\/body>\n<\/html>",
          "client.id": "317190f9-efec-4307-beb9-7f8380a8ae16"
        }
      }
    },
    {
      "authorization": {
        "roles": [],
        "authorization.script": "state.agent.logoff(state.id);\ntrue;"
      },
      "response.contenttype": "text/html",
      "content.preload": false,
      "plugin": {},
      "session.needed": true,
      "session.afterconditionsmatch": false,
      "name": "Logoff",
      "description": "Logs off the session",
      "action": "respond",
      "conditions": [{
        "deny": false,
        "values": ["/logoff"],
        "type": "path"
      }],
      "response.status": 200,
      "response.content": "<html><body>You are now logged off.<\/body><\/html>",
      "cookiesnapper": {}
    },
    {
      "response.contenttype": "text/html",
      "plugin": {},
      "session.needed": true,
      "name": "WebSSO",
      "description": "WebSSO / ADFS Example",
      "action": "respond",
      "response.reason": "OK",
      "response.status": 200,
      "response.content": "<html>\n<body>Hello... %{REMOTE_USER}\n<\/body>\n<\/html>",
      "cookiesnapper": {},
      "conditions": [{
        "deny": false,
        "values": ["/adfs"],
        "type": "path"
      }],
      "authentication": {
        "websso": {
          "response.contenttype": "text/html",
          "identityprovider.name": "%{script}var name=state.getQueryOrPostParam(\"idpname\");\nif (name === null) name = 'microsoft';\nname;",
          "redirecturl": "%{REQUEST_URL}",
          "serviceprovider.name": "%{script}state.getQueryOrPostParam(\"spname\");",
          "failure": {
            "response.contenttype": "text/html",
            "action": "respond",
            "response.status": 403,
            "response.content": "<html><body>Authentication failed<p/>\nDetails:<\/br>\n<pre>\n%{htmlencode:EXCEPTION_LOG}\n<\/pre>\n<\/body><\/html>"
          },
          "response.status": 200,
          "response.content": "<html><body>Success %{REMOTE_USER}<\/body><\/html>",
          "federation.enabled": true
        },
        "plugins": ["io.ceptor.authentication.AuthenticatorWebSSO"]
      }
    },
    {
      "content.preload": false,
      "description": "Every single request",
      "request.concurrent.max": 0,
      "cookiesnapper": {
        "classifier": "%{HTTP_HOST}",
        "pattern": "JSESSIONID"
      },
      "request.queue.size": 10000,
      "valid.methods": "GET|POST|OPTIONS|HEAD",
      "noauthentication.for.options": false,
      "authorization": {
        "noauthorization.for.options": false,
        "roles": [],
        "server.identifier": "none"
      },
      "proxy.destination": "demoapp",
      "request.headers": [
        {
          "name": "X-Forwarded-Proto",
          "value": "%{HTTP_SCHEME}"
        },
        {
          "name": "X-Forwarded-For",
          "value": "%{REMOTE_ADDR}"
        },
        {
          "name": "X-Forwarded-Port",
          "value": "%{REMOTE_PORT}"
        },
        {
          "name": "X-Forwarded-Server",
          "value": "%{SERVER_NAME}"
        }
      ],
      "plugin": {"classifier": "%{HTTP_HOST}"},
      "request.persecond.max": 0,
      "response.maxbytes.persecond": 0,
      "urlrewrite": [{
        "newurl": "/secret/$1",
        "last": true,
        "pattern.flags": "CASE_INSENSITIVE",
        "decode.before.match": true,
        "name": "TOPSECRET to secret",
        "pattern": "^/TOPSECRET/(.*)",
        "redirect": false,
        "clear.query.params": false,
        "conditions": [{
          "deny": false,
          "values": [
            "localhost*",
            "{regex:IGNORE_CASE}LoCaLhOsT.*"
          ],
          "type": "host"
        }]
      }],
      "session.needed": false,
      "response.compress": true,
      "name": "All requests",
      "response.cookies": [{
        "path": "/stuff",
        "discard": false,
        "name": "IWasHere",
        "httponly": true,
		"samesite": lax,
        "secure": true,
        "value": "%{GEOIP_ISP}"
      }],
      "action": "continue",
      "response.headers": [
        {
          "name": "Via",
          "value": "ceptor.io"
        },
        {
          "name": "Server",
          "value": null
        },
        {
          "name": "Location",
          "value": "%{rewrite:responseheader:location;\"http\\:\\/\\/(.*)$\";\"CASE_INSENSITIVE\";\"https://$1\"}"
        }
      ],
      "conditions": [],
      "request.cookies": [
        {
          "name": "sessionid",
          "value": null
        },
        {
          "name": "sslsessionid",
          "value": null
        }
      ]
    },
    {
      "request.attributes": [{
        "name": "NotAGif",
        "value": "true"
      }],
      "plugin": {},
      "response.hooks": [
        {
          "expected.response.status": "404",
          "respond": true,
          "response.headers": [{
            "name": "X-Content",
            "value": "WasNotFound"
          }],
          "response.status": 404,
          "response.reason": "Sorry, not found",
          "response.contenttype": "text/plain",
          "response.content": "Oh no, I did not find that"
        },
        {
          "expected.response.status": "401",
          "respond": false,
          "response.status": 302,
          "response.redirect": "https://somewhere.else",
          "script": "%{script}// Example javascript that simply sends the response configured in the response hook\r\n\r\ncontext.gateway.sendResponse(context, context.currentResponseHook.response);"
        }
      ],
      "session.notvalid.action": "continue",
      "url.validator": {
        "verify.encoding": true,
        "verify.fullurl": true,
        "maxlength": 32768,
        "query.key.maxlength": 1024,
        "query.value.maxlength": 8192,
        "enabled": true,
        "authority.regex": null
      },
      "session.needed": false,
      "name": "All requests except jpg,png,gif,css",
      "action": "continue",
      "conditions": [
        {
          "values": ["*"],
          "type": "path"
        },
        {
          "deny": true,
          "values": ["*.jpg|*.png|*.gif|*.css"],
          "type": "path"
        }
      ],
      "param.validator": {
        "verify.pathparams": true,
        "verify.params": [{
          "value.lowercase": true,
          "key.lowercase": true,
          "value": "*abc*1",
          "key": "test*"
        }],
        "failure": {
          "response.contenttype": "text/html",
          "action": "respond",
          "response.headers": [],
          "response.reason": "Invalid parameter",
          "response.status": 400,
          "response.content": "<html><body><h1>Invalid parameter<\/h1><\/body><\/html>"
        },
        "verify.postparams": false,
        "verify.params.required": true,
        "verify.params.extra.allowed": true,
        "verify.queryparams": true
      },
      "cookiesnapper": {},
      "authentication": {
        "ntlm": {
          "authenticationplugin": 35,
          "failure": {
            "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}",
            "action": "respond",
            "response.reason": "Invalid userid/password",
            "response.status": 403,
            "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid userid/password<\/h1><\/body><\/html>';}"
          },
          "required": false,
          "allow.anonymous": true
        },
        "plugins": [
          "io.ceptor.authentication.AuthenticatorSSLClientCert",
          "io.ceptor.authentication.AuthenticatorBasicAuth"
        ],
        "spnego": {
          "authenticationplugin": 26,
          "failure": {
            "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}",
            "action": "respond",
            "response.reason": "Invalid userid/password",
            "response.status": 403,
            "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid userid/password<\/h1><\/body><\/html>';}"
          },
          "allow.ntlm.fallback": true
        },
        "basicauth": {
          "authenticationplugin": 9,
          "failure": {
            "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}",
            "action": "respond",
            "response.headers": [{
              "name": "WWW-Authenticate",
              "value": "Basic realm=\"ceptor.io\""
            }],
            "response.reason": "Invalid userid/password",
            "response.status": 401,
            "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid userid/password<\/h1><\/body><\/html>';}"
          },
          "realm": "ceptor.io",
          "required": false
        },
        "ssl": {
          "authenticationplugin": 18,
          "failure": {
            "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}",
            "action": "respond",
            "response.reason": "Invalid client cert",
            "response.status": 401,
            "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid client certificate<\/h1><\/body><\/html>';}"
          },
          "required": false
        }
      },
      "ip.restriction": {
        "ranges": [
          {
            "values": [
              "127.0.0.1-127.0.0.255",
              "::1"
            ],
            "name": "local"
          },
          {
            "values": ["192.168.1.0/24"],
            "name": "intranet"
          },
          {
            "values": ["{file}${portalprotect.home}/config/iprange1.txt"],
            "name": "range1"
          }
        ],
        "allowchange": true,
        "action.invalid": {
          "response.redirect": "/invalid?originalUrl=%{urlencode:REQUEST_URL}",
          "action": "respond",
          "response.reason": "Invalid IP",
          "response.status": 302
        },
        "ip.address.maxcount": 32,
        "geoip.type": "complex",
        "geoip.distance": 100,
        "geoip.complexrules": [
          "ip1=ip2",
          "country1=country2&country2=\"DK\"",
          "distance=300"
        ],
        "script": "if (input == '127.0.0.1') true; else false;"
      }
    },
    {
      "plugin": {
        "response.wrapper.script": "%{file}/responsedumper.js",
        "response.wrapper.class": "io.ceptor.gateway.plugin.ResponseDumper",
        "request.wrapper.class": "io.ceptor.gateway.plugin.RequestDumper",
        "XXXrequest.wrapper.script": "%{file}/requestdumper.js"
      },
      "session.needed": false,
      "name": "JSP response dumper",
      "conditions": [{
        "values": ["*.jsp"],
        "type": "path"
      }],
      "cookiesnapper": {}
    },
    {
      "proxy.destination": "google",
      "plugin": {},
      "urlrewrite": [{
        "newurl": "https://www.google.com/search?q=$1",
        "last": true,
        "decode.before.match": true,
        "name": "googl",
        "pattern": "^/search/(.*)$"
      }],
      "session.needed": false,
      "roles": ["pp_everyone"],
      "name": "Google",
      "action": "proxy",
      "conditions": [{
        "values": ["/search*"],
        "type": "path"
      }],
      "cookiesnapper": {}
    },
    {
      "authorization": {
        "failure": {
          "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}",
          "action": "respond",
          "response.reason": "No access",
          "response.status": 403,
          "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>403 No Access<\/h1><\/body><\/html>';}"
        },
        "roles": [
          "staff",
          "pp_identifiedusers"
        ],
        "server.identifier": "default"
      },
      "request.headers": [
        {
          "name": "authorization",
          "value": null
        },
        {
          "name": "x-user",
          "value": null
        },
        {
          "name": "x-forwarded-server",
          "value": null
        },
        {
          "name": "user-agent",
          "value": null
        },
        {
          "name": "Host",
          "value": "ekstrabladet.dk"
        },
        {
          "name": "Referer",
          "value": null
        }
      ],
      "name": "Secret Destination",
      "action": "continue",
      "locations": [
        {
          "proxy.destination": "ekstrabladet",
          "name": "EB",
          "action": "proxy",
          "conditions": [{
            "values": ["localhost*"],
            "type": "host"
          }]
        },
        {
          "proxy.destination": "google",
          "name": "Google",
          "action": "proxy",
          "conditions": []
        }
      ],
      "conditions": [
        {
          "ignorecase": true,
          "values": [
            "/secret/*",
            "/secret",
            "{regex}^/verysecret.*$"
          ],
          "type": "path"
        },
        {
          "values": ["*"],
          "type": "host"
        }
      ],
      "request.cookies": [{
        "name": "pp_jsessionid",
        "value": null
      }],
      "ip.restriction": {
        "ranges": [{
          "values": ["192.168.1.0/30"],
          "name": "Internal"
        }],
        "allowchange": false
      },
      "authentication": {
        "plugins": [
          "io.ceptor.authentication.AuthenticatorScript",
          "io.ceptor.authentication.AuthenticatorForms",
          "io.ceptor.authentication.AuthenticatorBasicAuth"
        ],
        "basicauth": {
          "realm": "ceptor",
          "required": false
        },
        "forms": {
          "redirect": {
            "response.redirect": "/login.jsp",
            "action": "respond"
          },
          "authenticationplugin": 9,
          "failure": {
            "response.contenttype": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') 'application/json'; else 'text/html';}",
            "action": "respond",
            "response.reason": "Invalid userid/password",
            "response.status": 403,
            "response.content": "%{script:if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'application/json') '{\"error\":\"access.denied\"\\}'; else '<html><head><title>No access<\/title><body><h1>Invalid userid/password<\/h1><\/body><\/html>';}"
          },
          "required": false
        },
        "script": {
          "content.preload": false,
          "authentication.script": "authenticate();\r\n\r\nfunction authenticate() {\r\n   // If already authenticated, just continue\r\n   if (state.agent.isLoggedOn(state.id))\r\n      return 'CONTINUE';\r\n      \r\n   try {\r\n        var user = state.httpExchange.getRequestHeaders().getFirst('X-User');\r\n        var pass = state.httpExchange.getRequestHeaders().getFirst('X-Password');\r\n        if (user === null) {\r\n            user = state.httpExchange.getQueryParameters().get('X-User').getFirst();\r\n        }\r\n        if (pass === null) {\r\n            pass = state.httpExchange.getQueryParameters().get('X-Password').getFirst();\r\n        }\r\n        \r\n        if (user === null || pass === null) {\r\n            // Ignore if user or password is not supplied - making this type of authentication optional\r\n            return 'CONTINUE';\r\n        } else {\r\n            state.trace.trace('About to logon from script with user: ' + user);\r\n            // 9 is authentication plugin type\r\n            state.agent.logon(state.id, 9, user, pass, null);\r\n            return 'SUCCESS';\r\n        }\r\n    } catch(err) {\r\n        state.gateway.sendAndLogError(state, 401, 'Authentication Required', err);\r\n        return 'RESPOND';\r\n    }\r\n}"
        }
      }
    },
    {
      "proxy.destination": "demoapp",
      "roles": ["pp_everyone"],
      "name": "Local",
      "action": "proxy",
      "conditions": [{
        "values": ["/*"],
        "type": "path"
      }],
      "request.cookies": [{
        "name": "ppSessionId",
        "value": "%{REQUEST_ID}"
      }]
    },
    {
      "response.contenttype": "text/html",
      "#description": "Deny access to everything, by default if no other rule is matching",
      "name": "Default",
      "action": "respond",
      "response.headers": [{
        "name": "X-Access",
        "value": "Denied"
      }],
      "response.reason": "No access",
      "conditions": [{
        "values": ["/*"],
        "type": "path"
      }],
      "response.status": 403,
      "response.content": "<html><head><title>No access<\/title><body><h1>403 No Access<\/h1><\/body><\/html>"
    }
  ],
  "gateway": {},
  "listen": []
}

...

It has many sections below it - note that they are marked with a blank circle if no values are defined for that particular section, and a cog if something is defined for this section. This makes it easy to see if you need to look at a particular session when going through the configuration to view the settings for a particular location.

Image RemovedImage Added

Location configuration

...

Default: true
JSON key: response.compress 

Enable Dynatrace support

If set, Dynatrace OneAgent SDK is called with information about both incoming and outgoing requests, and Dynatrace HTTP tracing header is added to all outgoing requests.

Note

This requires minimum version 6.5.0

Default: false
JSON key: enable.dynatrace 

Limits

Can be used to limit the number of concurrent requests, or requests per second for this location.

...