Add couple of toString / simplify

This commit is contained in:
AFaust
2021-12-05 12:48:02 +01:00
parent 1170f343c9
commit b1f97ada95
11 changed files with 232 additions and 128 deletions

View File

@@ -304,8 +304,6 @@ public class KeycloakAuthenticationComponent extends AbstractAuthenticationCompo
throw new AuthenticationException("Failed to authenticate against Keycloak", atex); throw new AuthenticationException("Failed to authenticate against Keycloak", atex);
} }
// TODO Override setCurrentUser to perform user existence validation and role retrieval for non-Keycloak logins
// (e.g. via public API setCurrentUser)
this.setCurrentUser(realUserName); this.setCurrentUser(realUserName);
this.handleUserTokens(accessTokenHolder.getAccessToken(), accessTokenHolder.getIdToken(), true); this.handleUserTokens(accessTokenHolder.getAccessToken(), accessTokenHolder.getIdToken(), true);
} }

View File

@@ -176,7 +176,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param active * @param active
* the active to set * the active to set
*/ */
public void setActive(final boolean active) public void setActive(final boolean active)
{ {
@@ -185,7 +185,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param allowTicketLogon * @param allowTicketLogon
* the allowTicketLogon to set * the allowTicketLogon to set
*/ */
public void setAllowTicketLogon(final boolean allowTicketLogon) public void setAllowTicketLogon(final boolean allowTicketLogon)
{ {
@@ -194,7 +194,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param allowHttpBasicLogon * @param allowHttpBasicLogon
* the allowHttpBasicLogon to set * the allowHttpBasicLogon to set
*/ */
public void setAllowHttpBasicLogon(final boolean allowHttpBasicLogon) public void setAllowHttpBasicLogon(final boolean allowHttpBasicLogon)
{ {
@@ -203,7 +203,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param handlePublicApi * @param handlePublicApi
* the handlePublicApi to set * the handlePublicApi to set
*/ */
public void setHandlePublicApi(final boolean handlePublicApi) public void setHandlePublicApi(final boolean handlePublicApi)
{ {
@@ -212,7 +212,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param loginPageUrl * @param loginPageUrl
* the loginPageUrl to set * the loginPageUrl to set
*/ */
public void setLoginPageUrl(final String loginPageUrl) public void setLoginPageUrl(final String loginPageUrl)
{ {
@@ -221,7 +221,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param originalRequestUrlHeaderName * @param originalRequestUrlHeaderName
* the originalRequestUrlHeaderName to set * the originalRequestUrlHeaderName to set
*/ */
public void setOriginalRequestUrlHeaderName(final String originalRequestUrlHeaderName) public void setOriginalRequestUrlHeaderName(final String originalRequestUrlHeaderName)
{ {
@@ -230,7 +230,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param noKeycloakHandlingHeaderName * @param noKeycloakHandlingHeaderName
* the noKeycloakHandlingHeaderName to set * the noKeycloakHandlingHeaderName to set
*/ */
public void setNoKeycloakHandlingHeaderName(final String noKeycloakHandlingHeaderName) public void setNoKeycloakHandlingHeaderName(final String noKeycloakHandlingHeaderName)
{ {
@@ -239,7 +239,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param bodyBufferLimit * @param bodyBufferLimit
* the bodyBufferLimit to set * the bodyBufferLimit to set
*/ */
public void setBodyBufferLimit(final int bodyBufferLimit) public void setBodyBufferLimit(final int bodyBufferLimit)
{ {
@@ -248,7 +248,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param keycloakDeployment * @param keycloakDeployment
* the keycloakDeployment to set * the keycloakDeployment to set
*/ */
public void setKeycloakDeployment(final KeycloakDeployment keycloakDeployment) public void setKeycloakDeployment(final KeycloakDeployment keycloakDeployment)
{ {
@@ -257,7 +257,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param sessionIdMapper * @param sessionIdMapper
* the sessionIdMapper to set * the sessionIdMapper to set
*/ */
public void setSessionIdMapper(final SessionIdMapper sessionIdMapper) public void setSessionIdMapper(final SessionIdMapper sessionIdMapper)
{ {
@@ -266,7 +266,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param keycloakAuthenticationComponent * @param keycloakAuthenticationComponent
* the keycloakAuthenticationComponent to set * the keycloakAuthenticationComponent to set
*/ */
public void setKeycloakAuthenticationComponent(final KeycloakAuthenticationComponent keycloakAuthenticationComponent) public void setKeycloakAuthenticationComponent(final KeycloakAuthenticationComponent keycloakAuthenticationComponent)
{ {
@@ -275,7 +275,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param keycloakTicketTokenCache * @param keycloakTicketTokenCache
* the keycloakTicketTokenCache to set * the keycloakTicketTokenCache to set
*/ */
public void setKeycloakTicketTokenCache(final SimpleCache<String, RefreshableAccessTokenHolder> keycloakTicketTokenCache) public void setKeycloakTicketTokenCache(final SimpleCache<String, RefreshableAccessTokenHolder> keycloakTicketTokenCache)
{ {
@@ -284,7 +284,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
/** /**
* @param publicApiRuntimeContainer * @param publicApiRuntimeContainer
* the publicApiRuntimeContainer to set * the publicApiRuntimeContainer to set
*/ */
public void setPublicApiRuntimeContainer(final RuntimeContainer publicApiRuntimeContainer) public void setPublicApiRuntimeContainer(final RuntimeContainer publicApiRuntimeContainer)
{ {
@@ -333,12 +333,12 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* Checks and processes any HTTP Basic authentication if allowed. * Checks and processes any HTTP Basic authentication if allowed.
* *
* @param req * @param req
* the servlet request * the servlet request
* *
* @throws IOException * @throws IOException
* if any error occurs during processing of HTTP Basic authentication * if any error occurs during processing of HTTP Basic authentication
* @throws ServletException * @throws ServletException
* if any error occurs during processing of HTTP Basic authentication * if any error occurs during processing of HTTP Basic authentication
* *
* @return {@code true} if an existing HTTP Basic authentication header was successfully processed, {@code false} otherwise * @return {@code true} if an existing HTTP Basic authentication header was successfully processed, {@code false} otherwise
*/ */
@@ -415,17 +415,17 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* will be terminated. Otherwise processing may continue with the filter chain (if still applicable). * will be terminated. Otherwise processing may continue with the filter chain (if still applicable).
* *
* @param context * @param context
* the servlet context * the servlet context
* @param req * @param req
* the servlet request * the servlet request
* @param res * @param res
* the servlet response * the servlet response
* @param chain * @param chain
* the filter chain * the filter chain
* @throws IOException * @throws IOException
* if any error occurs during Keycloak authentication or processing of the filter chain * if any error occurs during Keycloak authentication or processing of the filter chain
* @throws ServletException * @throws ServletException
* if any error occurs during Keycloak authentication or processing of the filter chain * if any error occurs during Keycloak authentication or processing of the filter chain
*/ */
protected void processKeycloakAuthenticationAndActions(final ServletContext context, final HttpServletRequest req, protected void processKeycloakAuthenticationAndActions(final ServletContext context, final HttpServletRequest req,
final HttpServletResponse res, final FilterChain chain) throws IOException, ServletException final HttpServletResponse res, final FilterChain chain) throws IOException, ServletException
@@ -556,21 +556,21 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* Processes a sucessfull authentication via Keycloak. * Processes a sucessfull authentication via Keycloak.
* *
* @param context * @param context
* the servlet context * the servlet context
* @param req * @param req
* the servlet request * the servlet request
* @param res * @param res
* the servlet response * the servlet response
* @param chain * @param chain
* the filter chain * the filter chain
* @param facade * @param facade
* the Keycloak HTTP facade * the Keycloak HTTP facade
* @param tokenStore * @param tokenStore
* the Keycloak token store * the Keycloak token store
* @throws IOException * @throws IOException
* if any error occurs during Keycloak authentication or processing of the filter chain * if any error occurs during Keycloak authentication or processing of the filter chain
* @throws ServletException * @throws ServletException
* if any error occurs during Keycloak authentication or processing of the filter chain * if any error occurs during Keycloak authentication or processing of the filter chain
*/ */
protected void onKeycloakAuthenticationSuccess(final ServletContext context, final HttpServletRequest req, protected void onKeycloakAuthenticationSuccess(final ServletContext context, final HttpServletRequest req,
final HttpServletResponse res, final FilterChain chain, final OIDCServletHttpFacade facade, final HttpServletResponse res, final FilterChain chain, final OIDCServletHttpFacade facade,
@@ -668,16 +668,16 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* Processes a failed authentication via Keycloak. * Processes a failed authentication via Keycloak.
* *
* @param context * @param context
* the servlet context * the servlet context
* @param req * @param req
* the servlet request * the servlet request
* @param res * @param res
* the servlet response * the servlet response
* *
* @throws IOException * @throws IOException
* if any error occurs during processing of the filter chain * if any error occurs during processing of the filter chain
* @throws ServletException * @throws ServletException
* if any error occurs during processing of the filter chain * if any error occurs during processing of the filter chain
*/ */
protected void onKeycloakAuthenticationFailure(final ServletContext context, final HttpServletRequest req, protected void onKeycloakAuthenticationFailure(final ServletContext context, final HttpServletRequest req,
final HttpServletResponse res) throws IOException, ServletException final HttpServletResponse res) throws IOException, ServletException
@@ -707,18 +707,18 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* Checks if processing of the filter must be skipped for the specified request. * Checks if processing of the filter must be skipped for the specified request.
* *
* @param context * @param context
* the servlet context * the servlet context
* @param req * @param req
* the servlet request to check for potential conditions to skip * the servlet request to check for potential conditions to skip
* @param res * @param res
* the servlet response on which potential updates of cookies / response headers need to be set * the servlet response on which potential updates of cookies / response headers need to be set
* @return {@code true} if processing of the {@link #doFilter(ServletContext, ServletRequest, ServletResponse, FilterChain) filter * @return {@code true} if processing of the {@link #doFilter(ServletContext, ServletRequest, ServletResponse, FilterChain) filter
* operation} must be skipped, {@code false} otherwise * operation} must be skipped, {@code false} otherwise
* *
* @throws IOException * @throws IOException
* if any error occurs during inspection of the request * if any error occurs during inspection of the request
* @throws ServletException * @throws ServletException
* if any error occurs during inspection of the request * if any error occurs during inspection of the request
*/ */
protected boolean checkForSkipCondition(final ServletContext context, final HttpServletRequest req, final HttpServletResponse res) protected boolean checkForSkipCondition(final ServletContext context, final HttpServletRequest req, final HttpServletResponse res)
throws IOException, ServletException throws IOException, ServletException
@@ -772,11 +772,10 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
} }
else if (authHeader != null && authHeader.toLowerCase(Locale.ENGLISH).startsWith("bearer ")) else if (authHeader != null && authHeader.toLowerCase(Locale.ENGLISH).startsWith("bearer "))
{ {
if (session == null) // even though we provide a remote user mapper, it may not be the first in the chain, so Bearer might not be processed (yet) and
{ // thus session not initialised
throw new IllegalStateException("Session should have been initialised by Bearer authentication in remote user mapper"); final AccessToken accessToken = session != null ? (AccessToken) session.getAttribute(KeycloakRemoteUserMapper.class.getName())
} : null;
final AccessToken accessToken = (AccessToken) session.getAttribute(KeycloakRemoteUserMapper.class.getName());
if (accessToken != null) if (accessToken != null)
{ {
if (accessToken.isActive()) if (accessToken.isActive())
@@ -1011,13 +1010,13 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* Checks whether a particular request is aimed at a Public v1 ReST API web script which does not require any authentication. * Checks whether a particular request is aimed at a Public v1 ReST API web script which does not require any authentication.
* *
* @param req * @param req
* the request to check * the request to check
* @param servletPath * @param servletPath
* the path to the servlet matching the request * the path to the servlet matching the request
* @param pathInfo * @param pathInfo
* the request path following the servlet path * the request path following the servlet path
* @return {@code true} if the request targets a Public v1 ReST API web script which does not require authentication, {@code false} * @return {@code true} if the request targets a Public v1 ReST API web script which does not require authentication, {@code false}
* otherwise * otherwise
*/ */
protected boolean isNoAuthPublicRestApiWebScriptRequest(final HttpServletRequest req, final String servletPath, final String pathInfo) protected boolean isNoAuthPublicRestApiWebScriptRequest(final HttpServletRequest req, final String servletPath, final String pathInfo)
{ {
@@ -1059,13 +1058,13 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* necessary or configured. * necessary or configured.
* *
* @param req * @param req
* the HTTP servlet request * the HTTP servlet request
* @param res * @param res
* the HTTP servlet response * the HTTP servlet response
* @param userId * @param userId
* the ID of the authenticated user * the ID of the authenticated user
* @return {@code true} if processing of the {@link #doFilter(ServletContext, ServletRequest, ServletResponse, FilterChain) filter * @return {@code true} if processing of the {@link #doFilter(ServletContext, ServletRequest, ServletResponse, FilterChain) filter
* operation} can be skipped as the account represents a valid and still active authentication, {@code false} otherwise * operation} can be skipped as the account represents a valid and still active authentication, {@code false} otherwise
*/ */
protected boolean validateAndRefreshKeycloakAuthentication(final HttpServletRequest req, final HttpServletResponse res, protected boolean validateAndRefreshKeycloakAuthentication(final HttpServletRequest req, final HttpServletResponse res,
final String userId) final String userId)
@@ -1133,16 +1132,16 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* Check if the request has specified a ticket parameter to bypass the standard authentication. * Check if the request has specified a ticket parameter to bypass the standard authentication.
* *
* @param context * @param context
* the servlet context * the servlet context
* @param req * @param req
* the request * the request
* @param resp * @param resp
* the response * the response
* *
* @throws IOException * @throws IOException
* if any error occurs during ticket processing * if any error occurs during ticket processing
* @throws ServletException * @throws ServletException
* if any error occurs during ticket processing * if any error occurs during ticket processing
* *
* @return boolean * @return boolean
*/ */
@@ -1202,7 +1201,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* Checks if the HTTP request has set the Keycloak state cookie. * Checks if the HTTP request has set the Keycloak state cookie.
* *
* @param req * @param req
* the HTTP request to check * the HTTP request to check
* @return {@code true} if the state cookie is set, {@code false} otherwise * @return {@code true} if the state cookie is set, {@code false} otherwise
*/ */
protected boolean hasStateCookie(final HttpServletRequest req) protected boolean hasStateCookie(final HttpServletRequest req)
@@ -1219,11 +1218,11 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* Resets any Keycloak-related state cookies present in the current request. * Resets any Keycloak-related state cookies present in the current request.
* *
* @param context * @param context
* the servlet context * the servlet context
* @param req * @param req
* the servlet request * the servlet request
* @param res * @param res
* the servlet response * the servlet response
*/ */
protected void resetStateCookies(final ServletContext context, final HttpServletRequest req, final HttpServletResponse res) protected void resetStateCookies(final ServletContext context, final HttpServletRequest req, final HttpServletResponse res)
{ {
@@ -1247,7 +1246,7 @@ public class KeycloakAuthenticationFilter extends BaseAuthenticationFilter
* technical default value in lieu of an explicitly configured value. * technical default value in lieu of an explicitly configured value.
* *
* @param req * @param req
* the incoming request * the incoming request
* @return the assumed SSL port to be used in redirects * @return the assumed SSL port to be used in redirects
*/ */
protected int determineLikelySslPort(final HttpServletRequest req) protected int determineLikelySslPort(final HttpServletRequest req)

View File

@@ -121,9 +121,6 @@ public class KeycloakRemoteUserMapper implements RemoteUserMapper, ActivateableB
final BearerTokenRequestAuthenticator authenticator = new BearerTokenRequestAuthenticator(this.keycloakDeployment); final BearerTokenRequestAuthenticator authenticator = new BearerTokenRequestAuthenticator(this.keycloakDeployment);
final AuthOutcome authOutcome = authenticator.authenticate(httpFacade); final AuthOutcome authOutcome = authenticator.authenticate(httpFacade);
// TODO Check on how to enable / add client/audience validation
// currently, Share token seems to be valid here, which it shouldn't be
// also, Share token may not contain Alfresco client roles (e.g. admin)
if (authOutcome == AuthOutcome.AUTHENTICATED) if (authOutcome == AuthOutcome.AUTHENTICATED)
{ {
final AccessToken token = authenticator.getToken(); final AccessToken token = authenticator.getToken();

View File

@@ -34,7 +34,6 @@ import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.extensions.surf.util.URLDecoder;
import org.springframework.extensions.webscripts.Description.RequiredAuthentication; import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
import org.springframework.extensions.webscripts.Match; import org.springframework.extensions.webscripts.Match;
import org.springframework.extensions.webscripts.RuntimeContainer; import org.springframework.extensions.webscripts.RuntimeContainer;
@@ -116,7 +115,7 @@ public class KeycloakWebScriptSSOAuthenticationFilter extends BaseAuthentication
LOGGER.debug("Processing request: {} SID: {}", pathInfo, req.getSession(false) != null ? req.getSession().getId() : null); LOGGER.debug("Processing request: {} SID: {}", pathInfo, req.getSession(false) != null ? req.getSession().getId() : null);
final Match match = this.container.getRegistry().findWebScript(req.getMethod(), URLDecoder.decode(pathInfo)); final Match match = this.container.getRegistry().findWebScript(req.getMethod(), pathInfo);
if (match != null && match.getWebScript() != null) if (match != null && match.getWebScript() != null)
{ {
final RequiredAuthentication reqAuth = match.getWebScript().getDescription().getRequiredAuthentication(); final RequiredAuthentication reqAuth = match.getWebScript().getDescription().getRequiredAuthentication();

View File

@@ -52,7 +52,7 @@ public class AggregateRoleNameMapper implements InitializingBean, RoleNameMapper
/** /**
* @param granularMappers * @param granularMappers
* the granularMappers to set * the granularMappers to set
*/ */
public void setGranularMappers(final List<RoleNameMapper> granularMappers) public void setGranularMappers(final List<RoleNameMapper> granularMappers)
{ {
@@ -61,7 +61,7 @@ public class AggregateRoleNameMapper implements InitializingBean, RoleNameMapper
/** /**
* @param upperCaseRoles * @param upperCaseRoles
* the upperCaseRoles to set * the upperCaseRoles to set
*/ */
public void setUpperCaseRoles(final boolean upperCaseRoles) public void setUpperCaseRoles(final boolean upperCaseRoles)
{ {
@@ -109,4 +109,25 @@ public class AggregateRoleNameMapper implements InitializingBean, RoleNameMapper
} }
return mappedName; return mappedName;
} }
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
builder.append("AggregateRoleNameMapper [");
if (this.granularMappers != null)
{
builder.append("granularMappers=");
builder.append(this.granularMappers);
builder.append(", ");
}
builder.append("upperCaseRoles=");
builder.append(this.upperCaseRoles);
builder.append("]");
return builder.toString();
}
} }

View File

@@ -15,6 +15,7 @@
*/ */
package de.acosix.alfresco.keycloak.repo.roles; package de.acosix.alfresco.keycloak.repo.roles;
import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@@ -34,33 +35,41 @@ public class PatternRoleNameMapper implements RoleNameMapper
private static final Logger LOGGER = LoggerFactory.getLogger(PatternRoleNameMapper.class); private static final Logger LOGGER = LoggerFactory.getLogger(PatternRoleNameMapper.class);
protected Map<String, String> patternMappings; protected final Map<String, String> patternMappings = new HashMap<>();
protected Map<String, String> patternInverseMappings; protected final Map<String, String> patternInverseMappings = new HashMap<>();
protected boolean upperCaseRoles; protected boolean upperCaseRoles;
/** /**
* @param patternMappings * @param patternMappings
* the patternMappings to set * the patternMappings to set
*/ */
public void setPatternMappings(final Map<String, String> patternMappings) public void setPatternMappings(final Map<String, String> patternMappings)
{ {
this.patternMappings = patternMappings; this.patternMappings.clear();
if (patternMappings != null)
{
this.patternMappings.putAll(patternMappings);
}
} }
/** /**
* @param patternInverseMappings * @param patternInverseMappings
* the patternInverseMappings to set * the patternInverseMappings to set
*/ */
public void setPatternInverseMappings(final Map<String, String> patternInverseMappings) public void setPatternInverseMappings(final Map<String, String> patternInverseMappings)
{ {
this.patternInverseMappings = patternInverseMappings; this.patternInverseMappings.clear();
if (patternInverseMappings != null)
{
this.patternInverseMappings.putAll(patternInverseMappings);
}
} }
/** /**
* @param upperCaseRoles * @param upperCaseRoles
* the upperCaseRoles to set * the upperCaseRoles to set
*/ */
public void setUpperCaseRoles(final boolean upperCaseRoles) public void setUpperCaseRoles(final boolean upperCaseRoles)
{ {
@@ -75,23 +84,18 @@ public class PatternRoleNameMapper implements RoleNameMapper
{ {
ParameterCheck.mandatoryString("roleName", roleName); ParameterCheck.mandatoryString("roleName", roleName);
Optional<String> result = Optional.empty(); final Optional<String> matchingPattern = this.patternMappings.keySet().stream().filter(roleName::matches).findFirst();
final Optional<String> result = matchingPattern.map(pattern -> {
final String replacement = this.patternMappings.get(pattern);
LOGGER.debug("Role {} matches mapping pattern {} - applying replacement pattern {}", roleName, pattern, replacement);
final String mappedName = roleName.replaceAll(pattern, replacement);
LOGGER.debug("Mapped role {} to {}", roleName, mappedName);
return mappedName;
}).map(name -> this.upperCaseRoles ? name.toUpperCase(Locale.ENGLISH) : name);
if (this.patternMappings != null) if (!result.isPresent())
{ {
final Optional<String> matchingPattern = this.patternMappings.keySet().stream().filter(roleName::matches).findFirst(); LOGGER.debug("No matching pattern applies to role {}", roleName);
result = matchingPattern.map(pattern -> {
final String replacement = this.patternMappings.get(pattern);
LOGGER.debug("Role {} matches mapping pattern {} - applying replacement pattern {}", roleName, pattern, replacement);
final String mappedName = roleName.replaceAll(pattern, replacement);
LOGGER.debug("Mapped role {} to {}", roleName, mappedName);
return mappedName;
}).map(name -> this.upperCaseRoles ? name.toUpperCase(Locale.ENGLISH) : name);
if (!result.isPresent())
{
LOGGER.debug("No matching pattern applies to role {}", roleName);
}
} }
return result; return result;
@@ -125,4 +129,31 @@ public class PatternRoleNameMapper implements RoleNameMapper
return result; return result;
} }
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
builder.append("PatternRoleNameMapper [");
if (this.patternMappings != null)
{
builder.append("patternMappings=");
builder.append(this.patternMappings);
builder.append(", ");
}
if (this.patternInverseMappings != null)
{
builder.append("patternInverseMappings=");
builder.append(this.patternInverseMappings);
builder.append(", ");
}
builder.append("upperCaseRoles=");
builder.append(this.upperCaseRoles);
builder.append("]");
return builder.toString();
}
} }

View File

@@ -39,7 +39,7 @@ public class PrefixAttachingRoleNameMapper implements RoleNameMapper
/** /**
* @param prefix * @param prefix
* the prefix to set * the prefix to set
*/ */
public void setPrefix(final String prefix) public void setPrefix(final String prefix)
{ {
@@ -48,7 +48,7 @@ public class PrefixAttachingRoleNameMapper implements RoleNameMapper
/** /**
* @param upperCaseRoles * @param upperCaseRoles
* the upperCaseRoles to set * the upperCaseRoles to set
*/ */
public void setUpperCaseRoles(final boolean upperCaseRoles) public void setUpperCaseRoles(final boolean upperCaseRoles)
{ {
@@ -96,4 +96,25 @@ public class PrefixAttachingRoleNameMapper implements RoleNameMapper
return result; return result;
} }
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
builder.append("PrefixAttachingRoleNameMapper [");
if (this.prefix != null)
{
builder.append("prefix=");
builder.append(this.prefix);
builder.append(", ");
}
builder.append("upperCaseRoles=");
builder.append(this.upperCaseRoles);
builder.append("]");
return builder.toString();
}
} }

View File

@@ -15,6 +15,7 @@
*/ */
package de.acosix.alfresco.keycloak.repo.roles; package de.acosix.alfresco.keycloak.repo.roles;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.alfresco.util.ParameterCheck; import org.alfresco.util.ParameterCheck;
@@ -31,15 +32,19 @@ public class StaticRoleNameFilter implements RoleNameFilter
private static final Logger LOGGER = LoggerFactory.getLogger(StaticRoleNameFilter.class); private static final Logger LOGGER = LoggerFactory.getLogger(StaticRoleNameFilter.class);
protected Set<String> allowedRoles; protected final Set<String> allowedRoles = new HashSet<>();
/** /**
* @param allowedRoles * @param allowedRoles
* the allowedRoles to set * the allowedRoles to set
*/ */
public void setAllowedRoles(final Set<String> allowedRoles) public void setAllowedRoles(final Set<String> allowedRoles)
{ {
this.allowedRoles = allowedRoles; this.allowedRoles.clear();
if (allowedRoles != null)
{
this.allowedRoles.addAll(allowedRoles);
}
} }
/** /**
@@ -50,15 +55,24 @@ public class StaticRoleNameFilter implements RoleNameFilter
{ {
ParameterCheck.mandatoryString("roleName", roleName); ParameterCheck.mandatoryString("roleName", roleName);
boolean exposed = false; final boolean exposed = this.allowedRoles.contains(roleName);
LOGGER.debug("Determined exposure flag of {} for role {} using a static match set", exposed, roleName);
if (this.allowedRoles != null)
{
exposed = this.allowedRoles.contains(roleName);
LOGGER.debug("Determined exposure flag of {} for role {} using a static match set", exposed, roleName);
}
return exposed; return exposed;
} }
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
builder.append("StaticRoleNameFilter [");
builder.append("allowedRoles=");
builder.append(this.allowedRoles);
builder.append("]");
return builder.toString();
}
} }

View File

@@ -15,6 +15,7 @@
*/ */
package de.acosix.alfresco.keycloak.repo.roles; package de.acosix.alfresco.keycloak.repo.roles;
import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -34,22 +35,26 @@ public class StaticRoleNameMapper implements RoleNameMapper
private static final Logger LOGGER = LoggerFactory.getLogger(StaticRoleNameMapper.class); private static final Logger LOGGER = LoggerFactory.getLogger(StaticRoleNameMapper.class);
protected Map<String, String> nameMappings; protected final Map<String, String> nameMappings = new HashMap<>();
protected boolean upperCaseRoles; protected boolean upperCaseRoles;
/** /**
* @param nameMappings * @param nameMappings
* the nameMappings to set * the nameMappings to set
*/ */
public void setNameMappings(final Map<String, String> nameMappings) public void setNameMappings(final Map<String, String> nameMappings)
{ {
this.nameMappings = nameMappings; this.nameMappings.clear();
if (nameMappings != null)
{
this.nameMappings.putAll(nameMappings);
}
} }
/** /**
* @param upperCaseRoles * @param upperCaseRoles
* the upperCaseRoles to set * the upperCaseRoles to set
*/ */
public void setUpperCaseRoles(final boolean upperCaseRoles) public void setUpperCaseRoles(final boolean upperCaseRoles)
{ {
@@ -93,24 +98,39 @@ public class StaticRoleNameMapper implements RoleNameMapper
Optional<String> result = Optional.empty(); Optional<String> result = Optional.empty();
if (this.nameMappings != null) for (final Entry<String, String> entry : this.nameMappings.entrySet())
{ {
for (final Entry<String, String> entry : this.nameMappings.entrySet()) if (entry.getValue().equals(authorityName) || (this.upperCaseRoles && entry.getValue().equalsIgnoreCase(authorityName)))
{ {
if (entry.getValue().equals(authorityName) || (this.upperCaseRoles && entry.getValue().equalsIgnoreCase(authorityName))) final String mappedName = entry.getKey();
{ LOGGER.debug("Mapped authority name {} to {} using static mapping", authorityName, mappedName);
final String mappedName = entry.getKey(); result = Optional.of(mappedName);
LOGGER.debug("Mapped authority name {} to {} using static mapping", authorityName, mappedName); break;
result = Optional.of(mappedName);
break;
}
}
if (!result.isPresent())
{
LOGGER.debug("No static mapping applies to authority name {}", authorityName);
} }
} }
if (!result.isPresent())
{
LOGGER.debug("No static mapping applies to authority name {}", authorityName);
}
return result; return result;
} }
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
builder.append("StaticRoleNameMapper [");
builder.append("nameMappings=");
builder.append(this.nameMappings);
builder.append(", ");
builder.append("upperCaseRoles=");
builder.append(this.upperCaseRoles);
builder.append("]");
return builder.toString();
}
} }

View File

@@ -574,7 +574,8 @@
{ {
"clientScope": "alfresco-role-service", "clientScope": "alfresco-role-service",
"roles": [ "roles": [
"view-clients" "view-clients",
"view-realm"
] ]
} }
], ],
@@ -1135,7 +1136,8 @@
"query-groups", "query-groups",
"query-users", "query-users",
"view-users", "view-users",
"view-clients" "view-clients",
"view-realm"
] ]
} }
}, },

View File

@@ -609,7 +609,8 @@
{ {
"clientScope": "alfresco-role-service", "clientScope": "alfresco-role-service",
"roles": [ "roles": [
"view-clients" "view-clients",
"view-realm"
] ]
} }
], ],
@@ -1205,7 +1206,8 @@
"query-groups", "query-groups",
"query-users", "query-users",
"view-users", "view-users",
"view-clients" "view-clients",
"view-realm"
] ]
} }
}, },