Skip to content

Commit

Permalink
configurable header names, documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
srose committed May 29, 2015
1 parent 7659b1a commit a6eface
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 77 deletions.
189 changes: 123 additions & 66 deletions docbook/reference/en/en-US/modules/proxy.xml
Expand Up @@ -182,106 +182,162 @@ $ java -jar bin/launcher.jar [your-config.json]
</section> </section>
<section> <section>
<title>Application Config</title> <title>Application Config</title>
<para> <para>
Next under the <literal>applications</literal> array attribute, you can define one or more applications per host you are proxying. Next under the <literal>applications</literal> array attribute, you can define one or more applications per host you are proxying.
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term>base-path</term> <term>base-path</term>
<listitem> <listitem>
<para> <para>
The base context root for the application. Must start with '/' <emphasis>REQUIRED.</emphasis>. The base context root for the application. Must start with '/' <emphasis>REQUIRED.</emphasis>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>error-page</term> <term>error-page</term>
<listitem> <listitem>
<para> <para>
If the proxy has an error, it will display the target application's error page relative URL <emphasis>OPTIONAL.</emphasis>. If the proxy has an error, it will display the target application's error page relative URL <emphasis>OPTIONAL.</emphasis>.
This is a relative path to the base-path. In the example above it would be <literal>/customer-portal/error.html</literal>. This is a relative path to the base-path. In the example above it would be <literal>/customer-portal/error.html</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>adapter-config</term> <term>adapter-config</term>
<listitem> <listitem>
<para> <para>
<emphasis>REQUIRED.</emphasis>. Same configuration as any other keycloak adapter. See <link linkend='adapter-config'>Adapter Config</link> <emphasis>REQUIRED.</emphasis>. Same configuration as any other keycloak adapter. See <link linkend='adapter-config'>Adapter Config</link>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</para> </para>
<section> <section>
<title>Constraint Config</title> <title>Constraint Config</title>

