Merge pull request #1298 from AOEpeople/KEYCLOAK-1103
KEYCLOAK-1103 proxy configuration for inject header if user is logged in, but do not enforce login
This commit is contained in:
commit
5680be743c
6 changed files with 248 additions and 93 deletions
|
@ -182,106 +182,162 @@ $ java -jar bin/launcher.jar [your-config.json]
|
|||
</section>
|
||||
<section>
|
||||
<title>Application Config</title>
|
||||
<para>
|
||||
Next under the <literal>applications</literal> array attribute, you can define one or more applications per host you are proxying.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>base-path</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The base context root for the application. Must start with '/' <emphasis>REQUIRED.</emphasis>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>error-page</term>
|
||||
<listitem>
|
||||
<para>
|
||||
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>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>adapter-config</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis>REQUIRED.</emphasis>. Same configuration as any other keycloak adapter. See <link linkend='adapter-config'>Adapter Config</link>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<para>
|
||||
Next under the <literal>applications</literal> array attribute, you can define one or more applications per host you are proxying.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>base-path</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The base context root for the application. Must start with '/' <emphasis>REQUIRED.</emphasis>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>error-page</term>
|
||||
<listitem>
|
||||
<para>
|
||||
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>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>adapter-config</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis>REQUIRED.</emphasis>. Same configuration as any other keycloak adapter. See <link linkend='adapter-config'>Adapter Config</link>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<section>
|
||||
<title>Constraint Config</title>
|
||||
|
||||
<para>
|
||||
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 specific URL pattern. You can specify roles allowed for that path as well. More specific constraints will take
|
||||
precedence over more general ones.
|
||||
<para>
|
||||
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 specific URL pattern. You can specify roles allowed for that path as well. More specific constraints will take
|
||||
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>
|
||||
<varlistentry>
|
||||
<term>pattern</term>
|
||||
<term>keycloak-subject</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>.
|
||||
e.g. MYAPP_USER_ID
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>roles-allowed</term>
|
||||
<term>keycloak-username</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Array of strings of roles allowed to access this url pattern. <emphasis>OPTIONAL.</emphasis>.
|
||||
e.g. MYAPP_USER_NAME
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>methods</term>
|
||||
<term>keycloak-email</term>
|
||||
<listitem>
|
||||
<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>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>excluded-methods</term>
|
||||
<term>keycloak-name</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Array of strings of HTTP methods that will be ignored when match this pattern. <emphasis>OPTIONAL.</emphasis>.
|
||||
e.g. MYAPP_USER_ID
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>deny</term>
|
||||
<term>keycloak-access-token</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>authenticate</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Require authentication for this pattern, but no role mapping. <emphasis>OPTIONAL.</emphasis>.
|
||||
e.g. MYAPP_ACCESS_TOKEN
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</section>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
|
@ -333,6 +389,14 @@ $ java -jar bin/launcher.jar [your-config.json]
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
Header field names can be configured using a map of <literal>header-names</literal> in configuration file:
|
||||
<programlisting><![CDATA[
|
||||
{
|
||||
"header-names" {
|
||||
"keycloak-subject": "MY_SUBJECT"
|
||||
}
|
||||
}
|
||||
]]></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
|
@ -6,43 +6,68 @@ import io.undertow.util.HttpString;
|
|||
import org.keycloak.adapters.undertow.KeycloakUndertowAccount;
|
||||
import org.keycloak.representations.IDToken;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ConstraintAuthorizationHandler implements HttpHandler {
|
||||
public static final HttpString KEYCLOAK_SUBJECT = new HttpString("KEYCLOAK-SUBJECT");
|
||||
public static final HttpString KEYCLOAK_USERNAME = new HttpString("KEYCLOAK-USERNAME");
|
||||
public static final HttpString KEYCLOAK_EMAIL = new HttpString("KEYCLOAK-EMAIL");
|
||||
public static final HttpString KEYCLOAK_NAME = new HttpString("KEYCLOAK-NAME");
|
||||
public static final HttpString KEYCLOAK_ACCESS_TOKEN = new HttpString("KEYCLOAK-ACCESS-TOKEN");
|
||||
|
||||
public static final String KEYCLOAK_SUBJECT = "KEYCLOAK_SUBJECT";
|
||||
public static final String KEYCLOAK_USERNAME = "KEYCLOAK_USERNAME";
|
||||
public static final String KEYCLOAK_EMAIL = "KEYCLOAK_EMAIL";
|
||||
public static final String KEYCLOAK_NAME = "KEYCLOAK_NAME";
|
||||
public static final String KEYCLOAK_ACCESS_TOKEN = "KEYCLOAK_ACCESS_TOKEN";
|
||||
private final Map<String, HttpString> httpHeaderNames;
|
||||
|
||||
protected HttpHandler next;
|
||||
protected String errorPage;
|
||||
protected boolean sendAccessToken;
|
||||
|
||||
public ConstraintAuthorizationHandler(HttpHandler next, String errorPage, boolean sendAccessToken) {
|
||||
public ConstraintAuthorizationHandler(HttpHandler next, String errorPage, boolean sendAccessToken, Map<String, String> headerNames) {
|
||||
this.next = next;
|
||||
this.errorPage = errorPage;
|
||||
this.sendAccessToken = sendAccessToken;
|
||||
|
||||
this.httpHeaderNames = new HashMap<>();
|
||||
this.httpHeaderNames.put(KEYCLOAK_SUBJECT, new HttpString(getOrDefault(headerNames, "keycloak-subject", KEYCLOAK_SUBJECT)));
|
||||
this.httpHeaderNames.put(KEYCLOAK_SUBJECT, new HttpString(getOrDefault(headerNames, "keycloak-username", KEYCLOAK_USERNAME)));
|
||||
this.httpHeaderNames.put(KEYCLOAK_EMAIL, new HttpString(getOrDefault(headerNames, "keycloak-email", KEYCLOAK_EMAIL)));
|
||||
this.httpHeaderNames.put(KEYCLOAK_NAME, new HttpString(getOrDefault(headerNames, "keycloak-name", KEYCLOAK_NAME)));
|
||||
this.httpHeaderNames.put(KEYCLOAK_ACCESS_TOKEN, new HttpString(getOrDefault(headerNames, "keycloak-access-token", KEYCLOAK_ACCESS_TOKEN)));
|
||||
}
|
||||
|
||||
private String getOrDefault(Map<String, String> map, String key, String defaultValue) {
|
||||
return map.containsKey(key) ? map.get(key) : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
||||
|
||||
KeycloakUndertowAccount account = (KeycloakUndertowAccount)exchange.getSecurityContext().getAuthenticatedAccount();
|
||||
|
||||
SingleConstraintMatch match = exchange.getAttachment(ConstraintMatcherHandler.CONSTRAINT_KEY);
|
||||
if (match == null || (match.getRequiredRoles().isEmpty() && match.getEmptyRoleSemantic() == SecurityInfo.EmptyRoleSemantic.AUTHENTICATE)) {
|
||||
authenticatedRequest(account, exchange);
|
||||
return;
|
||||
}
|
||||
|
||||
if (match != null) {
|
||||
for (String role : match.getRequiredRoles()) {
|
||||
if (account.getRoles().contains(role)) {
|
||||
authenticatedRequest(account, exchange);
|
||||
return;
|
||||
if(SecurityInfo.EmptyRoleSemantic.PERMIT_AND_INJECT_IF_AUTHENTICATED.equals(match.getEmptyRoleSemantic())) {
|
||||
authenticatedRequest(account, exchange);
|
||||
return;
|
||||
} else {
|
||||
for (String role : match.getRequiredRoles()) {
|
||||
if (account.getRoles().contains(role)) {
|
||||
authenticatedRequest(account, exchange);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errorPage != null) {
|
||||
exchange.setRequestPath(errorPage);
|
||||
exchange.setRelativePath(errorPage);
|
||||
|
@ -61,20 +86,20 @@ public class ConstraintAuthorizationHandler implements HttpHandler {
|
|||
IDToken idToken = account.getKeycloakSecurityContext().getToken();
|
||||
if (idToken == null) return;
|
||||
if (idToken.getSubject() != null) {
|
||||
exchange.getRequestHeaders().put(KEYCLOAK_SUBJECT, idToken.getSubject());
|
||||
exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_SUBJECT), idToken.getSubject());
|
||||
}
|
||||
|
||||
if (idToken.getPreferredUsername() != null) {
|
||||
exchange.getRequestHeaders().put(KEYCLOAK_USERNAME, idToken.getPreferredUsername());
|
||||
exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_USERNAME), idToken.getPreferredUsername());
|
||||
}
|
||||
if (idToken.getEmail() != null) {
|
||||
exchange.getRequestHeaders().put(KEYCLOAK_EMAIL, idToken.getEmail());
|
||||
exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_EMAIL), idToken.getEmail());
|
||||
}
|
||||
if (idToken.getName() != null) {
|
||||
exchange.getRequestHeaders().put(KEYCLOAK_NAME, idToken.getName());
|
||||
exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_NAME), idToken.getName());
|
||||
}
|
||||
if (sendAccessToken) {
|
||||
exchange.getRequestHeaders().put(KEYCLOAK_ACCESS_TOKEN, account.getKeycloakSecurityContext().getTokenString());
|
||||
exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_ACCESS_TOKEN), account.getKeycloakSecurityContext().getTokenString());
|
||||
}
|
||||
}
|
||||
next.handleRequest(exchange);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package org.keycloak.proxy;
|
||||
|
||||
import io.undertow.security.handlers.AuthenticationConstraintHandler;
|
||||
import io.undertow.security.api.AuthenticationMechanism;
|
||||
import io.undertow.server.HttpHandler;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.util.AttachmentKey;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -47,10 +48,42 @@ public class ConstraintMatcherHandler implements HttpHandler {
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (match.getRequiredRoles().isEmpty()
|
||||
&& match.getEmptyRoleSemantic() == SecurityInfo.EmptyRoleSemantic.PERMIT_AND_INJECT_IF_AUTHENTICATED) {
|
||||
|
||||
boolean successfulAuthenticatedMethodFound = isSuccessfulAuthenticatedMethodFound(exchange);
|
||||
|
||||
if(successfulAuthenticatedMethodFound) {
|
||||
//in case of authenticated we go for injecting headers
|
||||
exchange.putAttachment(CONSTRAINT_KEY, match);
|
||||
securedHandler.handleRequest(exchange);
|
||||
return;
|
||||
} else {
|
||||
//in case of not authenticated we just show the resource
|
||||
unsecuredHandler.handleRequest(exchange);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("found constraint");
|
||||
exchange.getSecurityContext().setAuthenticationRequired();
|
||||
exchange.putAttachment(CONSTRAINT_KEY, match);
|
||||
securedHandler.handleRequest(exchange);
|
||||
|
||||
}
|
||||
|
||||
private boolean isSuccessfulAuthenticatedMethodFound(HttpServerExchange exchange) {
|
||||
boolean successfulAuthenticatedMethodFound = false;
|
||||
List<AuthenticationMechanism> authenticationMechanisms = exchange.getSecurityContext().getAuthenticationMechanisms();
|
||||
|
||||
for (AuthenticationMechanism authenticationMechanism : authenticationMechanisms) {
|
||||
AuthenticationMechanism.AuthenticationMechanismOutcome authenticationMechanismOutcome =
|
||||
authenticationMechanism.authenticate(exchange, exchange.getSecurityContext());
|
||||
if(authenticationMechanismOutcome.equals(AuthenticationMechanism.AuthenticationMechanismOutcome.AUTHENTICATED)) {
|
||||
successfulAuthenticatedMethodFound = true;
|
||||
}
|
||||
}
|
||||
return successfulAuthenticatedMethodFound;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,7 @@ package org.keycloak.proxy;
|
|||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -41,6 +38,8 @@ public class ProxyConfig {
|
|||
protected boolean sendAccessToken;
|
||||
@JsonProperty("applications")
|
||||
protected List<Application> applications = new LinkedList<Application>();
|
||||
@JsonProperty("header-names")
|
||||
private Map<String,String> headerNames = new HashMap<>();
|
||||
|
||||
public String getBindAddress() {
|
||||
return bindAddress;
|
||||
|
@ -154,6 +153,14 @@ public class ProxyConfig {
|
|||
this.sendAccessToken = sendAccessToken;
|
||||
}
|
||||
|
||||
public void setHeaderNames(Map<String, String> headerNames) {
|
||||
this.headerNames = headerNames;
|
||||
}
|
||||
|
||||
public Map<String, String> getHeaderNames() {
|
||||
return headerNames;
|
||||
}
|
||||
|
||||
public static class Application {
|
||||
@JsonProperty("base-path")
|
||||
protected String basePath;
|
||||
|
@ -212,6 +219,8 @@ public class ProxyConfig {
|
|||
protected boolean permit;
|
||||
@JsonProperty("authenticate")
|
||||
protected boolean authenticate;
|
||||
@JsonProperty("permit-and-inject")
|
||||
protected boolean permitAndInject;
|
||||
|
||||
public String getPattern() {
|
||||
return pattern;
|
||||
|
@ -253,6 +262,14 @@ public class ProxyConfig {
|
|||
this.authenticate = authenticate;
|
||||
}
|
||||
|
||||
public boolean isPermitAndInject() {
|
||||
return permitAndInject;
|
||||
}
|
||||
|
||||
public void setPermitAndInject(boolean permitAndInject) {
|
||||
this.permitAndInject = permitAndInject;
|
||||
}
|
||||
|
||||
public Set<String> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
|
|
@ -51,10 +51,7 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -76,6 +73,8 @@ public class ProxyServerBuilder {
|
|||
protected HttpHandler proxyHandler;
|
||||
protected boolean sendAccessToken;
|
||||
|
||||
protected Map<String, String> headerNameConfig;
|
||||
|
||||
public ProxyServerBuilder target(String uri) {
|
||||
SimpleProxyClientProvider provider = null;
|
||||
try {
|
||||
|
@ -98,6 +97,12 @@ public class ProxyServerBuilder {
|
|||
this.sendAccessToken = flag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProxyServerBuilder headerNameConfig(Map<String, String> headerNameConfig) {
|
||||
this.headerNameConfig = headerNameConfig;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ApplicationBuilder application(AdapterConfig config) {
|
||||
return new ApplicationBuilder(config);
|
||||
}
|
||||
|
@ -169,6 +174,11 @@ public class ProxyServerBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ConstraintBuilder injectIfAuthenticated() {
|
||||
semantic = SecurityInfo.EmptyRoleSemantic.PERMIT_AND_INJECT_IF_AUTHENTICATED;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConstraintBuilder excludedMethods(Set<String> excludedMethods) {
|
||||
this.excludedMethods = excludedMethods;
|
||||
return this;
|
||||
|
@ -222,7 +232,7 @@ public class ProxyServerBuilder {
|
|||
errorPage = base + "/" + errorPage;
|
||||
}
|
||||
}
|
||||
handler = new ConstraintAuthorizationHandler(handler, errorPage, sendAccessToken);
|
||||
handler = new ConstraintAuthorizationHandler(handler, errorPage, sendAccessToken, headerNameConfig);
|
||||
handler = new ProxyAuthenticationCallHandler(handler);
|
||||
handler = new ConstraintMatcherHandler(matches, handler, toWrap, errorPage);
|
||||
final List<AuthenticationMechanism> mechanisms = new LinkedList<AuthenticationMechanism>();
|
||||
|
@ -373,6 +383,7 @@ public class ProxyServerBuilder {
|
|||
if (constraint.isDeny()) constraintBuilder.deny();
|
||||
if (constraint.isPermit()) constraintBuilder.permit();
|
||||
if (constraint.isAuthenticate()) constraintBuilder.authenticate();
|
||||
if (constraint.isPermitAndInject()) constraintBuilder.injectIfAuthenticated();
|
||||
constraintBuilder.add();
|
||||
}
|
||||
}
|
||||
|
@ -383,6 +394,7 @@ public class ProxyServerBuilder {
|
|||
|
||||
public static void initOptions(ProxyConfig config, ProxyServerBuilder builder) {
|
||||
builder.sendAccessToken(config.isSendAccessToken());
|
||||
builder.headerNameConfig(config.getHeaderNames());
|
||||
if (config.getBufferSize() != null) builder.setBufferSize(config.getBufferSize());
|
||||
if (config.getBuffersPerRegion() != null) builder.setBuffersPerRegion(config.getBuffersPerRegion());
|
||||
if (config.getIoThreads() != null) builder.setIoThreads(config.getIoThreads());
|
||||
|
|
|
@ -46,8 +46,12 @@ public class SecurityInfo<T extends SecurityInfo> implements Cloneable {
|
|||
/**
|
||||
* Mandate authentication but authorize access as no roles to check against.
|
||||
*/
|
||||
AUTHENTICATE;
|
||||
AUTHENTICATE,
|
||||
|
||||
/**
|
||||
* Permit access in any case, but provide authorization info only if authorized.
|
||||
*/
|
||||
PERMIT_AND_INJECT_IF_AUTHENTICATED;
|
||||
}
|
||||
|
||||
private volatile EmptyRoleSemantic emptyRoleSemantic = EmptyRoleSemantic.DENY;
|
||||
|
|
Loading…
Reference in a new issue