<para>
<para> Next under each application you can define one or more constraints in the <literal>constraints</literal> array attribute.
Next under each application you can define one or more constraints in the <literal>constraints</literal> array attribute. A constraint defines a URL pattern relative to the base-path. You can deny, permit, or require authentication for
A constraint defines a URL pattern relative to the base-path. You can deny, permit, or require authentication for a specific URL pattern. You can specify roles allowed for that path as well. More specific constraints will take
a specific URL pattern. You can specify roles allowed for that path as well. More specific constraints will take precedence over more general ones.
precedence over more general ones. <variablelist>
<varlistentry>
<term>pattern</term>
<listitem>
<para>
URL pattern to match relative to the base-path of the application. Must start with '/' <emphasis>REQUIRED.</emphasis>.
You may only have one wildcard and it must come at the end of the pattern. Valid <literal>/foo/bar/*</literal> and <literal>/foo/*.txt</literal>
Not valid: <literal>/*/foo/*</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>roles-allowed</term>
<listitem>
<para>
Array of strings of roles allowed to access this url pattern. <emphasis>OPTIONAL.</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>methods</term>
<listitem>
<para>
Array of strings of HTTP methods that will exclusively match this pattern and HTTP request. <emphasis>OPTIONAL.</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>excluded-methods</term>
<listitem>
<para>
Array of strings of HTTP methods that will be ignored when match this pattern. <emphasis>OPTIONAL.</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>deny</term>
<listitem>
<para>
Deny all access to this URL pattern. <emphasis>OPTIONAL.</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>permit</term>
<listitem>
<para>
Permit all access without requiring authentication or a role mapping. <emphasis>OPTIONAL.</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>permit-and-inject</term>
<listitem>
<para>
Permit all access, but inject the headers, if user is already authenticated.<emphasis>OPTIONAL.</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>authenticate</term>
<listitem>
<para>
Require authentication for this pattern, but no role mapping. <emphasis>OPTIONAL.</emphasis>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>
</section>
<section>
<title>Header Names Config</title>
<para>
Next under the list of applications you can override the defaults for the names of the header fields injected by the proxy (see Keycloak Identity Headers).
This mapping is optional.
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term>pattern</term> <term>keycloak-subject</term>
<listitem> <listitem>
<para> <para>
URL pattern to match relative to the base-path of the application. Must start with '/' <emphasis>REQUIRED.</emphasis>. e.g. MYAPP_USER_ID
You may only have one wildcard and it must come at the end of the pattern. Valid <literal>/foo/bar/*</literal> and <literal>/foo/*.txt</literal>
Not valid: <literal>/*/foo/*</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>roles-allowed</term> <term>kkeycloak-username</term>
<listitem> <listitem>
<para> <para>
Array of strings of roles allowed to access this url pattern. <emphasis>OPTIONAL.</emphasis>. e.g. MYAPP_USER_NAME
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>methods</term> <term>keycloak-email</term>
<listitem> <listitem>
<para> <para>
Array of strings of HTTP methods that will exclusively match this pattern and HTTP request. <emphasis>OPTIONAL.</emphasis>. e.g. MYAPP_USER_EMAIL
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>excluded-methods</term> <term>keycloak-name</term>
<listitem> <listitem>
<para> <para>
Array of strings of HTTP methods that will be ignored when match this pattern. <emphasis>OPTIONAL.</emphasis>. e.g. MYAPP_USER_ID
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>deny</term> <term>keycloak-access-token</term>
<listitem> <listitem>
<para> <para>
Deny all access to this URL pattern. <emphasis>OPTIONAL.</emphasis>. e.g. MYAPP_ACCESS_TOKEN
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>permit</term>
<listitem>
<para>
Permit all access without requiring authentication or a role mapping. <emphasis>OPTIONAL.</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>authenticate</term>
<listitem>
<para>
Require authentication for this pattern, but no role mapping. <emphasis>OPTIONAL.</emphasis>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</para> </para>
</section>
</section> </section>
</section> </section>
<section> <section>
Expand Down Expand Up @@ -333,6 +389,7 @@ $ java -jar bin/launcher.jar [your-config.json]
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
Header field names can be configured using a map of <term>header-names</term> in configuration file.
</para> </para>
</section> </section>
</chapter> </chapter>
Expand Up @@ -45,7 +45,7 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
} }


if (match != null) { if (match != null) {
if(SecurityInfo.EmptyRoleSemantic.INJECT_IF_AUTHENTICATED.equals(match.getEmptyRoleSemantic())) { if(SecurityInfo.EmptyRoleSemantic.PERMIT_AND_INJECT_IF_AUTHENTICATED.equals(match.getEmptyRoleSemantic())) {
authenticatedRequest(account, exchange); authenticatedRequest(account, exchange);
return; return;
} else { } else {
Expand Down
Expand Up @@ -49,7 +49,8 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
return; return;
} }


if (match.getRequiredRoles().isEmpty() && match.getEmptyRoleSemantic() == SecurityInfo.EmptyRoleSemantic.INJECT_IF_AUTHENTICATED) { if (match.getRequiredRoles().isEmpty()
&& match.getEmptyRoleSemantic() == SecurityInfo.EmptyRoleSemantic.PERMIT_AND_INJECT_IF_AUTHENTICATED) {


boolean successfulAuthenticatedMethodFound = isSuccessfulAuthenticatedMethodFound(exchange); boolean successfulAuthenticatedMethodFound = isSuccessfulAuthenticatedMethodFound(exchange);


Expand Down
Expand Up @@ -219,8 +219,8 @@ public static class Constraint {
protected boolean permit; protected boolean permit;
@JsonProperty("authenticate") @JsonProperty("authenticate")
protected boolean authenticate; protected boolean authenticate;
@JsonProperty("inject-if-authenticated") @JsonProperty("permit-and-inject")
protected boolean injectIfAuthenticated; protected boolean permitAndInject;


public String getPattern() { public String getPattern() {
return pattern; return pattern;
Expand Down Expand Up @@ -262,12 +262,12 @@ public void setAuthenticate(boolean authenticate) {
this.authenticate = authenticate; this.authenticate = authenticate;
} }


public boolean isInjectIfAuthenticated() { public boolean isPermitAndInject() {
return injectIfAuthenticated; return permitAndInject;
} }


public void setInjectIfAuthenticated(boolean injectIfAuthenticated) { public void setPermitAndInject(boolean permitAndInject) {
this.injectIfAuthenticated = injectIfAuthenticated; this.permitAndInject = permitAndInject;
} }


public Set<String> getMethods() { public Set<String> getMethods() {
Expand Down
Expand Up @@ -175,7 +175,7 @@ public ConstraintBuilder authenticate() {
} }


public ConstraintBuilder injectIfAuthenticated() { public ConstraintBuilder injectIfAuthenticated() {
semantic = SecurityInfo.EmptyRoleSemantic.INJECT_IF_AUTHENTICATED; semantic = SecurityInfo.EmptyRoleSemantic.PERMIT_AND_INJECT_IF_AUTHENTICATED;
return this; return this;
} }


Expand Down Expand Up @@ -383,7 +383,7 @@ public static Undertow build(ProxyConfig config) {
if (constraint.isDeny()) constraintBuilder.deny(); if (constraint.isDeny()) constraintBuilder.deny();
if (constraint.isPermit()) constraintBuilder.permit(); if (constraint.isPermit()) constraintBuilder.permit();
if (constraint.isAuthenticate()) constraintBuilder.authenticate(); if (constraint.isAuthenticate()) constraintBuilder.authenticate();
if (constraint.isInjectIfAuthenticated()) constraintBuilder.injectIfAuthenticated(); if (constraint.isPermitAndInject()) constraintBuilder.injectIfAuthenticated();
constraintBuilder.add(); constraintBuilder.add();
} }
} }
Expand Down
Expand Up @@ -51,7 +51,7 @@ public enum EmptyRoleSemantic {
/** /**
* Permit access in any case, but provide authorization info only if authorized. * Permit access in any case, but provide authorization info only if authorized.
*/ */
INJECT_IF_AUTHENTICATED; PERMIT_AND_INJECT_IF_AUTHENTICATED;
} }


private volatile EmptyRoleSemantic emptyRoleSemantic = EmptyRoleSemantic.DENY; private volatile EmptyRoleSemantic emptyRoleSemantic = EmptyRoleSemantic.DENY;
Expand Down

0 comments on commit a6eface

Please sign in to comment.