refactor: Refactoring AuthProcFilters
parent
64a22d758f
commit
677943d4d6
|
@ -252,7 +252,7 @@
|
||||||
<security:intercept-url pattern="#{T(cz.muni.ics.oidc.web.controllers.LoginController).MAPPING_FAILURE}"
|
<security:intercept-url pattern="#{T(cz.muni.ics.oidc.web.controllers.LoginController).MAPPING_FAILURE}"
|
||||||
access="permitAll()"/>
|
access="permitAll()"/>
|
||||||
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
|
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
|
||||||
<security:custom-filter ref="mdcMuFilter" before="FIRST"/>
|
<security:custom-filter ref="mdcFilter" before="FIRST"/>
|
||||||
<security:custom-filter ref="metadataGeneratorFilter" before="CHANNEL_FILTER"/>
|
<security:custom-filter ref="metadataGeneratorFilter" before="CHANNEL_FILTER"/>
|
||||||
<security:custom-filter ref="clearSessionFilter" after="CHANNEL_FILTER"/>
|
<security:custom-filter ref="clearSessionFilter" after="CHANNEL_FILTER"/>
|
||||||
<security:custom-filter ref="samlFilter" before="CSRF_FILTER"/>
|
<security:custom-filter ref="samlFilter" before="CSRF_FILTER"/>
|
||||||
|
@ -337,8 +337,6 @@
|
||||||
<property name="order" value="1" />
|
<property name="order" value="1" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="mdcMuFilter" class="cz.muni.ics.oidc.server.filters.impl.MultiMDCFilter"/>
|
|
||||||
|
|
||||||
<!-- SAML -->
|
<!-- SAML -->
|
||||||
<bean id="clearSessionFilter" class="cz.muni.ics.oidc.saml.SamlInvalidateSessionFilter">
|
<bean id="clearSessionFilter" class="cz.muni.ics.oidc.saml.SamlInvalidateSessionFilter">
|
||||||
<constructor-arg name="contextLogoutHandler" ref="logoutHandler"/>
|
<constructor-arg name="contextLogoutHandler" ref="logoutHandler"/>
|
||||||
|
@ -362,7 +360,7 @@
|
||||||
|
|
||||||
<bean id="successLogoutHandler" class="cz.muni.ics.oidc.saml.PerunOidcLogoutSuccessHandler">
|
<bean id="successLogoutHandler" class="cz.muni.ics.oidc.saml.PerunOidcLogoutSuccessHandler">
|
||||||
<property name="defaultTargetUrl" value="#{T(cz.muni.ics.oidc.web.controllers.LogoutController).MAPPING_SUCCESS}"/>
|
<property name="defaultTargetUrl" value="#{T(cz.muni.ics.oidc.web.controllers.LogoutController).MAPPING_SUCCESS}"/>
|
||||||
<property name="targetUrlParameter" value="#{T(cz.muni.ics.oidc.server.filters.PerunFilterConstants).PARAM_TARGET}"/>
|
<property name="targetUrlParameter" value="#{T(cz.muni.ics.oidc.server.filters.AuthProcFilterConstants).PARAM_TARGET}"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="logoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
|
<bean id="logoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
|
||||||
|
|
|
@ -20,10 +20,10 @@ public class RemoteAddressMDCFilter {
|
||||||
"REMOTE_ADDR"
|
"REMOTE_ADDR"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String REMOTE_ADDR = "remoteAddr";
|
private static final String REMOTE_ADDRESS = "remoteAddr";
|
||||||
|
|
||||||
public void doFilter(ServletRequest servletRequest) {
|
public void doFilter(ServletRequest servletRequest) {
|
||||||
MDC.put(REMOTE_ADDR, getRemoteAddr((HttpServletRequest) servletRequest));
|
MDC.put(REMOTE_ADDRESS, getRemoteAddr((HttpServletRequest) servletRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRemoteAddr(HttpServletRequest request) {
|
private String getRemoteAddr(HttpServletRequest request) {
|
||||||
|
@ -37,7 +37,7 @@ public class RemoteAddressMDCFilter {
|
||||||
return ipList.split(",")[0];
|
return ipList.split(",")[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package cz.muni.ics.oidc;
|
||||||
|
|
||||||
|
public interface PerunConstants {
|
||||||
|
|
||||||
|
String REGISTRAR_TARGET_NEW = "targetnew";
|
||||||
|
String REGISTRAR_TARGET_EXISTING = "targetexisting";
|
||||||
|
String REGISTRAR_TARGET_EXTENDED = "targetextended";
|
||||||
|
|
||||||
|
String REGISTRAR_PARAM_VO = "vo";
|
||||||
|
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import org.opensaml.ws.message.encoder.MessageEncodingException;
|
||||||
import org.opensaml.xml.util.Pair;
|
import org.opensaml.xml.util.Pair;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.AARC_IDP_HINT;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.AARC_IDP_HINT;
|
||||||
|
|
||||||
public class PerunHTTPRedirectDeflateEncoder extends HTTPRedirectDeflateEncoder {
|
public class PerunHTTPRedirectDeflateEncoder extends HTTPRedirectDeflateEncoder {
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cz.muni.ics.oidc.saml;
|
package cz.muni.ics.oidc.saml;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_POST_LOGOUT_REDIRECT_URI;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_POST_LOGOUT_REDIRECT_URI;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_STATE;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_STATE;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
package cz.muni.ics.oidc.saml;
|
package cz.muni.ics.oidc.saml;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.AARC_IDP_HINT;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.AARC_IDP_HINT;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.CLIENT_ID_PREFIX;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.CLIENT_ID_PREFIX;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.EFILTER_PREFIX;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.EFILTER_PREFIX;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.FILTER_PREFIX;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.FILTER_PREFIX;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.IDP_ENTITY_ID_PREFIX;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.IDP_ENTITY_ID_PREFIX;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_CLIENT_ID;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_CLIENT_ID;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_PROMPT;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_PROMPT;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.REFEDS_MFA;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.REFEDS_MFA;
|
||||||
|
|
||||||
import cz.muni.ics.oidc.models.Facility;
|
import cz.muni.ics.oidc.models.Facility;
|
||||||
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
||||||
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
||||||
import cz.muni.ics.oidc.server.configurations.FacilityAttrsConfig;
|
import cz.muni.ics.oidc.server.configurations.FacilityAttrsConfig;
|
||||||
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
import cz.muni.ics.oidc.server.filters.PerunFilterConstants;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterConstants;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -160,12 +160,12 @@ public class PerunSamlEntryPoint extends SAMLEntryPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processAcrValues(HttpServletRequest request, WebSSOProfileOptions options) {
|
private void processAcrValues(HttpServletRequest request, WebSSOProfileOptions options) {
|
||||||
String acrValues = request.getParameter(PerunFilterConstants.PARAM_ACR_VALUES);
|
String acrValues = request.getParameter(AuthProcFilterConstants.PARAM_ACR_VALUES);
|
||||||
log.debug("Processing acr_values parameter: {}", acrValues);
|
log.debug("Processing acr_values parameter: {}", acrValues);
|
||||||
List<String> acrs = convertAcrValuesToList(acrValues);
|
List<String> acrs = convertAcrValuesToList(acrValues);
|
||||||
|
|
||||||
if (!hasAcrForcingIdp(acrs)) {
|
if (!hasAcrForcingIdp(acrs)) {
|
||||||
String clientId = request.getParameter(PerunFilterConstants.PARAM_CLIENT_ID);
|
String clientId = request.getParameter(AuthProcFilterConstants.PARAM_CLIENT_ID);
|
||||||
String idpFilter = extractIdpFilterForRp(clientId);
|
String idpFilter = extractIdpFilterForRp(clientId);
|
||||||
if (idpFilter != null) {
|
if (idpFilter != null) {
|
||||||
log.debug("Added IdP filter as SAML AuthnContextClassRef ({})", idpFilter);
|
log.debug("Added IdP filter as SAML AuthnContextClassRef ({})", idpFilter);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package cz.muni.ics.oidc.saml;
|
package cz.muni.ics.oidc.saml;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_ACR_VALUES;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_ACR_VALUES;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_FORCE_AUTHN;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_FORCE_AUTHN;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_PROMPT;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_PROMPT;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PROMPT_LOGIN;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PROMPT_LOGIN;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PROMPT_SELECT_ACCOUNT;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PROMPT_SELECT_ACCOUNT;
|
||||||
|
|
||||||
import cz.muni.ics.oidc.server.filters.PerunFilterConstants;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterConstants;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
@ -32,7 +32,7 @@ public class PerunSamlUtils {
|
||||||
public static boolean needsReAuthByMfa(ServletRequest request) {
|
public static boolean needsReAuthByMfa(ServletRequest request) {
|
||||||
String acrValues = request.getParameter(PARAM_ACR_VALUES);
|
String acrValues = request.getParameter(PARAM_ACR_VALUES);
|
||||||
boolean res = StringUtils.hasText(acrValues)
|
boolean res = StringUtils.hasText(acrValues)
|
||||||
&& acrValues.contains(PerunFilterConstants.REFEDS_MFA);
|
&& acrValues.contains(AuthProcFilterConstants.REFEDS_MFA);
|
||||||
log.debug("requires reAuth by MFA acr - {}", res);
|
log.debug("requires reAuth by MFA acr - {}", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,37 @@
|
||||||
package cz.muni.ics.oidc.server.filters;
|
package cz.muni.ics.oidc.server.filters;
|
||||||
|
|
||||||
|
import cz.muni.ics.oidc.exceptions.ConfigurationException;
|
||||||
|
import cz.muni.ics.oidc.saml.SamlProperties;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.Principal;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class for Perun filters. All filters called in CallPerunFiltersFilter has to extend this.
|
* Abstract class for Perun AuthProc filters. All filters defined and called in the
|
||||||
*
|
* {@link cz.muni.ics.oidc.server.filters.AuthProcFiltersContainer} instance have to extend this base class.
|
||||||
* Configuration of filter names:
|
|
||||||
* <ul>
|
|
||||||
* <li><b>filter.names</b> - comma separated list of names of the request filters</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
*
|
||||||
* Configuration of filter (replace [name] part with the name defined for the filter):
|
* Configuration of filter (replace [name] part with the name defined for the filter):
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><b>filter.[name].class</b> - Class the filter instantiates</li>
|
* <li><b>filter.[name].class</b> - Class the filter instantiates</li>
|
||||||
* <li><b>filter.[name].subs</b> - comma separated list of sub values for which execution of filter will be skipped
|
* <li><b>filter.[name].skip_for_users</b> - comma separated list of users for whom the execution of the filter
|
||||||
* if user's SUB is in the list</li>
|
* will be skipped if the users' SUB matches any value in the list</li>
|
||||||
* <li><b>filter.[name].clientIds</b> - comma separated list of client_id values for which execution of filter
|
* <li><b>filter.[name].skip_for_clients</b> - comma separated list of clients for which the execution of the filter
|
||||||
* will be skipped if client_id is in the list</li>
|
* will be skipped if the CLIENT_ID matches any value in the list</li>
|
||||||
|
* <li><b>filter.[name].execute_for_users</b> - comma separated list of users for whom the filter will be executed
|
||||||
|
* if the users' SUB matches any value in the list</li>
|
||||||
|
* <li><b>filter.[name].execute_for_clients</b> - comma separated list of clients for whom the filter will be executed
|
||||||
|
* if the CLIENT_ID matches any value in the list</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
* <i>NOTE: if none of the SKIP/EXECUTE conditions is specified (or the lists are empty), filter is run for all users
|
||||||
|
* and all clients</i>
|
||||||
*
|
*
|
||||||
* @see cz.muni.ics.oidc.server.filters.impl package for specific filters and their configuration
|
* @see cz.muni.ics.oidc.server.filters.impl package for specific filters and their configuration
|
||||||
*
|
*
|
||||||
|
@ -33,33 +39,57 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Getter
|
||||||
public abstract class AuthProcFilter {
|
public abstract class AuthProcFilter {
|
||||||
|
|
||||||
|
public static final String APPLIED = "APPLIED_";
|
||||||
|
|
||||||
private static final String DELIMITER = ",";
|
private static final String DELIMITER = ",";
|
||||||
private static final String CLIENT_IDS = "clientIds";
|
private static final String EXECUTE = "execute";
|
||||||
|
private static final String EXECUTE_FOR_CLIENTS = "execute_for_clients";
|
||||||
|
private static final String EXECUTE_FOR_USERS = "execute_for_users";
|
||||||
|
private static final String SKIP_FOR_CLIENTS = "skip_for_clients";
|
||||||
|
private static final String SKIP_FOR_USERS = "skip_for_users";
|
||||||
private static final String SUBS = "subs";
|
private static final String SUBS = "subs";
|
||||||
|
private static final String CLIENT_IDS = "clientIds";
|
||||||
|
|
||||||
private final String filterName;
|
private final String filterName;
|
||||||
private Set<String> clientIds = new HashSet<>();
|
private final Set<String> executeForClients = new HashSet<>();
|
||||||
private Set<String> subs = new HashSet<>();
|
private final Set<String> executeForUsers = new HashSet<>();
|
||||||
|
private final Set<String> skipForClients = new HashSet<>();
|
||||||
|
private final Set<String> skipForUsers = new HashSet<>();
|
||||||
|
|
||||||
public AuthProcFilter(AuthProcFilterParams params) {
|
private final SamlProperties samlProperties;
|
||||||
filterName = params.getFilterName();
|
|
||||||
|
|
||||||
if (params.hasProperty(CLIENT_IDS)) {
|
public AuthProcFilter(AuthProcFilterInitContext ctx) throws ConfigurationException {
|
||||||
this.clientIds = new HashSet<>(Arrays.asList(params.getProperty(CLIENT_IDS).split(DELIMITER)));
|
filterName = ctx.getFilterName();
|
||||||
|
this.samlProperties = ctx.getBeanUtil().getBean(SamlProperties.class);
|
||||||
|
initializeExecutionRulesLists(ctx);
|
||||||
|
|
||||||
|
if (!Collections.disjoint(executeForClients, skipForClients)) {
|
||||||
|
throw new ConfigurationException("Filter '" + filterName + "' is configured to be run and skipped for the same client");
|
||||||
|
} else if (!Collections.disjoint(executeForUsers, skipForUsers)) {
|
||||||
|
throw new ConfigurationException("Filter '" + filterName + "' is configured to be run and skipped for the same user");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.hasProperty(SUBS)) {
|
log.info("{} - filter initialized", filterName);
|
||||||
this.subs = new HashSet<>(Arrays.asList(params.getProperty(SUBS).split(DELIMITER)));
|
if (!skipForUsers.isEmpty()) {
|
||||||
|
log.info("{} - skip execution for users with SUB in: '{}'", filterName, skipForUsers);
|
||||||
|
}
|
||||||
|
if (!skipForClients.isEmpty()) {
|
||||||
|
log.info("{} - skip execution for clients with CLIENT_ID in: '{}'", filterName, skipForClients);
|
||||||
|
}
|
||||||
|
if (!executeForUsers.isEmpty()) {
|
||||||
|
log.info("{} - execute for users with SUB in: '{}'", filterName, executeForUsers);
|
||||||
|
}
|
||||||
|
if (!executeForClients.isEmpty()) {
|
||||||
|
log.info("{} - execute for clients with CLIENT_ID in: '{}'", filterName, executeForClients);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("{} - filter initialized", filterName);
|
|
||||||
log.debug("{} - skip execution for users with SUB in: {}", filterName, subs);
|
|
||||||
log.debug("{} - skip execution for clients with CLIENT_ID in: {}", filterName, clientIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getSessionAppliedParamName();
|
protected String getSessionAppliedParamName() {
|
||||||
|
return APPLIED + getClass().getSimpleName() + '_' + getFilterName();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In this method is done whole logic of filer
|
* In this method is done whole logic of filer
|
||||||
|
@ -69,10 +99,10 @@ public abstract class AuthProcFilter {
|
||||||
* @return boolean if filter was successfully done
|
* @return boolean if filter was successfully done
|
||||||
* @throws IOException this exception could be thrown because of failed or interrupted I/O operation
|
* @throws IOException this exception could be thrown because of failed or interrupted I/O operation
|
||||||
*/
|
*/
|
||||||
protected abstract boolean process(HttpServletRequest request, HttpServletResponse response, FilterParams params)
|
protected abstract boolean process(HttpServletRequest request, HttpServletResponse response, AuthProcFilterCommonVars params)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
public boolean doFilter(HttpServletRequest req, HttpServletResponse res, FilterParams params) throws IOException {
|
public boolean doFilter(HttpServletRequest req, HttpServletResponse res, AuthProcFilterCommonVars params) throws IOException {
|
||||||
if (!skip(req)) {
|
if (!skip(req)) {
|
||||||
log.trace("{} - executing filter", filterName);
|
log.trace("{} - executing filter", filterName);
|
||||||
return process(req, res, params);
|
return process(req, res, params);
|
||||||
|
@ -81,14 +111,18 @@ public abstract class AuthProcFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean skip(HttpServletRequest request) {
|
private boolean skip(HttpServletRequest req) {
|
||||||
if (hasBeenApplied(request.getSession(true))) {
|
if (hasBeenApplied(req.getSession(true))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
log.debug("{} - marking filter as applied", filterName);
|
log.debug("{} - marking filter as applied", filterName);
|
||||||
request.getSession(true).setAttribute(getSessionAppliedParamName(), true);
|
req.getSession(true).setAttribute(getSessionAppliedParamName(), true);
|
||||||
return skipForSub(request.getUserPrincipal())
|
String sub = FiltersUtils.getUserIdentifier(req, samlProperties.getUserIdentifierAttribute());
|
||||||
|| skipForClientId(request.getParameter(PerunFilterConstants.PARAM_CLIENT_ID));
|
String clientId = FiltersUtils.getClientId(req);
|
||||||
|
|
||||||
|
boolean explicitExecution = executeForSub(sub) || executeForClientId(clientId);
|
||||||
|
boolean explicitSkip = skipForClientId(clientId) || skipForSub(sub);
|
||||||
|
return !explicitExecution && explicitSkip;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasBeenApplied(HttpSession sess) {
|
private boolean hasBeenApplied(HttpSession sess) {
|
||||||
|
@ -100,21 +134,45 @@ public abstract class AuthProcFilter {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean skipForSub(Principal p) {
|
private boolean executeForSub(String sub) {
|
||||||
String sub = (p != null) ? p.getName() : null;
|
return checkRule(sub, executeForUsers, "{} - execute filter: matched one of the explicit SUBS ({})");
|
||||||
if (sub != null && subs.contains(sub)) {
|
}
|
||||||
log.debug("{} - skip filter execution: matched one of the ignored SUBS ({})", filterName, sub);
|
|
||||||
return true;
|
private boolean executeForClientId(String clientId) {
|
||||||
}
|
return checkRule(clientId, executeForClients, "{} - execute filter: matched one of the explicit CLIENT_IDS ({})");
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
private boolean skipForSub(String sub) {
|
||||||
|
return checkRule(sub, skipForUsers, "{} - skip filter execution: matched one of the ignored SUBS ({})");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean skipForClientId(String clientId) {
|
private boolean skipForClientId(String clientId) {
|
||||||
if (clientId != null && clientIds.contains(clientId)){
|
return checkRule(clientId, skipForClients, "{} - skip filter execution: matched one of the ignored CLIENT_IDS ({})");
|
||||||
log.debug("{} - skip filter execution: matched one of the ignored CLIENT_IDS ({})", filterName, clientId);
|
}
|
||||||
|
|
||||||
|
private boolean checkRule(String param, Set<String> ruleSet, String logMsg) {
|
||||||
|
if (param != null && ruleSet.contains(param)){
|
||||||
|
log.debug(logMsg, filterName, param);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializeExecutionRulesLists(AuthProcFilterInitContext ctx) {
|
||||||
|
initializeExecutionRuleList(ctx, EXECUTE_FOR_CLIENTS, executeForClients);
|
||||||
|
initializeExecutionRuleList(ctx, SKIP_FOR_CLIENTS, skipForClients);
|
||||||
|
initializeExecutionRuleList(ctx, CLIENT_IDS, skipForClients);
|
||||||
|
|
||||||
|
initializeExecutionRuleList(ctx, EXECUTE_FOR_USERS, executeForUsers);
|
||||||
|
initializeExecutionRuleList(ctx, SKIP_FOR_USERS, skipForUsers);
|
||||||
|
initializeExecutionRuleList(ctx, SUBS, skipForUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeExecutionRuleList(AuthProcFilterInitContext ctx, String property, Set<String> list) {
|
||||||
|
if (ctx.hasProperty(property)) {
|
||||||
|
String value = ctx.getProperty(property, "");
|
||||||
|
list.addAll(Arrays.asList(value.split(DELIMITER)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,31 +3,18 @@ package cz.muni.ics.oidc.server.filters;
|
||||||
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
||||||
import cz.muni.ics.oidc.models.Facility;
|
import cz.muni.ics.oidc.models.Facility;
|
||||||
import cz.muni.ics.oidc.models.PerunUser;
|
import cz.muni.ics.oidc.models.PerunUser;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
public class FilterParams {
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AuthProcFilterCommonVars {
|
||||||
|
|
||||||
private final ClientDetailsEntity client;
|
private final ClientDetailsEntity client;
|
||||||
private final Facility facility;
|
private final Facility facility;
|
||||||
private final PerunUser user;
|
private final PerunUser user;
|
||||||
|
|
||||||
public FilterParams(ClientDetailsEntity client, Facility facility, PerunUser user) {
|
|
||||||
this.client = client;
|
|
||||||
this.facility = facility;
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClientDetailsEntity getClient() {
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Facility getFacility() {
|
|
||||||
return facility;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PerunUser getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientIdentifier() {
|
public String getClientIdentifier() {
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
return client.getClientId();
|
return client.getClientId();
|
|
@ -0,0 +1,55 @@
|
||||||
|
package cz.muni.ics.oidc.server.filters;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class containing common constants used by Perun request filters.
|
||||||
|
*
|
||||||
|
* @author Dominik Baranek <baranek@ics.muni.cz>
|
||||||
|
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
||||||
|
*/
|
||||||
|
public interface AuthProcFilterConstants {
|
||||||
|
|
||||||
|
String AUTHORIZE_REQ_PATTERN = "/auth/authorize";
|
||||||
|
String DEVICE_APPROVE_REQ_PATTERN = "/auth/device/authorize";
|
||||||
|
|
||||||
|
String PARAM_CLIENT_ID = "client_id";
|
||||||
|
String PARAM_SCOPE = "scope";
|
||||||
|
String PARAM_MESSAGE = "message";
|
||||||
|
String PARAM_HEADER = "header";
|
||||||
|
String PARAM_TARGET = "target";
|
||||||
|
String PARAM_FORCE_AUTHN = "forceAuthn";
|
||||||
|
String PARAM_PROMPT = "prompt";
|
||||||
|
String PARAM_REASON = "reason";
|
||||||
|
String PARAM_ACCEPTED = "accepted";
|
||||||
|
String PARAM_ACR_VALUES = "acr_values";
|
||||||
|
String PARAM_POST_LOGOUT_REDIRECT_URI = "post_logout_redirect_uri";
|
||||||
|
String PARAM_STATE = "state";
|
||||||
|
String CLIENT_ID_PREFIX = "urn:cesnet:proxyidp:client_id:";
|
||||||
|
String AARC_IDP_HINT = "aarc_idp_hint";
|
||||||
|
|
||||||
|
String IDP_ENTITY_ID_PREFIX = "urn:cesnet:proxyidp:idpentityid:";
|
||||||
|
String FILTER_PREFIX = "urn:cesnet:proxyidp:filter:";
|
||||||
|
String EFILTER_PREFIX = "urn:cesnet:proxyidp:efilter:";
|
||||||
|
|
||||||
|
String SAML_EPUID = "urn:oid:1.3.6.1.4.1.5923.1.1.1.13";
|
||||||
|
String SAML_EPPN = "urn:oid:1.3.6.1.4.1.5923.1.1.1.6";
|
||||||
|
String SAML_EPTID = "urn:oid:1.3.6.1.4.1.5923.1.1.1.10";
|
||||||
|
String SAML_UID = "urn:oid:0.9.2342.19200300.100.1.1";
|
||||||
|
String SAML_UNIQUE_IDENTIFIER = "urn:oid:0.9.2342.19200300.100.1.44";
|
||||||
|
String SAML_PERUN_USERID_IDENTIFIER = "urn:cesnet:proxyidp:attribute:perunUserId";
|
||||||
|
|
||||||
|
String REFEDS_MFA = "https://refeds.org/profile/mfa";
|
||||||
|
String PROMPT_LOGIN = "login";
|
||||||
|
String PROMPT_SELECT_ACCOUNT = "select_account";
|
||||||
|
|
||||||
|
Map<String, String> SAML_IDS = Map.of(
|
||||||
|
"eppn", SAML_EPPN,
|
||||||
|
"epuid", SAML_EPUID,
|
||||||
|
"eptid", SAML_EPTID,
|
||||||
|
"uid", SAML_UID,
|
||||||
|
"uniqueIdentifier", SAML_UNIQUE_IDENTIFIER,
|
||||||
|
"perunUserId", SAML_PERUN_USERID_IDENTIFIER
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package cz.muni.ics.oidc.server.filters;
|
||||||
|
|
||||||
|
import cz.muni.ics.oidc.BeanUtil;
|
||||||
|
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
||||||
|
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
|
import java.util.Properties;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class holding parameters for AuthProcFilter instantiation.
|
||||||
|
*
|
||||||
|
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AuthProcFilterInitContext {
|
||||||
|
|
||||||
|
public static final String PROP_CLASS = "class";
|
||||||
|
|
||||||
|
private final String filterName;
|
||||||
|
private final String filterPropertyPrefix;
|
||||||
|
private final Properties properties;
|
||||||
|
private final BeanUtil beanUtil;
|
||||||
|
|
||||||
|
public boolean hasProperty(String name) {
|
||||||
|
return this.properties.containsKey(filterPropertyPrefix + '.' + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProperty(String name) {
|
||||||
|
return this.properties.getProperty(filterPropertyPrefix + '.' + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProperty(String name, String defaultValue) {
|
||||||
|
if (this.properties.containsKey(filterPropertyPrefix + '.' + name)) {
|
||||||
|
return this.properties.getProperty(filterPropertyPrefix + '.' + name);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilterClass() {
|
||||||
|
return (String) properties.getOrDefault(filterPropertyPrefix + '.' + PROP_CLASS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PerunAdapter getPerunAdapterBean() {
|
||||||
|
return beanUtil.getBean(PerunAdapter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PerunOidcConfig getPerunOidcConfigBean() {
|
||||||
|
return beanUtil.getBean(PerunOidcConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,52 +0,0 @@
|
||||||
package cz.muni.ics.oidc.server.filters;
|
|
||||||
|
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class holding parameters for filter instantiation
|
|
||||||
*
|
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
|
||||||
*/
|
|
||||||
public class AuthProcFilterParams {
|
|
||||||
|
|
||||||
private final String filterName;
|
|
||||||
|
|
||||||
private final String propertyPrefix;
|
|
||||||
private final Properties properties;
|
|
||||||
private final BeanUtil beanUtil;
|
|
||||||
|
|
||||||
public AuthProcFilterParams(String filterName, String propertyPrefix, Properties properties, BeanUtil beanUtil) {
|
|
||||||
this.filterName = filterName;
|
|
||||||
this.propertyPrefix = propertyPrefix;
|
|
||||||
this.properties = properties;
|
|
||||||
this.beanUtil = beanUtil;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasProperty(String name) {
|
|
||||||
return this.properties.containsKey(propertyPrefix + '.' + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProperty(String name) {
|
|
||||||
return this.properties.getProperty(propertyPrefix + '.' + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProperty(String name, String defaultValue) {
|
|
||||||
if (this.properties.containsKey(propertyPrefix + '.' + name)) {
|
|
||||||
return this.properties.getProperty(propertyPrefix + '.' + name);
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BeanUtil getBeanUtil() {
|
|
||||||
return beanUtil;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilterName() {
|
|
||||||
return filterName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Properties getProperties() {
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cz.muni.ics.oidc.server.filters;
|
package cz.muni.ics.oidc.server.filters;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.AUTHORIZE_REQ_PATTERN;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.AUTHORIZE_REQ_PATTERN;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.DEVICE_APPROVE_REQ_PATTERN;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.DEVICE_APPROVE_REQ_PATTERN;
|
||||||
|
|
||||||
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
||||||
import cz.muni.ics.oauth2.service.ClientDetailsEntityService;
|
import cz.muni.ics.oauth2.service.ClientDetailsEntityService;
|
||||||
|
@ -23,6 +23,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
|
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
||||||
|
@ -31,7 +32,8 @@ import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.filter.GenericFilterBean;
|
import org.springframework.web.filter.GenericFilterBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This filter calls other Perun filters saved in the PerunFiltersContext
|
* Wrapper filter for the AuthProcFilters in the security chain. Takes care of providing most basic parameters
|
||||||
|
* and calls the custom AuthProcFilter chain.
|
||||||
*
|
*
|
||||||
* @author Dominik Baranek <baranek@ics.muni.cz>
|
* @author Dominik Baranek <baranek@ics.muni.cz>
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
||||||
|
@ -46,29 +48,34 @@ public class AuthProcFiltersContainer extends GenericFilterBean {
|
||||||
private static final RequestMatcher MATCHER = new OrRequestMatcher(
|
private static final RequestMatcher MATCHER = new OrRequestMatcher(
|
||||||
Arrays.asList(AUTHORIZE_MATCHER, AUTHORIZE_ALL_MATCHER, DEVICE_CODE_MATCHER, DEVICE_CODE_ALL_MATCHER));
|
Arrays.asList(AUTHORIZE_MATCHER, AUTHORIZE_ALL_MATCHER, DEVICE_CODE_MATCHER, DEVICE_CODE_ALL_MATCHER));
|
||||||
|
|
||||||
@Autowired
|
private final Properties properties;
|
||||||
private Properties coreProperties;
|
private final BeanUtil beanUtil;
|
||||||
|
private final OAuth2RequestFactory authRequestFactory;
|
||||||
|
private final ClientDetailsEntityService clientDetailsEntityService;
|
||||||
|
private final PerunAdapter perunAdapter;
|
||||||
|
private final SamlProperties samlProperties;
|
||||||
|
|
||||||
|
private List<AuthProcFilter> filters;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private BeanUtil beanUtil;
|
public AuthProcFiltersContainer(@Qualifier("coreProperties")Properties properties,
|
||||||
|
BeanUtil beanUtil,
|
||||||
@Autowired
|
OAuth2RequestFactory authRequestFactory,
|
||||||
private OAuth2RequestFactory authRequestFactory;
|
ClientDetailsEntityService clientDetailsEntityService,
|
||||||
|
PerunAdapter perunAdapter,
|
||||||
@Autowired
|
SamlProperties samlProperties)
|
||||||
private ClientDetailsEntityService clientDetailsEntityService;
|
{
|
||||||
|
this.properties = properties;
|
||||||
@Autowired
|
this.beanUtil = beanUtil;
|
||||||
private PerunAdapter perunAdapter;
|
this.authRequestFactory = authRequestFactory;
|
||||||
|
this.clientDetailsEntityService = clientDetailsEntityService;
|
||||||
@Autowired
|
this.perunAdapter = perunAdapter;
|
||||||
private SamlProperties samlProperties;
|
this.samlProperties = samlProperties;
|
||||||
|
}
|
||||||
private AuthProcFiltersContext perunFiltersContext;
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void postConstruct() {
|
public void postConstruct() {
|
||||||
this.perunFiltersContext = new AuthProcFiltersContext(coreProperties, beanUtil);
|
this.filters = AuthProcFiltersInitializer.initialize(properties, beanUtil);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,7 +87,6 @@ public class AuthProcFiltersContainer extends GenericFilterBean {
|
||||||
if (!MATCHER.matches(req)) {
|
if (!MATCHER.matches(req)) {
|
||||||
log.debug("AuthProc filters have been skipped, did not match authorization nor device req URL");
|
log.debug("AuthProc filters have been skipped, did not match authorization nor device req URL");
|
||||||
} else {
|
} else {
|
||||||
List<AuthProcFilter> filters = perunFiltersContext.getFilters();
|
|
||||||
if (filters != null && !filters.isEmpty()) {
|
if (filters != null && !filters.isEmpty()) {
|
||||||
ClientDetailsEntity client = FiltersUtils.extractClientFromRequest(req, authRequestFactory,
|
ClientDetailsEntity client = FiltersUtils.extractClientFromRequest(req, authRequestFactory,
|
||||||
clientDetailsEntityService);
|
clientDetailsEntityService);
|
||||||
|
@ -94,7 +100,7 @@ public class AuthProcFiltersContainer extends GenericFilterBean {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PerunUser user = FiltersUtils.getPerunUser(req, perunAdapter, samlProperties);
|
PerunUser user = FiltersUtils.getPerunUser(req, perunAdapter, samlProperties);
|
||||||
FilterParams params = new FilterParams(client, facility, user);
|
AuthProcFilterCommonVars params = new AuthProcFilterCommonVars(client, facility, user);
|
||||||
for (AuthProcFilter filter : filters) {
|
for (AuthProcFilter filter : filters) {
|
||||||
if (!filter.doFilter(req, res, params)) {
|
if (!filter.doFilter(req, res, params)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
package cz.muni.ics.oidc.server.filters;
|
|
||||||
|
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class that contains all custom Perun request filters. Filters are stored in the LinkedList
|
|
||||||
* and executed in the order they are added to the list.
|
|
||||||
*
|
|
||||||
* Filters are configured from configuration file in following way:
|
|
||||||
* filter.names=filterName1,filterName2,...
|
|
||||||
*
|
|
||||||
* @see AuthProcFilter for configuration of filter
|
|
||||||
*
|
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class AuthProcFiltersContext {
|
|
||||||
|
|
||||||
private static final String FILTER_NAMES = "filter.names";
|
|
||||||
private static final String FILTER_CLASS = ".class";
|
|
||||||
private static final String PREFIX = "filter.";
|
|
||||||
|
|
||||||
private final List<AuthProcFilter> filters;
|
|
||||||
private final Properties properties;
|
|
||||||
private final BeanUtil beanUtil;
|
|
||||||
|
|
||||||
public AuthProcFiltersContext(Properties properties, BeanUtil beanUtil) {
|
|
||||||
this.properties = properties;
|
|
||||||
this.beanUtil = beanUtil;
|
|
||||||
this.filters = new LinkedList<>();
|
|
||||||
|
|
||||||
String filterNames = properties.getProperty(FILTER_NAMES);
|
|
||||||
log.debug("Filters to be initialized '{}'", filterNames);
|
|
||||||
|
|
||||||
log.debug("--------------------------------");
|
|
||||||
for (String filterName: filterNames.split(",")) {
|
|
||||||
AuthProcFilter requestFilter = loadFilter(filterName);
|
|
||||||
filters.add(requestFilter);
|
|
||||||
log.debug("--------------------------------");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<AuthProcFilter> getFilters() {
|
|
||||||
return filters;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthProcFilter loadFilter(String filterName) {
|
|
||||||
String propPrefix = AuthProcFiltersContext.PREFIX + filterName;
|
|
||||||
String filterClass = properties.getProperty(propPrefix + FILTER_CLASS, null);
|
|
||||||
if (!StringUtils.hasText(filterClass)) {
|
|
||||||
log.warn("{} - failed to initialized filter: no class has ben configured", filterName);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
log.trace("{} - loading class '{}'", filterName, filterClass);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class<?> rawClazz = Class.forName(filterClass);
|
|
||||||
if (!AuthProcFilter.class.isAssignableFrom(rawClazz)) {
|
|
||||||
log.warn("{} - failed to initialized filter: class '{}' does not extend AuthProcFilter",
|
|
||||||
filterName, filterClass);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") Class<AuthProcFilter> clazz = (Class<AuthProcFilter>) rawClazz;
|
|
||||||
Constructor<AuthProcFilter> constructor = clazz.getConstructor(AuthProcFilterParams.class);
|
|
||||||
AuthProcFilterParams params = new AuthProcFilterParams(filterName, propPrefix, properties, beanUtil);
|
|
||||||
return constructor.newInstance(params);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
log.warn("{} - failed to initialize filter: class '{}' was not found", filterName, filterClass);
|
|
||||||
log.trace("{} - details:", filterName, e);
|
|
||||||
return null;
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
log.warn("{} - failed to initialize filter: class '{}' does not have proper constructor",
|
|
||||||
filterName, filterClass);
|
|
||||||
log.trace("{} - details:", filterName, e);
|
|
||||||
return null;
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
|
|
||||||
log.warn("{} - failed to initialize filter: class '{}' cannot be instantiated", filterName, filterClass);
|
|
||||||
log.trace("{} - details:", filterName, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package cz.muni.ics.oidc.server.filters;
|
||||||
|
|
||||||
|
import cz.muni.ics.oidc.BeanUtil;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization class for AuthProcFilters. Takes care of loading the filters and putting them into the custom
|
||||||
|
* authentication processing chain.
|
||||||
|
*
|
||||||
|
* @author Dominik Baranek <baranek@ics.muni.cz>
|
||||||
|
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class AuthProcFiltersInitializer {
|
||||||
|
|
||||||
|
private static final String FILTER_NAMES = "filter.names";
|
||||||
|
private static final String FILTERS_PROP_BASE_PREFIX = "filter.";
|
||||||
|
|
||||||
|
public static List<AuthProcFilter> initialize(Properties coreProperties, BeanUtil beanUtil) {
|
||||||
|
List<AuthProcFilter> filters = new LinkedList<>();
|
||||||
|
|
||||||
|
String filterNames = coreProperties.getProperty(FILTER_NAMES);
|
||||||
|
log.debug("Filters to be initialized '{}'", filterNames);
|
||||||
|
|
||||||
|
log.debug("--------------------------------");
|
||||||
|
for (String filterName: filterNames.split(",")) {
|
||||||
|
String filterPropertyPrefix = FILTERS_PROP_BASE_PREFIX + filterName;
|
||||||
|
AuthProcFilterInitContext ctx = new AuthProcFilterInitContext(filterName, filterPropertyPrefix, coreProperties, beanUtil);
|
||||||
|
AuthProcFilter requestFilter = loadFilter(ctx);
|
||||||
|
filters.add(requestFilter);
|
||||||
|
log.debug("--------------------------------");
|
||||||
|
}
|
||||||
|
return filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AuthProcFilter loadFilter(AuthProcFilterInitContext ctx) {
|
||||||
|
String filterClass = ctx.getFilterClass();
|
||||||
|
if (!StringUtils.hasText(filterClass)) {
|
||||||
|
log.warn("{} - failed to initialized filter: no class has ben configured", ctx.getFilterName());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
log.debug("{} - loading class '{}'", ctx.getFilterName(), filterClass);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class<?> rawClazz = Class.forName(filterClass);
|
||||||
|
if (!AuthProcFilter.class.isAssignableFrom(rawClazz)) {
|
||||||
|
log.warn("{} - failed to initialized filter: class '{}' does not extend AuthProcFilter",
|
||||||
|
ctx.getFilterName(), filterClass);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") Class<AuthProcFilter> clazz = (Class<AuthProcFilter>) rawClazz;
|
||||||
|
Constructor<AuthProcFilter> constructor = clazz.getConstructor(AuthProcFilterInitContext.class);
|
||||||
|
return constructor.newInstance(ctx);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
log.warn("{} - failed to initialize filter: class '{}' was not found", ctx.getFilterName(), filterClass);
|
||||||
|
log.debug("{} - details:", ctx.getFilterName(), e);
|
||||||
|
return null;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
log.warn("{} - failed to initialize filter: class '{}' does not have proper constructor",
|
||||||
|
ctx.getFilterName(), filterClass);
|
||||||
|
log.debug("{} - details:", ctx.getFilterName(), e);
|
||||||
|
return null;
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
|
||||||
|
log.warn("{} - failed to initialize filter: class '{}' cannot be instantiated", ctx.getFilterName(), filterClass);
|
||||||
|
log.debug("{} - details:", ctx.getFilterName(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package cz.muni.ics.oidc.server.filters;
|
package cz.muni.ics.oidc.server.filters;
|
||||||
|
|
||||||
import static cz.muni.ics.oauth2.web.endpoint.DeviceEndpoint.DEVICE_CODE_SESSION_ATTRIBUTE;
|
import static cz.muni.ics.oauth2.web.endpoint.DeviceEndpoint.DEVICE_CODE_SESSION_ATTRIBUTE;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_FORCE_AUTHN;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_FORCE_AUTHN;
|
||||||
|
|
||||||
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
||||||
import cz.muni.ics.oauth2.model.DeviceCode;
|
import cz.muni.ics.oauth2.model.DeviceCode;
|
||||||
|
@ -9,8 +9,11 @@ import cz.muni.ics.oauth2.service.ClientDetailsEntityService;
|
||||||
import cz.muni.ics.oidc.models.Facility;
|
import cz.muni.ics.oidc.models.Facility;
|
||||||
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
||||||
import cz.muni.ics.oidc.models.PerunUser;
|
import cz.muni.ics.oidc.models.PerunUser;
|
||||||
|
import cz.muni.ics.oidc.saml.SamlPrincipal;
|
||||||
import cz.muni.ics.oidc.saml.SamlProperties;
|
import cz.muni.ics.oidc.saml.SamlProperties;
|
||||||
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
||||||
|
import cz.muni.ics.oidc.server.claims.ClaimInitContext;
|
||||||
|
import cz.muni.ics.oidc.server.claims.ClaimSourceInitContext;
|
||||||
import cz.muni.ics.oidc.server.configurations.FacilityAttrsConfig;
|
import cz.muni.ics.oidc.server.configurations.FacilityAttrsConfig;
|
||||||
import cz.muni.ics.oidc.web.controllers.ControllerUtils;
|
import cz.muni.ics.oidc.web.controllers.ControllerUtils;
|
||||||
import cz.muni.ics.oidc.web.controllers.PerunUnapprovedRegistrationController;
|
import cz.muni.ics.oidc.web.controllers.PerunUnapprovedRegistrationController;
|
||||||
|
@ -35,6 +38,42 @@ import org.springframework.util.StringUtils;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class FiltersUtils {
|
public class FiltersUtils {
|
||||||
|
|
||||||
|
public static final String NO_VALUE = null;
|
||||||
|
|
||||||
|
public static String fillStringMandatoryProperty(String suffix, AuthProcFilterInitContext ctx) {
|
||||||
|
String filled = fillStringPropertyOrDefaultVal(ctx.getProperty(suffix, NO_VALUE), NO_VALUE);
|
||||||
|
|
||||||
|
if (filled == null) {
|
||||||
|
throw new IllegalArgumentException(ctx.getFilterName() + " - missing mandatory configuration option: " + suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String fillStringPropertyOrDefaultVal(String suffix, AuthProcFilterInitContext ctx, String defaultVal) {
|
||||||
|
return fillStringPropertyOrDefaultVal(ctx.getProperty(suffix, NO_VALUE), defaultVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String fillStringPropertyOrDefaultVal(String prop, String defaultVal) {
|
||||||
|
if (StringUtils.hasText(prop)) {
|
||||||
|
return prop;
|
||||||
|
} else {
|
||||||
|
return defaultVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean fillBooleanPropertyOrDefaultVal(String suffix, AuthProcFilterInitContext ctx, boolean defaultVal) {
|
||||||
|
return fillBooleanPropertyOrDefaultVal(ctx.getProperty(suffix, NO_VALUE), defaultVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean fillBooleanPropertyOrDefaultVal(String prop, boolean defaultVal) {
|
||||||
|
if (StringUtils.hasText(prop)) {
|
||||||
|
return Boolean.parseBoolean(prop);
|
||||||
|
} else {
|
||||||
|
return defaultVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create map of request params in format key = name, value = paramValue.
|
* Create map of request params in format key = name, value = paramValue.
|
||||||
*
|
*
|
||||||
|
@ -173,7 +212,7 @@ public class FiltersUtils {
|
||||||
} else if (!StringUtils.hasText(idAttribute)) {
|
} else if (!StringUtils.hasText(idAttribute)) {
|
||||||
throw new IllegalArgumentException("No identifier from SAML configured");
|
throw new IllegalArgumentException("No identifier from SAML configured");
|
||||||
}
|
}
|
||||||
String identifierAttrOid = PerunFilterConstants.SAML_IDS.getOrDefault(idAttribute, null);
|
String identifierAttrOid = AuthProcFilterConstants.SAML_IDS.getOrDefault(idAttribute, null);
|
||||||
if (identifierAttrOid == null) {
|
if (identifierAttrOid == null) {
|
||||||
throw new IllegalStateException("SAML credentials has no value for attribute: " + idAttribute);
|
throw new IllegalStateException("SAML credentials has no value for attribute: " + idAttribute);
|
||||||
}
|
}
|
||||||
|
@ -283,10 +322,11 @@ public class FiltersUtils {
|
||||||
PerunUser user,
|
PerunUser user,
|
||||||
String clientIdentifier,
|
String clientIdentifier,
|
||||||
FacilityAttrsConfig facilityAttrsConfig,
|
FacilityAttrsConfig facilityAttrsConfig,
|
||||||
Map<String, PerunAttributeValue> facilityAttributes,
|
|
||||||
PerunAdapter perunAdapter,
|
PerunAdapter perunAdapter,
|
||||||
String redirectUrl)
|
String redirectUrl)
|
||||||
{
|
{
|
||||||
|
Map<String, PerunAttributeValue> facilityAttributes = perunAdapter.getFacilityAttributeValues(
|
||||||
|
facility, facilityAttrsConfig.getMembershipAttrNames());
|
||||||
if (facilityAttributes.get(facilityAttrsConfig.getAllowRegistrationAttr()).valueAsBoolean()) {
|
if (facilityAttributes.get(facilityAttrsConfig.getAllowRegistrationAttr()).valueAsBoolean()) {
|
||||||
boolean canRegister = perunAdapter.getAdapterRpc().groupWhereCanRegisterExists(facility);
|
boolean canRegister = perunAdapter.getAdapterRpc().groupWhereCanRegisterExists(facility);
|
||||||
if (canRegister) {
|
if (canRegister) {
|
||||||
|
@ -316,7 +356,7 @@ public class FiltersUtils {
|
||||||
|
|
||||||
public static String fillStringMandatoryProperty(String propertyName,
|
public static String fillStringMandatoryProperty(String propertyName,
|
||||||
String filterName,
|
String filterName,
|
||||||
AuthProcFilterParams params) {
|
AuthProcFilterInitContext params) {
|
||||||
String filled = params.getProperty(propertyName);
|
String filled = params.getProperty(propertyName);
|
||||||
|
|
||||||
if (!StringUtils.hasText(filled)) {
|
if (!StringUtils.hasText(filled)) {
|
||||||
|
@ -366,4 +406,11 @@ public class FiltersUtils {
|
||||||
return new AbstractMap.SimpleImmutableEntry<>(key, value);
|
return new AbstractMap.SimpleImmutableEntry<>(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getUserIdentifier(HttpServletRequest req, String identifierSamlAttribute) {
|
||||||
|
return getExtLogin(getSamlCredential(req), identifierSamlAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getClientId(HttpServletRequest req) {
|
||||||
|
return req.getParameter(AuthProcFilterConstants.PARAM_CLIENT_ID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
package cz.muni.ics.oidc.server.filters;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class containing common constants used by Perun request filters.
|
|
||||||
*
|
|
||||||
* @author Dominik Baranek <baranek@ics.muni.cz>
|
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
|
||||||
*/
|
|
||||||
public class PerunFilterConstants {
|
|
||||||
|
|
||||||
public static final String AUTHORIZE_REQ_PATTERN = "/auth/authorize";
|
|
||||||
public static final String DEVICE_APPROVE_REQ_PATTERN = "/auth/device/authorize";
|
|
||||||
|
|
||||||
public static final String PARAM_CLIENT_ID = "client_id";
|
|
||||||
public static final String PARAM_SCOPE = "scope";
|
|
||||||
public static final String PARAM_MESSAGE = "message";
|
|
||||||
public static final String PARAM_HEADER = "header";
|
|
||||||
public static final String PARAM_TARGET = "target";
|
|
||||||
public static final String PARAM_FORCE_AUTHN = "forceAuthn";
|
|
||||||
public static final String PARAM_PROMPT = "prompt";
|
|
||||||
public static final String PARAM_REASON = "reason";
|
|
||||||
public static final String PARAM_ACCEPTED = "accepted";
|
|
||||||
public static final String PARAM_ACR_VALUES = "acr_values";
|
|
||||||
public static final String PARAM_POST_LOGOUT_REDIRECT_URI = "post_logout_redirect_uri";
|
|
||||||
public static final String PARAM_STATE = "state";
|
|
||||||
public static final String CLIENT_ID_PREFIX = "urn:cesnet:proxyidp:client_id:";
|
|
||||||
public static final String AARC_IDP_HINT = "aarc_idp_hint";
|
|
||||||
|
|
||||||
public static final String IDP_ENTITY_ID_PREFIX = "urn:cesnet:proxyidp:idpentityid:";
|
|
||||||
public static final String FILTER_PREFIX = "urn:cesnet:proxyidp:filter:";
|
|
||||||
public static final String EFILTER_PREFIX = "urn:cesnet:proxyidp:efilter:";
|
|
||||||
|
|
||||||
public static final String SAML_EPUID = "urn:oid:1.3.6.1.4.1.5923.1.1.1.13";
|
|
||||||
public static final String SAML_EPPN = "urn:oid:1.3.6.1.4.1.5923.1.1.1.6";
|
|
||||||
public static final String SAML_EPTID = "urn:oid:1.3.6.1.4.1.5923.1.1.1.10";
|
|
||||||
public static final String SAML_UID = "urn:oid:0.9.2342.19200300.100.1.1";
|
|
||||||
public static final String SAML_UNIQUE_IDENTIFIER = "urn:oid:0.9.2342.19200300.100.1.44";
|
|
||||||
public static final String SAML_PERUN_USERID_IDENTIFIER = "urn:cesnet:proxyidp:attribute:perunUserId";
|
|
||||||
|
|
||||||
public static final String REFEDS_MFA = "https://refeds.org/profile/mfa";
|
|
||||||
public static final String PROMPT_LOGIN = "login";
|
|
||||||
public static final String PROMPT_SELECT_ACCOUNT = "select_account";
|
|
||||||
|
|
||||||
public static final Map<String, String> SAML_IDS = new HashMap<>();
|
|
||||||
static {
|
|
||||||
SAML_IDS.put("eppn", SAML_EPPN);
|
|
||||||
SAML_IDS.put("epuid", SAML_EPUID);
|
|
||||||
SAML_IDS.put("eptid", SAML_EPTID);
|
|
||||||
SAML_IDS.put("uid", SAML_UID);
|
|
||||||
SAML_IDS.put("uniqueIdentifier", SAML_UNIQUE_IDENTIFIER);
|
|
||||||
SAML_IDS.put("perunUserId", SAML_PERUN_USERID_IDENTIFIER);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl;
|
|
||||||
|
|
||||||
import cz.muni.ics.oidc.server.filters.impl.mdc.RemoteAddressMDCFilter;
|
|
||||||
import cz.muni.ics.oidc.server.filters.impl.mdc.SessionIdMDCFilter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import javax.servlet.FilterChain;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletResponse;
|
|
||||||
import org.slf4j.MDC;
|
|
||||||
import org.springframework.web.filter.GenericFilterBean;
|
|
||||||
|
|
||||||
public class MultiMDCFilter extends GenericFilterBean {
|
|
||||||
|
|
||||||
private final RemoteAddressMDCFilter remoteAddressMDCFilter;
|
|
||||||
private final SessionIdMDCFilter sessionIdMDCFilter;
|
|
||||||
|
|
||||||
public MultiMDCFilter() {
|
|
||||||
this.remoteAddressMDCFilter = new RemoteAddressMDCFilter();
|
|
||||||
this.sessionIdMDCFilter = new SessionIdMDCFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
|
||||||
throws IOException, ServletException
|
|
||||||
{
|
|
||||||
remoteAddressMDCFilter.doFilter(servletRequest);
|
|
||||||
sessionIdMDCFilter.doFilter(servletRequest);
|
|
||||||
filterChain.doFilter(servletRequest, servletResponse);
|
|
||||||
MDC.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,17 +1,18 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl;
|
package cz.muni.ics.oidc.server.filters.impl;
|
||||||
|
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
import static cz.muni.ics.oidc.web.controllers.PerunUnapprovedController.UNAPPROVED_AUTHORIZATION;
|
||||||
|
|
||||||
|
import cz.muni.ics.oidc.exceptions.ConfigurationException;
|
||||||
import cz.muni.ics.oidc.models.Facility;
|
import cz.muni.ics.oidc.models.Facility;
|
||||||
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
||||||
import cz.muni.ics.oidc.models.PerunUser;
|
import cz.muni.ics.oidc.models.PerunUser;
|
||||||
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
||||||
import cz.muni.ics.oidc.server.configurations.FacilityAttrsConfig;
|
import cz.muni.ics.oidc.server.configurations.FacilityAttrsConfig;
|
||||||
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
import cz.muni.ics.oidc.server.filters.FilterParams;
|
|
||||||
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterCommonVars;
|
||||||
import cz.muni.ics.oidc.web.controllers.PerunUnapprovedController;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterInitContext;
|
||||||
|
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -25,44 +26,35 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
* Configuration:
|
* Configuration:
|
||||||
* - based on the configuration of bean "facilityAttrsConfig"
|
* - based on the configuration of bean "facilityAttrsConfig"
|
||||||
* @see FacilityAttrsConfig
|
* @see FacilityAttrsConfig
|
||||||
|
* @see cz.muni.ics.oidc.server.filters.AuthProcFilter (basic configuration options)
|
||||||
*
|
*
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PerunAuthorizationFilter extends AuthProcFilter {
|
public class PerunAuthorizationFilter extends AuthProcFilter {
|
||||||
|
|
||||||
public static final String APPLIED = "APPLIED_" + PerunAuthorizationFilter.class.getSimpleName();
|
|
||||||
|
|
||||||
private final PerunAdapter perunAdapter;
|
private final PerunAdapter perunAdapter;
|
||||||
private final FacilityAttrsConfig facilityAttrsConfig;
|
private final FacilityAttrsConfig facilityAttrsConfig;
|
||||||
private final String filterName;
|
|
||||||
private final PerunOidcConfig config;
|
private final PerunOidcConfig config;
|
||||||
|
|
||||||
public PerunAuthorizationFilter(AuthProcFilterParams params) {
|
public PerunAuthorizationFilter(AuthProcFilterInitContext ctx) throws ConfigurationException {
|
||||||
super(params);
|
super(ctx);
|
||||||
BeanUtil beanUtil = params.getBeanUtil();
|
this.perunAdapter = ctx.getPerunAdapterBean();
|
||||||
this.perunAdapter = beanUtil.getBean(PerunAdapter.class);
|
this.config = ctx.getPerunOidcConfigBean();
|
||||||
this.facilityAttrsConfig = beanUtil.getBean(FacilityAttrsConfig.class);
|
this.facilityAttrsConfig = ctx.getBeanUtil().getBean(FacilityAttrsConfig.class);
|
||||||
this.filterName = params.getFilterName();
|
|
||||||
this.config = beanUtil.getBean(PerunOidcConfig.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getSessionAppliedParamName() {
|
protected boolean process(HttpServletRequest req, HttpServletResponse res, AuthProcFilterCommonVars params) {
|
||||||
return APPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean process(HttpServletRequest req, HttpServletResponse res, FilterParams params) {
|
|
||||||
Facility facility = params.getFacility();
|
Facility facility = params.getFacility();
|
||||||
if (facility == null || facility.getId() == null) {
|
if (facility == null || facility.getId() == null) {
|
||||||
log.debug("{} - skip filter execution: no facility provided", filterName);
|
log.debug("{} - skip filter execution: no facility provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerunUser user = params.getUser();
|
PerunUser user = params.getUser();
|
||||||
if (user == null || user.getId() == null) {
|
if (user == null || user.getId() == null) {
|
||||||
log.debug("{} - skip filter execution: no user provided", filterName);
|
log.debug("{} - skip filter execution: no user provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,17 +70,16 @@ public class PerunAuthorizationFilter extends AuthProcFilter {
|
||||||
facility, facilityAttrsConfig.getMembershipAttrNames());
|
facility, facilityAttrsConfig.getMembershipAttrNames());
|
||||||
|
|
||||||
if (!facilityAttributes.get(facilityAttrsConfig.getCheckGroupMembershipAttr()).valueAsBoolean()) {
|
if (!facilityAttributes.get(facilityAttrsConfig.getCheckGroupMembershipAttr()).valueAsBoolean()) {
|
||||||
log.debug("{} - skip filter execution: membership check not requested", filterName);
|
log.debug("{} - skip filter execution: membership check not requested", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perunAdapter.canUserAccessBasedOnMembership(facility, user.getId())) {
|
if (perunAdapter.canUserAccessBasedOnMembership(facility, user.getId())) {
|
||||||
log.info("{} - user allowed to access the service", filterName);
|
log.info("{} - user allowed to access the service", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
FiltersUtils.redirectUserCannotAccess(config.getConfigBean().getIssuer(), response, facility, user, clientIdentifier,
|
FiltersUtils.redirectUserCannotAccess(config.getConfigBean().getIssuer(), response, facility, user,
|
||||||
facilityAttrsConfig, facilityAttributes, perunAdapter,
|
clientIdentifier, facilityAttrsConfig, perunAdapter, UNAPPROVED_AUTHORIZATION);
|
||||||
PerunUnapprovedController.UNAPPROVED_AUTHORIZATION);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl;
|
package cz.muni.ics.oidc.server.filters.impl;
|
||||||
|
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
import cz.muni.ics.oidc.PerunConstants;
|
||||||
|
import cz.muni.ics.oidc.exceptions.ConfigurationException;
|
||||||
import cz.muni.ics.oidc.models.Facility;
|
import cz.muni.ics.oidc.models.Facility;
|
||||||
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
||||||
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
||||||
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
import cz.muni.ics.oidc.server.filters.FilterParams;
|
|
||||||
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterInitContext;
|
||||||
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterCommonVars;
|
||||||
|
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
||||||
import cz.muni.ics.oidc.web.controllers.ControllerUtils;
|
import cz.muni.ics.oidc.web.controllers.ControllerUtils;
|
||||||
import cz.muni.ics.oidc.web.controllers.PerunUnapprovedController;
|
import cz.muni.ics.oidc.web.controllers.PerunUnapprovedController;
|
||||||
import cz.muni.ics.oidc.web.controllers.RegistrationController;
|
import cz.muni.ics.oidc.web.controllers.RegistrationController;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -26,6 +28,7 @@ import org.springframework.util.StringUtils;
|
||||||
* Otherwise, user can to access the service.
|
* Otherwise, user can to access the service.
|
||||||
*
|
*
|
||||||
* Configuration (replace [name] part with the name defined for the filter):
|
* Configuration (replace [name] part with the name defined for the filter):
|
||||||
|
* @see cz.muni.ics.oidc.server.filters.AuthProcFilter (basic configuration options)
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><b>filter.[name].triggerAttr</b> - mapping to attribute which contains flag if this is enabled for facility</li>
|
* <li><b>filter.[name].triggerAttr</b> - mapping to attribute which contains flag if this is enabled for facility</li>
|
||||||
* <li><b>filter.[name].voDefsAttr</b> - mapping to attribute which contains VO(s) to check</li>
|
* <li><b>filter.[name].voDefsAttr</b> - mapping to attribute which contains VO(s) to check</li>
|
||||||
|
@ -36,8 +39,6 @@ import org.springframework.util.StringUtils;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PerunEnsureVoMember extends AuthProcFilter {
|
public class PerunEnsureVoMember extends AuthProcFilter {
|
||||||
|
|
||||||
public static final String APPLIED = "APPLIED_" + PerunEnsureVoMember.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final String TRIGGER_ATTR = "triggerAttr";
|
private static final String TRIGGER_ATTR = "triggerAttr";
|
||||||
private static final String VO_DEFS_ATTR = "voDefsAttr";
|
private static final String VO_DEFS_ATTR = "voDefsAttr";
|
||||||
private static final String LOGIN_URL_ATTR = "loginURL";
|
private static final String LOGIN_URL_ATTR = "loginURL";
|
||||||
|
@ -46,50 +47,45 @@ public class PerunEnsureVoMember extends AuthProcFilter {
|
||||||
private final String voDefsAttr;
|
private final String voDefsAttr;
|
||||||
private final String loginUrlAttr;
|
private final String loginUrlAttr;
|
||||||
private final PerunAdapter perunAdapter;
|
private final PerunAdapter perunAdapter;
|
||||||
private final String filterName;
|
|
||||||
private final PerunOidcConfig perunOidcConfig;
|
private final PerunOidcConfig perunOidcConfig;
|
||||||
|
|
||||||
public PerunEnsureVoMember(AuthProcFilterParams params) {
|
public PerunEnsureVoMember(AuthProcFilterInitContext ctx) throws ConfigurationException {
|
||||||
super(params);
|
super(ctx);
|
||||||
BeanUtil beanUtil = params.getBeanUtil();
|
this.perunOidcConfig = ctx.getPerunOidcConfigBean();
|
||||||
|
this.perunAdapter = ctx.getPerunAdapterBean();
|
||||||
|
|
||||||
this.perunOidcConfig = beanUtil.getBean(PerunOidcConfig.class);
|
this.triggerAttr = FiltersUtils.fillStringMandatoryProperty(TRIGGER_ATTR, ctx);
|
||||||
this.perunAdapter = beanUtil.getBean(PerunAdapter.class);
|
this.voDefsAttr = FiltersUtils.fillStringMandatoryProperty(VO_DEFS_ATTR, ctx);
|
||||||
this.filterName = params.getFilterName();
|
this.loginUrlAttr = FiltersUtils.fillStringPropertyOrDefaultVal(LOGIN_URL_ATTR, ctx, null);
|
||||||
|
|
||||||
this.triggerAttr = FiltersUtils.fillStringMandatoryProperty(TRIGGER_ATTR, filterName, params);
|
|
||||||
this.voDefsAttr = FiltersUtils.fillStringMandatoryProperty(VO_DEFS_ATTR, filterName, params);
|
|
||||||
|
|
||||||
this.loginUrlAttr = params.getProperty(LOGIN_URL_ATTR);
|
|
||||||
log.debug("{} - initialized filter: {}", filterName, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getSessionAppliedParamName() {
|
protected boolean process(HttpServletRequest req, HttpServletResponse res, AuthProcFilterCommonVars params) {
|
||||||
return APPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean process(HttpServletRequest req, HttpServletResponse res, FilterParams params) {
|
|
||||||
Facility facility = params.getFacility();
|
Facility facility = params.getFacility();
|
||||||
if (facility == null || facility.getId() == null) {
|
if (facility == null || facility.getId() == null) {
|
||||||
log.debug("{} - skip execution: no facility provided", filterName);
|
log.debug("{} - skip execution: no facility provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, PerunAttributeValue> attrs = perunAdapter.getFacilityAttributeValues(facility,
|
List<String> attrsToFetch = Arrays.asList(voDefsAttr, triggerAttr, loginUrlAttr);
|
||||||
Arrays.asList(voDefsAttr, triggerAttr, loginUrlAttr));
|
Map<String, PerunAttributeValue> attrs = perunAdapter.getFacilityAttributeValues(facility, attrsToFetch);
|
||||||
|
|
||||||
|
if (attrs == null) {
|
||||||
|
log.debug("{} - skip filter execution: could not fetch attributes '{}' for facility '{}'",
|
||||||
|
getFilterName(), attrsToFetch, facility);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
PerunAttributeValue triggerAttrValue = attrs.getOrDefault(triggerAttr, null);
|
PerunAttributeValue triggerAttrValue = attrs.getOrDefault(triggerAttr, null);
|
||||||
if (triggerAttrValue == null || !triggerAttrValue.valueAsBoolean()) {
|
if (triggerAttrValue == null || !triggerAttrValue.valueAsBoolean()) {
|
||||||
log.debug("{} - skip execution: attribute '{}' is null or false, which disables the filter",
|
log.debug("{} - skip execution: attribute '{}' is null or false, which disables the filter",
|
||||||
filterName, triggerAttr);
|
getFilterName(), triggerAttr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerunAttributeValue voDefsAttrValue = getVoDefsAttrValue(attrs.getOrDefault(voDefsAttr, null));
|
PerunAttributeValue voDefsAttrValue = getVoDefsAttrValue(attrs.getOrDefault(voDefsAttr, null));
|
||||||
if (voDefsAttrValue == null) {
|
if (voDefsAttrValue == null) {
|
||||||
log.debug("{} - skip execution: attribute '{}' has null or no value", filterName, voDefsAttr);
|
log.debug("{} - skip execution: attribute '{}' has null or no value", getFilterName(), voDefsAttr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
String voShortName = voDefsAttrValue.valueAsString();
|
String voShortName = voDefsAttrValue.valueAsString();
|
||||||
|
@ -97,7 +93,7 @@ public class PerunEnsureVoMember extends AuthProcFilter {
|
||||||
boolean canAccess = perunAdapter.isUserInVo(params.getUser().getId(), voShortName);
|
boolean canAccess = perunAdapter.isUserInVo(params.getUser().getId(), voShortName);
|
||||||
|
|
||||||
if (canAccess) {
|
if (canAccess) {
|
||||||
log.debug("{} - user allowed to continue", filterName);
|
log.debug("{} - user allowed to continue", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
redirect(res, getLoginUrl(facility.getId()), voShortName);
|
redirect(res, getLoginUrl(facility.getId()), voShortName);
|
||||||
|
@ -144,10 +140,11 @@ public class PerunEnsureVoMember extends AuthProcFilter {
|
||||||
private void redirectDirectly(HttpServletResponse res, String loginUrl, String voShortName) {
|
private void redirectDirectly(HttpServletResponse res, String loginUrl, String voShortName) {
|
||||||
String registrarUrl = perunOidcConfig.getRegistrarUrl();
|
String registrarUrl = perunOidcConfig.getRegistrarUrl();
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("vo", voShortName);
|
params.put(PerunConstants.REGISTRAR_PARAM_VO, voShortName);
|
||||||
if (StringUtils.hasText(loginUrl)) {
|
if (StringUtils.hasText(loginUrl)) {
|
||||||
params.put("targetnew", loginUrl);
|
params.put(PerunConstants.REGISTRAR_TARGET_NEW, loginUrl);
|
||||||
params.put("targetexisting", loginUrl);
|
params.put(PerunConstants.REGISTRAR_TARGET_EXISTING, loginUrl);
|
||||||
|
params.put(PerunConstants.REGISTRAR_TARGET_EXTENDED, loginUrl);
|
||||||
}
|
}
|
||||||
String target = ControllerUtils.createUrl(registrarUrl, params);
|
String target = ControllerUtils.createUrl(registrarUrl, params);
|
||||||
|
|
||||||
|
@ -156,7 +153,7 @@ public class PerunEnsureVoMember extends AuthProcFilter {
|
||||||
params.put(RegistrationController.PARAM_TARGET, target);
|
params.put(RegistrationController.PARAM_TARGET, target);
|
||||||
|
|
||||||
String redirectUrl = ControllerUtils.createUrl(url, params);
|
String redirectUrl = ControllerUtils.createUrl(url, params);
|
||||||
log.debug("{} - redirecting user to '{}'", filterName, redirectUrl);
|
log.debug("{} - redirecting user to '{}'", getFilterName(), redirectUrl);
|
||||||
res.reset();
|
res.reset();
|
||||||
res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
||||||
res.setHeader(HttpHeaders.LOCATION, redirectUrl);
|
res.setHeader(HttpHeaders.LOCATION, redirectUrl);
|
||||||
|
@ -166,7 +163,7 @@ public class PerunEnsureVoMember extends AuthProcFilter {
|
||||||
String redirectUrl = ControllerUtils.constructRequestUrl(perunOidcConfig,
|
String redirectUrl = ControllerUtils.constructRequestUrl(perunOidcConfig,
|
||||||
PerunUnapprovedController.UNAPPROVED_ENSURE_VO_MAPPING);
|
PerunUnapprovedController.UNAPPROVED_ENSURE_VO_MAPPING);
|
||||||
|
|
||||||
log.debug("{} - redirecting user to '{}'", filterName, redirectUrl);
|
log.debug("{} - redirecting user to '{}'", getFilterName(), redirectUrl);
|
||||||
res.reset();
|
res.reset();
|
||||||
res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
||||||
res.setHeader(HttpHeaders.LOCATION, redirectUrl);
|
res.setHeader(HttpHeaders.LOCATION, redirectUrl);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import static cz.muni.ics.oidc.web.controllers.AupController.APPROVED;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
import cz.muni.ics.oidc.BeanUtil;
|
||||||
|
import cz.muni.ics.oidc.exceptions.ConfigurationException;
|
||||||
import cz.muni.ics.oidc.models.Aup;
|
import cz.muni.ics.oidc.models.Aup;
|
||||||
import cz.muni.ics.oidc.models.Facility;
|
import cz.muni.ics.oidc.models.Facility;
|
||||||
import cz.muni.ics.oidc.models.PerunAttribute;
|
import cz.muni.ics.oidc.models.PerunAttribute;
|
||||||
|
@ -12,10 +13,10 @@ import cz.muni.ics.oidc.models.PerunUser;
|
||||||
import cz.muni.ics.oidc.saml.SamlProperties;
|
import cz.muni.ics.oidc.saml.SamlProperties;
|
||||||
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
||||||
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
import cz.muni.ics.oidc.server.filters.FilterParams;
|
|
||||||
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterCommonVars;
|
||||||
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterInitContext;
|
||||||
|
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
||||||
import cz.muni.ics.oidc.web.controllers.AupController;
|
import cz.muni.ics.oidc.web.controllers.AupController;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
@ -36,6 +37,7 @@ import org.springframework.util.StringUtils;
|
||||||
* AUP filter checks if there are new AUPs which user hasn't accepted yet and forces him to do that.
|
* AUP filter checks if there are new AUPs which user hasn't accepted yet and forces him to do that.
|
||||||
*
|
*
|
||||||
* Configuration (replace [name] part with the name defined for the filter):
|
* Configuration (replace [name] part with the name defined for the filter):
|
||||||
|
* @see cz.muni.ics.oidc.server.filters.AuthProcFilter (basic configuration options)
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><b>filter.[name].orgAupsAttrName</b> - Mapping to Perun entityless attribute containing organization AUPs</li>
|
* <li><b>filter.[name].orgAupsAttrName</b> - Mapping to Perun entityless attribute containing organization AUPs</li>
|
||||||
* <li><b>filter.[name].userAupsAttrName</b> - Mapping to Perun user attribute containing list of AUPS approved by user</li>
|
* <li><b>filter.[name].userAupsAttrName</b> - Mapping to Perun user attribute containing list of AUPS approved by user</li>
|
||||||
|
@ -52,8 +54,6 @@ import org.springframework.util.StringUtils;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PerunForceAupFilter extends AuthProcFilter {
|
public class PerunForceAupFilter extends AuthProcFilter {
|
||||||
|
|
||||||
public static final String APPLIED = "APPLIED_" + PerunForceAupFilter.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final String DATE_FORMAT = "yyyy-MM-dd";
|
private static final String DATE_FORMAT = "yyyy-MM-dd";
|
||||||
|
|
||||||
/* CONFIGURATION PROPERTIES */
|
/* CONFIGURATION PROPERTIES */
|
||||||
|
@ -75,46 +75,39 @@ public class PerunForceAupFilter extends AuthProcFilter {
|
||||||
private final PerunAdapter perunAdapter;
|
private final PerunAdapter perunAdapter;
|
||||||
private final PerunOidcConfig perunOidcConfig;
|
private final PerunOidcConfig perunOidcConfig;
|
||||||
private final SamlProperties samlProperties;
|
private final SamlProperties samlProperties;
|
||||||
private final String filterName;
|
|
||||||
|
|
||||||
public PerunForceAupFilter(AuthProcFilterParams params) {
|
public PerunForceAupFilter(AuthProcFilterInitContext ctx) throws ConfigurationException {
|
||||||
super(params);
|
super(ctx);
|
||||||
BeanUtil beanUtil = params.getBeanUtil();
|
BeanUtil beanUtil = ctx.getBeanUtil();
|
||||||
this.perunAdapter = beanUtil.getBean(PerunAdapter.class);
|
this.perunAdapter = ctx.getPerunAdapterBean();
|
||||||
this.perunOidcConfig = beanUtil.getBean(PerunOidcConfig.class);
|
this.perunOidcConfig = ctx.getPerunOidcConfigBean();
|
||||||
this.samlProperties = beanUtil.getBean(SamlProperties.class);
|
this.samlProperties = beanUtil.getBean(SamlProperties.class);
|
||||||
|
|
||||||
this.perunOrgAupsAttrName = params.getProperty(ORG_AUPS_ATTR_NAME);
|
this.perunOrgAupsAttrName = FiltersUtils.fillStringMandatoryProperty(ORG_AUPS_ATTR_NAME, ctx);
|
||||||
this.perunUserAupsAttrName = params.getProperty(USER_AUPS_ATTR_NAME);
|
this.perunUserAupsAttrName = FiltersUtils.fillStringMandatoryProperty(USER_AUPS_ATTR_NAME, ctx);
|
||||||
this.perunVoAupAttrName = params.getProperty(VO_AUP_ATTR_NAME);
|
this.perunVoAupAttrName = FiltersUtils.fillStringMandatoryProperty(VO_AUP_ATTR_NAME, ctx);
|
||||||
this.perunFacilityRequestedAupsAttrName = params.getProperty(FACILITY_REQUESTED_AUPS_ATTR_NAME);
|
this.perunFacilityRequestedAupsAttrName = FiltersUtils.fillStringMandatoryProperty(FACILITY_REQUESTED_AUPS_ATTR_NAME, ctx);
|
||||||
this.perunFacilityVoShortNamesAttrName = params.getProperty(VO_SHORT_NAMES_ATTR_NAME);
|
this.perunFacilityVoShortNamesAttrName = FiltersUtils.fillStringMandatoryProperty(VO_SHORT_NAMES_ATTR_NAME, ctx);
|
||||||
this.filterName = params.getFilterName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getSessionAppliedParamName() {
|
protected boolean process(HttpServletRequest req, HttpServletResponse res, AuthProcFilterCommonVars params) throws IOException {
|
||||||
return APPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean process(HttpServletRequest req, HttpServletResponse res, FilterParams params) throws IOException {
|
|
||||||
if (req.getSession() != null && req.getSession().getAttribute(APPROVED) != null) {
|
if (req.getSession() != null && req.getSession().getAttribute(APPROVED) != null) {
|
||||||
req.getSession().removeAttribute(APPROVED);
|
req.getSession().removeAttribute(APPROVED);
|
||||||
log.debug("{} - skip filter execution: aups are already approved, check at next access to the service due" +
|
log.debug("{} - skip filter execution: aups are already approved, check at next access to the service due" +
|
||||||
" to a delayed propagation to LDAP", filterName);
|
" to a delayed propagation to LDAP", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerunUser user = FiltersUtils.getPerunUser(req, perunAdapter, samlProperties);
|
PerunUser user = FiltersUtils.getPerunUser(req, perunAdapter, samlProperties);
|
||||||
if (user == null || user.getId() == null) {
|
if (user == null || user.getId() == null) {
|
||||||
log.debug("{} - skip filter execution: no user provider", filterName);
|
log.debug("{} - skip filter execution: no user provider", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Facility facility = params.getFacility();
|
Facility facility = params.getFacility();
|
||||||
if (facility == null || facility.getId() == null) {
|
if (facility == null || facility.getId() == null) {
|
||||||
log.debug("{} - skip filter execution: no facility provider", filterName);
|
log.debug("{} - skip filter execution: no facility provider", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,13 +117,13 @@ public class PerunForceAupFilter extends AuthProcFilter {
|
||||||
|
|
||||||
if (facilityAttributes == null) {
|
if (facilityAttributes == null) {
|
||||||
log.debug("{} - skip filter execution: could not fetch attributes '{}' for facility '{}'",
|
log.debug("{} - skip filter execution: could not fetch attributes '{}' for facility '{}'",
|
||||||
filterName, attrsToFetch, facility);
|
getFilterName(), attrsToFetch, facility);
|
||||||
return true;
|
return true;
|
||||||
} else if (!facilityAttributes.containsKey(perunFacilityRequestedAupsAttrName) &&
|
} else if (!facilityAttributes.containsKey(perunFacilityRequestedAupsAttrName) &&
|
||||||
!facilityAttributes.containsKey(perunFacilityVoShortNamesAttrName))
|
!facilityAttributes.containsKey(perunFacilityVoShortNamesAttrName))
|
||||||
{
|
{
|
||||||
log.debug("{} - skip filter execution: could not fetch required attributes '{}' and '{}' for facility '{}'",
|
log.debug("{} - skip filter execution: could not fetch required attributes '{}' and '{}' for facility '{}'",
|
||||||
filterName, perunFacilityRequestedAupsAttrName, perunFacilityVoShortNamesAttrName, facility);
|
getFilterName(), perunFacilityRequestedAupsAttrName, perunFacilityVoShortNamesAttrName, facility);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,30 +132,36 @@ public class PerunForceAupFilter extends AuthProcFilter {
|
||||||
try {
|
try {
|
||||||
newAups = getAupsToApprove(user, facilityAttributes);
|
newAups = getAupsToApprove(user, facilityAttributes);
|
||||||
} catch (ParseException | IOException e) {
|
} catch (ParseException | IOException e) {
|
||||||
log.warn("{} - caught parse exception when processing AUPs to approve", filterName);
|
log.warn("{} - caught parse exception when processing AUPs to approve", getFilterName());
|
||||||
log.trace("{} - details:", filterName, e);
|
log.debug("{} - details:", getFilterName(), e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newAups.isEmpty()) {
|
if (!newAups.isEmpty()) {
|
||||||
log.debug("{} - user has to approve some AUPs", filterName);
|
log.info("{} - user has to approve some AUPs", getFilterName());
|
||||||
log.trace("{} - AUPS to be approved: '{}'", filterName, newAups);
|
log.debug("{} - AUPS to be approved: '{}'", getFilterName(), newAups);
|
||||||
String newAupsString = mapper.writeValueAsString(newAups);
|
redirectToApproval(req, res, newAups, user);
|
||||||
|
|
||||||
req.getSession().setAttribute(AupController.RETURN_URL, req.getRequestURI()
|
|
||||||
.replace(req.getContextPath(), "") + '?' + req.getQueryString());
|
|
||||||
req.getSession().setAttribute(AupController.NEW_AUPS, newAupsString);
|
|
||||||
req.getSession().setAttribute(AupController.USER_ATTR, perunUserAupsAttrName);
|
|
||||||
|
|
||||||
log.debug("{} - redirecting user '{}' to AUPs approval page", filterName, user);
|
|
||||||
res.sendRedirect(req.getContextPath() + '/' + AupController.URL);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("{} - no need to approve any AUPs", filterName);
|
log.debug("{} - no need to approve any AUPs", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void redirectToApproval(HttpServletRequest req, HttpServletResponse res, Map<String, Aup> newAups,
|
||||||
|
PerunUser user) throws IOException
|
||||||
|
{
|
||||||
|
String newAupsString = mapper.writeValueAsString(newAups);
|
||||||
|
|
||||||
|
req.getSession().setAttribute(AupController.RETURN_URL, req.getRequestURI()
|
||||||
|
.replace(req.getContextPath(), "") + '?' + req.getQueryString());
|
||||||
|
req.getSession().setAttribute(AupController.NEW_AUPS, newAupsString);
|
||||||
|
req.getSession().setAttribute(AupController.USER_ATTR, perunUserAupsAttrName);
|
||||||
|
|
||||||
|
log.debug("{} - redirecting user '{}' to AUPs approval page", getFilterName(), user);
|
||||||
|
res.sendRedirect(req.getContextPath() + '/' + AupController.URL);
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Aup> getAupsToApprove(PerunUser user, Map<String, PerunAttributeValue> facilityAttributes)
|
private Map<String, Aup> getAupsToApprove(PerunUser user, Map<String, PerunAttributeValue> facilityAttributes)
|
||||||
throws ParseException, IOException
|
throws ParseException, IOException
|
||||||
{
|
{
|
||||||
|
@ -220,12 +219,12 @@ public class PerunForceAupFilter extends AuthProcFilter {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.debug("{} - need to approve AUP with key '{}' ({})", filterName, keyToVoAup.getKey(), voLatestAup);
|
log.debug("{} - need to approve AUP with key '{}' ({})", getFilterName(), keyToVoAup.getKey(), voLatestAup);
|
||||||
aupsToApprove.put(keyToVoAup.getKey(), voLatestAup);
|
aupsToApprove.put(keyToVoAup.getKey(), voLatestAup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.trace("{} - VO AUPs to approve: {}", filterName, aupsToApprove);
|
log.trace("{} - VO AUPs to approve: {}", getFilterName(), aupsToApprove);
|
||||||
return aupsToApprove;
|
return aupsToApprove;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +245,7 @@ public class PerunForceAupFilter extends AuthProcFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.debug("{} - Mapped ORG aups: {}", filterName, orgAups);
|
log.debug("{} - Mapped ORG aups: {}", getFilterName(), orgAups);
|
||||||
|
|
||||||
if (!orgAups.isEmpty()) {
|
if (!orgAups.isEmpty()) {
|
||||||
for (String requiredOrgAupKey : requestedAups) {
|
for (String requiredOrgAupKey : requestedAups) {
|
||||||
|
@ -260,12 +259,12 @@ public class PerunForceAupFilter extends AuthProcFilter {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.debug("{} - need to approve AUP with key '{}' ({})", filterName, requiredOrgAupKey, orgLatestAup);
|
log.debug("{} - need to approve AUP with key '{}' ({})", getFilterName(), requiredOrgAupKey, orgLatestAup);
|
||||||
aupsToApprove.put(requiredOrgAupKey, orgLatestAup);
|
aupsToApprove.put(requiredOrgAupKey, orgLatestAup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("{} - ORG AUPs to approve: {}", filterName, aupsToApprove);
|
log.debug("{} - ORG AUPs to approve: {}", getFilterName(), aupsToApprove);
|
||||||
return aupsToApprove;
|
return aupsToApprove;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl;
|
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_FORCE_AUTHN;
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_REASON;
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_SCOPE;
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_TARGET;
|
|
||||||
import static cz.muni.ics.oidc.web.controllers.PerunUnapprovedController.REASON_EXPIRED;
|
|
||||||
import static cz.muni.ics.oidc.web.controllers.PerunUnapprovedController.REASON_NOT_SET;
|
|
||||||
|
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
|
||||||
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
|
||||||
import cz.muni.ics.oidc.models.PerunUser;
|
|
||||||
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
|
||||||
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
|
||||||
import cz.muni.ics.oidc.server.filters.FilterParams;
|
|
||||||
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilterParams;
|
|
||||||
import cz.muni.ics.oidc.web.controllers.ControllerUtils;
|
|
||||||
import cz.muni.ics.oidc.web.controllers.PerunUnapprovedController;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.time.format.DateTimeParseException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.http.HttpHeaders;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This filter verifies that user attribute isCesnetEligible is not older than given time frame.
|
|
||||||
* In case the value is older, denies access to the service and forces user to use verified identity.
|
|
||||||
* Otherwise, user can to access the service.
|
|
||||||
*
|
|
||||||
* Configuration (replace [name] part with the name defined for the filter):
|
|
||||||
* <ul>
|
|
||||||
* <li><b>filter.[name].isCesnetEligibleAttr</b> - mapping to isCesnetEligible attribute</li>
|
|
||||||
* <li><b>filter.[name].validityPeriod</b> - specify in months, how long the value can be old, if no value
|
|
||||||
* or invalid value has been provided, defaults to 12 months</li>
|
|
||||||
* </ul>
|
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class PerunIsCesnetEligibleFilter extends AuthProcFilter {
|
|
||||||
|
|
||||||
public static final String APPLIED = "APPLIED_" + PerunIsCesnetEligibleFilter.class.getSimpleName();
|
|
||||||
|
|
||||||
/* CONFIGURATION PROPERTIES */
|
|
||||||
private static final String IS_CESNET_ELIGIBLE_ATTR_NAME = "isCesnetEligibleAttr";
|
|
||||||
private static final String IS_CESNET_ELIGIBLE_SCOPE = "isCesnetEligibleScope";
|
|
||||||
private static final String VALIDITY_PERIOD = "validityPeriod";
|
|
||||||
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
|
||||||
|
|
||||||
private final String isCesnetEligibleAttrName;
|
|
||||||
private final String triggerScope;
|
|
||||||
private final int validityPeriod;
|
|
||||||
/* END OF CONFIGURATION PROPERTIES */
|
|
||||||
|
|
||||||
private final PerunOidcConfig config;
|
|
||||||
private final PerunAdapter perunAdapter;
|
|
||||||
private final String filterName;
|
|
||||||
|
|
||||||
public PerunIsCesnetEligibleFilter(AuthProcFilterParams params) {
|
|
||||||
super(params);
|
|
||||||
BeanUtil beanUtil = params.getBeanUtil();
|
|
||||||
this.config = beanUtil.getBean(PerunOidcConfig.class);
|
|
||||||
this.perunAdapter = beanUtil.getBean(PerunAdapter.class);
|
|
||||||
this.isCesnetEligibleAttrName = params.getProperty(IS_CESNET_ELIGIBLE_ATTR_NAME);
|
|
||||||
this.triggerScope = params.getProperty(IS_CESNET_ELIGIBLE_SCOPE);
|
|
||||||
int validityPeriodParam = 12;
|
|
||||||
if (params.hasProperty(VALIDITY_PERIOD)) {
|
|
||||||
try {
|
|
||||||
validityPeriodParam = Integer.parseInt(params.getProperty(VALIDITY_PERIOD));
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
//no problem, we have default value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.validityPeriod = validityPeriodParam;
|
|
||||||
this.filterName = params.getFilterName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getSessionAppliedParamName() {
|
|
||||||
return APPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean process(HttpServletRequest req, HttpServletResponse res, FilterParams params) {
|
|
||||||
if (!FiltersUtils.isScopePresent(req.getParameter(PARAM_SCOPE), triggerScope)) {
|
|
||||||
log.debug("{} - skip execution: scope '{}' is not present in request", filterName, triggerScope);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PerunUser user = params.getUser();
|
|
||||||
if (user == null || user.getId() == null) {
|
|
||||||
log.debug("{} - skip execution: no user provider", filterName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String reason = REASON_NOT_SET;
|
|
||||||
PerunAttributeValue attrValue = perunAdapter.getUserAttributeValue(user.getId(), isCesnetEligibleAttrName);
|
|
||||||
if (attrValue != null) {
|
|
||||||
LocalDateTime timeStamp;
|
|
||||||
try {
|
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
|
|
||||||
timeStamp = LocalDateTime.parse(attrValue.valueAsString(), formatter);
|
|
||||||
} catch (DateTimeParseException e) {
|
|
||||||
log.warn("{} - could not parse timestamp from attribute '{}' value: '{}'",
|
|
||||||
filterName, isCesnetEligibleAttrName, attrValue.valueAsString());
|
|
||||||
log.debug("{} - skip execution: no timestamp to compare to", filterName);
|
|
||||||
log.trace("{} - details:", filterName, e);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
if (now.minusMonths(validityPeriod).isBefore(timeStamp)) {
|
|
||||||
log.debug("{} - attribute '{}' value is valid", filterName, isCesnetEligibleAttrName);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
reason = REASON_EXPIRED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("{} - attribute '{}' value is invalid, stop user at this point", filterName, attrValue);
|
|
||||||
this.redirect(req, res, reason);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void redirect(HttpServletRequest req, HttpServletResponse res, String reason) {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
|
|
||||||
String targetURL = FiltersUtils.buildRequestURL(req, Collections.singletonMap(PARAM_FORCE_AUTHN, "true"));
|
|
||||||
params.put(PARAM_TARGET, targetURL);
|
|
||||||
params.put(PARAM_REASON, reason);
|
|
||||||
|
|
||||||
String redirectUrl = ControllerUtils.createRedirectUrl(config.getConfigBean().getIssuer(),
|
|
||||||
PerunUnapprovedController.UNAPPROVED_IS_CESNET_ELIGIBLE_MAPPING, params);
|
|
||||||
log.debug("{} - redirecting user to unapproved: URL '{}'", filterName, redirectUrl);
|
|
||||||
res.reset();
|
|
||||||
res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
|
||||||
res.setHeader(HttpHeaders.LOCATION, redirectUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,17 +1,17 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl;
|
package cz.muni.ics.oidc.server.filters.impl;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_TARGET;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_TARGET;
|
||||||
import static cz.muni.ics.oidc.web.controllers.IsTestSpController.IS_TEST_SP_APPROVED_SESS;
|
import static cz.muni.ics.oidc.web.controllers.IsTestSpController.IS_TEST_SP_APPROVED_SESS;
|
||||||
|
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
import cz.muni.ics.oidc.exceptions.ConfigurationException;
|
||||||
import cz.muni.ics.oidc.models.Facility;
|
import cz.muni.ics.oidc.models.Facility;
|
||||||
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
||||||
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
||||||
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
import cz.muni.ics.oidc.server.filters.FilterParams;
|
|
||||||
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterInitContext;
|
||||||
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterCommonVars;
|
||||||
|
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
||||||
import cz.muni.ics.oidc.web.controllers.ControllerUtils;
|
import cz.muni.ics.oidc.web.controllers.ControllerUtils;
|
||||||
import cz.muni.ics.oidc.web.controllers.IsTestSpController;
|
import cz.muni.ics.oidc.web.controllers.IsTestSpController;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -27,8 +27,9 @@ import org.apache.http.HttpHeaders;
|
||||||
* Otherwise, user can to access the service.
|
* Otherwise, user can to access the service.
|
||||||
*
|
*
|
||||||
* Configuration (replace [name] part with the name defined for the filter):
|
* Configuration (replace [name] part with the name defined for the filter):
|
||||||
|
* @see cz.muni.ics.oidc.server.filters.AuthProcFilter (basic configuration options)
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><b>filter.[name].isTestSpAttr</b> - mapping to isCesnetEligible attribute</li>
|
* <li><b>filter.[name].isTestSpAttr</b> - mapping to isTestSp attribute</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
||||||
* @author Pavol Pluta <500348@mail.muni.cz>
|
* @author Pavol Pluta <500348@mail.muni.cz>
|
||||||
|
@ -36,50 +37,40 @@ import org.apache.http.HttpHeaders;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PerunIsTestSpFilter extends AuthProcFilter {
|
public class PerunIsTestSpFilter extends AuthProcFilter {
|
||||||
|
|
||||||
public static final String APPLIED = "APPLIED_" + PerunIsTestSpFilter.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final String IS_TEST_SP_ATTR_NAME = "isTestSpAttr";
|
private static final String IS_TEST_SP_ATTR_NAME = "isTestSpAttr";
|
||||||
|
|
||||||
private final String isTestSpAttrName;
|
private final String isTestSpAttrName;
|
||||||
private final PerunAdapter perunAdapter;
|
private final PerunAdapter perunAdapter;
|
||||||
private final String filterName;
|
|
||||||
private final PerunOidcConfig config;
|
private final PerunOidcConfig config;
|
||||||
|
|
||||||
public PerunIsTestSpFilter(AuthProcFilterParams params) {
|
public PerunIsTestSpFilter(AuthProcFilterInitContext ctx) throws ConfigurationException {
|
||||||
super(params);
|
super(ctx);
|
||||||
BeanUtil beanUtil = params.getBeanUtil();
|
this.perunAdapter = ctx.getPerunAdapterBean();
|
||||||
this.perunAdapter = beanUtil.getBean(PerunAdapter.class);
|
this.config = ctx.getPerunOidcConfigBean();
|
||||||
this.isTestSpAttrName = params.getProperty(IS_TEST_SP_ATTR_NAME);
|
this.isTestSpAttrName = FiltersUtils.fillStringMandatoryProperty(IS_TEST_SP_ATTR_NAME, ctx);
|
||||||
this.filterName = params.getFilterName();
|
|
||||||
this.config = beanUtil.getBean(PerunOidcConfig.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getSessionAppliedParamName() {
|
protected boolean process(HttpServletRequest req, HttpServletResponse res, AuthProcFilterCommonVars params) throws IOException {
|
||||||
return APPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean process(HttpServletRequest req, HttpServletResponse res, FilterParams params) throws IOException {
|
|
||||||
Facility facility = params.getFacility();
|
Facility facility = params.getFacility();
|
||||||
if (facility == null || facility.getId() == null) {
|
if (facility == null || facility.getId() == null) {
|
||||||
log.debug("{} - skip execution: no facility provided", filterName);
|
log.debug("{} - skip execution: no facility provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
} else if (testSpWarningApproved(req)){
|
} else if (testSpWarningApproved(req)){
|
||||||
log.debug("{} - skip execution: warning already approved", filterName);
|
log.debug("{} - skip execution: warning already approved", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerunAttributeValue attrValue = perunAdapter.getFacilityAttributeValue(facility.getId(), isTestSpAttrName);
|
PerunAttributeValue attrValue = perunAdapter.getFacilityAttributeValue(facility.getId(), isTestSpAttrName);
|
||||||
if (attrValue == null) {
|
if (attrValue == null) {
|
||||||
log.debug("{} - skip execution: attribute {} has null value", filterName, isTestSpAttrName);
|
log.debug("{} - skip execution: attribute {} has null value", getFilterName(), isTestSpAttrName);
|
||||||
return true;
|
return true;
|
||||||
} else if (attrValue.valueAsBoolean()) {
|
} else if (attrValue.valueAsBoolean()) {
|
||||||
log.debug("{} - redirecting user to test SP warning page", filterName);
|
log.debug("{} - redirecting user to test SP warning page", getFilterName());
|
||||||
this.redirect(req, res);
|
this.redirect(req, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
log.debug("{} - service is not testing, let user access it", filterName);
|
log.debug("{} - service is not testing, let user access it", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +93,7 @@ public class PerunIsTestSpFilter extends AuthProcFilter {
|
||||||
params.put(PARAM_TARGET, targetURL);
|
params.put(PARAM_TARGET, targetURL);
|
||||||
String redirectUrl = ControllerUtils.createRedirectUrl(config.getConfigBean().getIssuer(),
|
String redirectUrl = ControllerUtils.createRedirectUrl(config.getConfigBean().getIssuer(),
|
||||||
IsTestSpController.MAPPING, params);
|
IsTestSpController.MAPPING, params);
|
||||||
log.debug("{} - redirecting user to testSP warning page: {}", filterName, redirectUrl);
|
log.debug("{} - redirecting user to testSP warning page: {}", getFilterName(), redirectUrl);
|
||||||
res.reset();
|
res.reset();
|
||||||
res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
||||||
res.setHeader(HttpHeaders.LOCATION, redirectUrl);
|
res.setHeader(HttpHeaders.LOCATION, redirectUrl);
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl;
|
package cz.muni.ics.oidc.server.filters.impl;
|
||||||
|
|
||||||
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
||||||
|
import cz.muni.ics.oidc.exceptions.ConfigurationException;
|
||||||
import cz.muni.ics.oidc.models.PerunUser;
|
import cz.muni.ics.oidc.models.PerunUser;
|
||||||
import cz.muni.ics.oidc.saml.SamlProperties;
|
import cz.muni.ics.oidc.saml.SamlProperties;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterInitContext;
|
||||||
import cz.muni.ics.oidc.server.filters.FilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterCommonVars;
|
||||||
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -13,29 +14,23 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.security.saml.SAMLCredential;
|
import org.springframework.security.saml.SAMLCredential;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This filter logs information about the user who has logged in INFO level in the format:
|
* This filter logs information about the user who has logged in INFO level in the format
|
||||||
* 'User ID: {}, User identifier: {}, User name: {}, service ID: {}, service name: {}'.
|
* {} - user_id '{}', user_identifier '{}', user_name '{}', service_identifier '{}', service_name: '{}'.
|
||||||
|
* @see cz.muni.ics.oidc.server.filters.AuthProcFilter (basic configuration options)
|
||||||
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
* @author Dominik Frantisek Bucik <bucik@ics.muni.cz>
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PerunLogIdentityFilter extends AuthProcFilter {
|
public class PerunLogIdentityFilter extends AuthProcFilter {
|
||||||
|
|
||||||
public static final String APPLIED = "APPLIED_" + PerunLogIdentityFilter.class.getSimpleName();
|
|
||||||
|
|
||||||
private final String userIdentifierAttr;
|
private final String userIdentifierAttr;
|
||||||
|
|
||||||
public PerunLogIdentityFilter(AuthProcFilterParams params) {
|
public PerunLogIdentityFilter(AuthProcFilterInitContext params) throws ConfigurationException {
|
||||||
super(params);
|
super(params);
|
||||||
userIdentifierAttr = params.getBeanUtil().getBean(SamlProperties.class).getUserIdentifierAttribute();
|
userIdentifierAttr = params.getBeanUtil().getBean(SamlProperties.class).getUserIdentifierAttribute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getSessionAppliedParamName() {
|
protected boolean process(HttpServletRequest req, HttpServletResponse res, AuthProcFilterCommonVars params) {
|
||||||
return APPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean process(HttpServletRequest req, HttpServletResponse res, FilterParams params) {
|
|
||||||
PerunUser user = params.getUser();
|
PerunUser user = params.getUser();
|
||||||
ClientDetailsEntity client = params.getClient();
|
ClientDetailsEntity client = params.getClient();
|
||||||
SAMLCredential samlCredential = FiltersUtils.getSamlCredential(req);
|
SAMLCredential samlCredential = FiltersUtils.getSamlCredential(req);
|
||||||
|
@ -57,8 +52,8 @@ public class PerunLogIdentityFilter extends AuthProcFilter {
|
||||||
identifier = FiltersUtils.getExtLogin(samlCredential, userIdentifierAttr);
|
identifier = FiltersUtils.getExtLogin(samlCredential, userIdentifierAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("User ID: {}, User identifier: {}, User name: {}, service ID: {}, service name: {}",
|
log.info("{} - user_id '{}', user_identifier '{}', user_name '{}', service_identifier '{}', service_name: '{}'",
|
||||||
id, identifier, name, clientId, clientName);
|
getFilterName(), id, identifier, name, clientId, clientName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,12 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
import cz.muni.ics.oidc.BeanUtil;
|
||||||
|
import cz.muni.ics.oidc.exceptions.ConfigurationException;
|
||||||
import cz.muni.ics.oidc.saml.SamlProperties;
|
import cz.muni.ics.oidc.saml.SamlProperties;
|
||||||
import cz.muni.ics.oidc.server.filters.FilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterCommonVars;
|
||||||
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterInitContext;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.Date;
|
import java.sql.Date;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
|
@ -29,6 +30,7 @@ import org.springframework.util.StringUtils;
|
||||||
* Filter for collecting data about login.
|
* Filter for collecting data about login.
|
||||||
*
|
*
|
||||||
* Configuration (replace [name] part with the name defined for the filter):
|
* Configuration (replace [name] part with the name defined for the filter):
|
||||||
|
* @see cz.muni.ics.oidc.server.filters.AuthProcFilter (basic configuration options)
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><b>filter.[name].idpNameAttributeName</b> - Mapping to Request attribute containing name of used
|
* <li><b>filter.[name].idpNameAttributeName</b> - Mapping to Request attribute containing name of used
|
||||||
* Identity Provider</li>
|
* Identity Provider</li>
|
||||||
|
@ -51,8 +53,6 @@ import org.springframework.util.StringUtils;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ProxyStatisticsFilter extends AuthProcFilter {
|
public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
|
|
||||||
public static final String APPLIED = "APPLIED_" + ProxyStatisticsFilter.class.getSimpleName();
|
|
||||||
|
|
||||||
/* CONFIGURATION OPTIONS */
|
/* CONFIGURATION OPTIONS */
|
||||||
private static final String IDP_NAME_ATTRIBUTE_NAME = "idpNameAttributeName";
|
private static final String IDP_NAME_ATTRIBUTE_NAME = "idpNameAttributeName";
|
||||||
private static final String IDP_ENTITY_ID_ATTRIBUTE_NAME = "idpEntityIdAttributeName";
|
private static final String IDP_ENTITY_ID_ATTRIBUTE_NAME = "idpEntityIdAttributeName";
|
||||||
|
@ -74,62 +74,55 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
/* END OF CONFIGURATION OPTIONS */
|
/* END OF CONFIGURATION OPTIONS */
|
||||||
|
|
||||||
private final DataSource mitreIdStats;
|
private final DataSource mitreIdStats;
|
||||||
private final String filterName;
|
|
||||||
private final SamlProperties samlProperties;
|
private final SamlProperties samlProperties;
|
||||||
|
|
||||||
public ProxyStatisticsFilter(AuthProcFilterParams params) {
|
public ProxyStatisticsFilter(AuthProcFilterInitContext ctx) throws ConfigurationException {
|
||||||
super(params);
|
super(ctx);
|
||||||
BeanUtil beanUtil = params.getBeanUtil();
|
BeanUtil beanUtil = ctx.getBeanUtil();
|
||||||
this.mitreIdStats = beanUtil.getBean("mitreIdStats", DataSource.class);
|
this.mitreIdStats = beanUtil.getBean("mitreIdStats", DataSource.class);
|
||||||
this.samlProperties = beanUtil.getBean(SamlProperties.class);
|
this.samlProperties = beanUtil.getBean(SamlProperties.class);
|
||||||
|
|
||||||
this.idpNameAttributeName = params.getProperty(IDP_NAME_ATTRIBUTE_NAME,
|
this.idpNameAttributeName = FiltersUtils.fillStringPropertyOrDefaultVal(IDP_NAME_ATTRIBUTE_NAME, ctx,
|
||||||
"urn:cesnet:proxyidp:attribute:sourceIdPName");
|
"urn:cesnet:proxyidp:attribute:sourceIdPName");
|
||||||
this.idpEntityIdAttributeName = params.getProperty(IDP_ENTITY_ID_ATTRIBUTE_NAME,
|
this.idpEntityIdAttributeName = FiltersUtils.fillStringPropertyOrDefaultVal(IDP_ENTITY_ID_ATTRIBUTE_NAME, ctx,
|
||||||
"urn:cesnet:proxyidp:attribute:sourceIdPEntityID");
|
"urn:cesnet:proxyidp:attribute:sourceIdPEntityID");
|
||||||
this.statisticsTableName = params.getProperty(STATISTICS_TABLE_NAME, "statistics_per_user");
|
this.statisticsTableName = FiltersUtils.fillStringPropertyOrDefaultVal(STATISTICS_TABLE_NAME, ctx, "statistics_per_user");
|
||||||
this.identityProvidersMapTableName = params.getProperty(IDENTITY_PROVIDERS_MAP_TABLE_NAME, "statistics_idp");
|
this.identityProvidersMapTableName = FiltersUtils.fillStringPropertyOrDefaultVal(IDENTITY_PROVIDERS_MAP_TABLE_NAME, ctx, "statistics_idp");
|
||||||
this.serviceProvidersMapTableName = params.getProperty(SERVICE_PROVIDERS_MAP_TABLE_NAME, "statistics_sp");
|
this.serviceProvidersMapTableName = FiltersUtils.fillStringPropertyOrDefaultVal(SERVICE_PROVIDERS_MAP_TABLE_NAME, ctx, "statistics_sp");
|
||||||
this.idpIdColumnName = params.getProperty(IDP_ID_COLUMN_NAME, "idpId");
|
this.idpIdColumnName = FiltersUtils.fillStringPropertyOrDefaultVal(IDP_ID_COLUMN_NAME, ctx, "idpId");
|
||||||
this.spIdColumnName = params.getProperty(SP_ID_COLUMN_NAME, "spId");
|
this.spIdColumnName = FiltersUtils.fillStringPropertyOrDefaultVal(SP_ID_COLUMN_NAME, ctx, "spId");
|
||||||
this.usernameColumnName = params.getProperty(USERNAME_COLUMN_NAME, "user");
|
this.usernameColumnName = FiltersUtils.fillStringPropertyOrDefaultVal(USERNAME_COLUMN_NAME, ctx, "user");
|
||||||
this.filterName = params.getFilterName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getSessionAppliedParamName() {
|
protected boolean process(HttpServletRequest req, HttpServletResponse res, AuthProcFilterCommonVars params) {
|
||||||
return APPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean process(HttpServletRequest req, HttpServletResponse res, FilterParams params) {
|
|
||||||
ClientDetailsEntity client = params.getClient();
|
ClientDetailsEntity client = params.getClient();
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
log.warn("{} - skip execution: no client provided", filterName);
|
log.warn("{} - skip execution: no client provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
} else if (!StringUtils.hasText(client.getClientId())) {
|
} else if (!StringUtils.hasText(client.getClientId())) {
|
||||||
log.warn("{} - skip execution: no client identifier provided", filterName);
|
log.warn("{} - skip execution: no client identifier provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
} else if (!StringUtils.hasText(client.getClientName())) {
|
} else if (!StringUtils.hasText(client.getClientName())) {
|
||||||
log.warn("{} - skip execution: no client name provided", filterName);
|
log.warn("{} - skip execution: no client name provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SAMLCredential samlCredential = FiltersUtils.getSamlCredential(req);
|
SAMLCredential samlCredential = FiltersUtils.getSamlCredential(req);
|
||||||
if (samlCredential == null) {
|
if (samlCredential == null) {
|
||||||
log.warn("{} - skip execution: no authN object available, cannot extract user identifier and idp identifier",
|
log.warn("{} - skip execution: no authN object available, cannot extract user identifier and idp identifier",
|
||||||
filterName);
|
getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
String userIdentifier = FiltersUtils.getExtLogin(samlCredential, samlProperties.getUserIdentifierAttribute());
|
String userIdentifier = FiltersUtils.getExtLogin(samlCredential, samlProperties.getUserIdentifierAttribute());
|
||||||
if (!StringUtils.hasText(userIdentifier)) {
|
if (!StringUtils.hasText(userIdentifier)) {
|
||||||
log.warn("{} - skip execution: no user identifier provided", filterName);
|
log.warn("{} - skip execution: no user identifier provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
} else if (!StringUtils.hasText(samlCredential.getAttributeAsString(idpEntityIdAttributeName))) {
|
} else if (!StringUtils.hasText(samlCredential.getAttributeAsString(idpEntityIdAttributeName))) {
|
||||||
log.warn("{} - skip execution: no authenticating idp identifier provided", filterName);
|
log.warn("{} - skip execution: no authenticating idp identifier provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
} else if (!StringUtils.hasText(samlCredential.getAttributeAsString(idpNameAttributeName))) {
|
} else if (!StringUtils.hasText(samlCredential.getAttributeAsString(idpNameAttributeName))) {
|
||||||
log.warn("{} - skip execution: no authenticating idp identifier provided", filterName);
|
log.warn("{} - skip execution: no authenticating idp identifier provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +134,7 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
insertOrUpdateLogin(idpEntityId, idpName, clientId, clientName, userIdentifier);
|
insertOrUpdateLogin(idpEntityId, idpName, clientId, clientName, userIdentifier);
|
||||||
|
|
||||||
log.info("{} - User identity: {}, service: {}, serviceName: {}, via IdP: {}",
|
log.info("{} - User identity: {}, service: {}, serviceName: {}, via IdP: {}",
|
||||||
filterName, userIdentifier, client.getClientId(), client.getClientName(), idpEntityId);
|
getFilterName(), userIdentifier, client.getClientId(), client.getClientName(), idpEntityId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,12 +151,12 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
if (spId == null) {
|
if (spId == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.trace("{} - Extracted IDs for SP and IdP: spId={}({}), idpId={}({})",
|
log.debug("{} - Extracted IDs for SP and IdP: spId={}({}), idpId={}({})",
|
||||||
filterName, spId, spIdentifier, idpId, idpEntityId);
|
getFilterName(), spId, spIdentifier, idpId, idpEntityId);
|
||||||
insertOrUpdateLogin(c, idpId, spId, userId);
|
insertOrUpdateLogin(c, idpId, spId, userId);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.warn("{} - caught SQLException", filterName);
|
log.warn("{} - caught SQLException", getFilterName());
|
||||||
log.debug("{} - details:", filterName, ex);
|
log.debug("{} - details:", getFilterName(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +167,7 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
} else {
|
} else {
|
||||||
updateLogin(c, idpId, spId, userId);
|
updateLogin(c, idpId, spId, userId);
|
||||||
}
|
}
|
||||||
|
log.info("{} - login info stored in statistics", getFilterName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fetchLogin(Connection c, Long idpId, Long spId, String userId) {
|
private boolean fetchLogin(Connection c, Long idpId, Long spId, String userId) {
|
||||||
|
@ -193,8 +187,8 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
return rs.getInt("res") > 0;
|
return rs.getInt("res") > 0;
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.warn("{} - caught SQLException when fetching login entry", filterName);
|
log.warn("{} - caught SQLException when fetching login entry", getFilterName());
|
||||||
log.debug("{} - details:", filterName, e);
|
log.debug("{} - details:", getFilterName(), e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -210,8 +204,8 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
return rs.getLong(spIdColumnName);
|
return rs.getLong(spIdColumnName);
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.warn("{} - caught SQLException when extracting SP ID", filterName);
|
log.warn("{} - caught SQLException when extracting SP ID", getFilterName());
|
||||||
log.debug("{} - details:", filterName, ex);
|
log.debug("{} - details:", getFilterName(), ex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -227,8 +221,8 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
return rs.getLong(idpIdColumnName);
|
return rs.getLong(idpIdColumnName);
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.warn("{} - caught SQLException when extracting IdP ID", filterName);
|
log.warn("{} - caught SQLException when extracting IdP ID", getFilterName());
|
||||||
log.debug("{} - details:", filterName, ex);
|
log.debug("{} - details:", getFilterName(), ex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -238,11 +232,11 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
if (!Objects.equals(idpName, idpNameInDb)) {
|
if (!Objects.equals(idpName, idpNameInDb)) {
|
||||||
if (idpNameInDb == null) {
|
if (idpNameInDb == null) {
|
||||||
if (insertIdpMap(c, idpEntityId, idpName)) {
|
if (insertIdpMap(c, idpEntityId, idpName)) {
|
||||||
log.trace("{} - IdP map entry inserted", filterName);
|
log.debug("{} - IdP map entry inserted", getFilterName());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (updateIdpMap(c, idpEntityId, idpName)) {
|
if (updateIdpMap(c, idpEntityId, idpName)) {
|
||||||
log.trace("{} - IdP map entry updated", filterName);
|
log.debug("{} - IdP map entry updated", getFilterName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,11 +270,11 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
if (!Objects.equals(spName, spNameInDb)) {
|
if (!Objects.equals(spName, spNameInDb)) {
|
||||||
if (spNameInDb == null) {
|
if (spNameInDb == null) {
|
||||||
if (insertSpMap(c, spIdentifier, spName)) {
|
if (insertSpMap(c, spIdentifier, spName)) {
|
||||||
log.trace("{} - SP map entry inserted", filterName);
|
log.debug("{} - SP map entry inserted", getFilterName());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (updateSpMap(c, spIdentifier, spName)) {
|
if (updateSpMap(c, spIdentifier, spName)) {
|
||||||
log.trace("{} - SP map entry updated", filterName);
|
log.debug("{} - SP map entry updated", getFilterName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,10 +301,10 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
ps.setString(4, userId);
|
ps.setString(4, userId);
|
||||||
ps.execute();
|
ps.execute();
|
||||||
log.debug("{} - Inserted first login for combination: idpId={}, spId={}, userId={}",
|
log.debug("{} - Inserted first login for combination: idpId={}, spId={}, userId={}",
|
||||||
filterName, idpId, spId, userId);
|
getFilterName(), idpId, spId, userId);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.warn("{} - caught SQLException when inserting login entry", filterName);
|
log.warn("{} - caught SQLException when inserting login entry", getFilterName());
|
||||||
log.debug("{} - details:", filterName, ex);
|
log.debug("{} - details:", getFilterName(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,10 +323,10 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
ps.setString(4, userId);
|
ps.setString(4, userId);
|
||||||
ps.execute();
|
ps.execute();
|
||||||
log.debug("{} - Updated login count by 1 for combination: idpId={}, spId={}, userId={}",
|
log.debug("{} - Updated login count by 1 for combination: idpId={}, spId={}, userId={}",
|
||||||
filterName, idpId, spId, userId);
|
getFilterName(), idpId, spId, userId);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.warn("{} - caught SQLException when updating login entry", filterName);
|
log.warn("{} - caught SQLException when updating login entry", getFilterName());
|
||||||
log.debug("{} - details:", filterName, ex);
|
log.debug("{} - details:", getFilterName(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,12 +346,12 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
ps.setString(1, identifier);
|
ps.setString(1, identifier);
|
||||||
ps.setString(2, name);
|
ps.setString(2, name);
|
||||||
ps.execute();
|
ps.execute();
|
||||||
log.debug("{} - {} entry inserted", filterName, table);
|
log.debug("{} - {} entry inserted", getFilterName(), table);
|
||||||
return true;
|
return true;
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
// someone has already inserted it
|
// someone has already inserted it
|
||||||
log.trace("{} - {} entry failed to insert", filterName, table);
|
log.debug("{} - {} entry failed to insert", getFilterName(), table);
|
||||||
log.trace("{} - details", filterName, ex);
|
log.debug("{} - details", getFilterName(), ex);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -377,11 +371,11 @@ public class ProxyStatisticsFilter extends AuthProcFilter {
|
||||||
ps.setString(1, name);
|
ps.setString(1, name);
|
||||||
ps.setString(2, identifier);
|
ps.setString(2, identifier);
|
||||||
ps.execute();
|
ps.execute();
|
||||||
log.debug("{} - {} entry updated", filterName, table);
|
log.debug("{} - {} entry updated", getFilterName(), table);
|
||||||
return true;
|
return true;
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.trace("{} - {} map entry failed to update", filterName, table);
|
log.debug("{} - {} map entry failed to update", getFilterName(), table);
|
||||||
log.trace("{} - details", filterName);
|
log.debug("{} - details", getFilterName());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl;
|
package cz.muni.ics.oidc.server.filters.impl;
|
||||||
|
|
||||||
import cz.muni.ics.oidc.BeanUtil;
|
import cz.muni.ics.oidc.exceptions.ConfigurationException;
|
||||||
import cz.muni.ics.oidc.models.Facility;
|
import cz.muni.ics.oidc.models.Facility;
|
||||||
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
import cz.muni.ics.oidc.models.PerunAttributeValue;
|
||||||
import cz.muni.ics.oidc.models.PerunUser;
|
import cz.muni.ics.oidc.models.PerunUser;
|
||||||
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
import cz.muni.ics.oidc.server.adapters.PerunAdapter;
|
||||||
import cz.muni.ics.oidc.server.configurations.FacilityAttrsConfig;
|
import cz.muni.ics.oidc.server.configurations.FacilityAttrsConfig;
|
||||||
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
import cz.muni.ics.oidc.server.filters.FilterParams;
|
|
||||||
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilter;
|
||||||
import cz.muni.ics.oidc.server.filters.AuthProcFilterParams;
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterCommonVars;
|
||||||
|
import cz.muni.ics.oidc.server.filters.AuthProcFilterInitContext;
|
||||||
|
import cz.muni.ics.oidc.server.filters.FiltersUtils;
|
||||||
import cz.muni.ics.oidc.web.controllers.PerunUnapprovedController;
|
import cz.muni.ics.oidc.web.controllers.PerunUnapprovedController;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -27,6 +26,7 @@ import org.springframework.util.StringUtils;
|
||||||
* the environment the service is in.
|
* the environment the service is in.
|
||||||
*
|
*
|
||||||
* Configuration (replace [name] part with the name defined for the filter):
|
* Configuration (replace [name] part with the name defined for the filter):
|
||||||
|
* @see cz.muni.ics.oidc.server.filters.AuthProcFilter (basic configuration options)
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><b>filter.[name].allEnvGroups</b> - Comma separated list of GROUP IDs the user must be always member of</li>
|
* <li><b>filter.[name].allEnvGroups</b> - Comma separated list of GROUP IDs the user must be always member of</li>
|
||||||
* <li><b>filter.[name].allEnvGroups</b> - Comma separated list of VO IDs the user must be always member of</li>
|
* <li><b>filter.[name].allEnvGroups</b> - Comma separated list of VO IDs the user must be always member of</li>
|
||||||
|
@ -46,8 +46,6 @@ import org.springframework.util.StringUtils;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ValidUserFilter extends AuthProcFilter {
|
public class ValidUserFilter extends AuthProcFilter {
|
||||||
|
|
||||||
public static final String APPLIED = "APPLIED_" + ValidUserFilter.class.getSimpleName();
|
|
||||||
|
|
||||||
/* CONFIGURATION OPTIONS */
|
/* CONFIGURATION OPTIONS */
|
||||||
private static final String ALL_ENV_GROUPS = "allEnvGroups";
|
private static final String ALL_ENV_GROUPS = "allEnvGroups";
|
||||||
private static final String ALL_ENV_VOS = "allEnvVos";
|
private static final String ALL_ENV_VOS = "allEnvVos";
|
||||||
|
@ -66,85 +64,92 @@ public class ValidUserFilter extends AuthProcFilter {
|
||||||
|
|
||||||
private final PerunAdapter perunAdapter;
|
private final PerunAdapter perunAdapter;
|
||||||
private final FacilityAttrsConfig facilityAttrsConfig;
|
private final FacilityAttrsConfig facilityAttrsConfig;
|
||||||
private final String filterName;
|
|
||||||
private final PerunOidcConfig config;
|
private final PerunOidcConfig config;
|
||||||
|
|
||||||
public ValidUserFilter(AuthProcFilterParams params) {
|
public ValidUserFilter(AuthProcFilterInitContext ctx) throws ConfigurationException {
|
||||||
super(params);
|
super(ctx);
|
||||||
BeanUtil beanUtil = params.getBeanUtil();
|
this.perunAdapter = ctx.getPerunAdapterBean();
|
||||||
this.perunAdapter = beanUtil.getBean(PerunAdapter.class);
|
this.config = ctx.getPerunOidcConfigBean();
|
||||||
this.facilityAttrsConfig = beanUtil.getBean(FacilityAttrsConfig.class);
|
this.facilityAttrsConfig = ctx.getBeanUtil().getBean(FacilityAttrsConfig.class);
|
||||||
|
|
||||||
this.allEnvGroups = this.getIdsFromParam(params, ALL_ENV_GROUPS);
|
this.allEnvGroups = getIdsFromParam(ctx, ALL_ENV_GROUPS);
|
||||||
this.allEnvVos = this.getIdsFromParam(params, ALL_ENV_VOS);
|
this.allEnvVos = getIdsFromParam(ctx, ALL_ENV_VOS);
|
||||||
this.testEnvGroups = this.getIdsFromParam(params, TEST_ENV_GROUPS);
|
this.testEnvGroups = getIdsFromParam(ctx, TEST_ENV_GROUPS);
|
||||||
this.testEnvVos = this.getIdsFromParam(params, TEST_ENV_VOS);
|
this.testEnvVos = getIdsFromParam(ctx, TEST_ENV_VOS);
|
||||||
this.prodEnvGroups = this.getIdsFromParam(params, PROD_ENV_GROUPS);
|
this.prodEnvGroups = getIdsFromParam(ctx, PROD_ENV_GROUPS);
|
||||||
this.prodEnvVos = this.getIdsFromParam(params, PROD_ENV_VOS);
|
this.prodEnvVos = getIdsFromParam(ctx, PROD_ENV_VOS);
|
||||||
this.filterName = params.getFilterName();
|
|
||||||
this.config = beanUtil.getBean(PerunOidcConfig.class);
|
if (allSetsEmpty()) {
|
||||||
|
throw new ConfigurationException("All sets are configured to be empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean allSetsEmpty() {
|
||||||
|
return allEnvVos.isEmpty() && allEnvGroups.isEmpty()
|
||||||
|
&& prodEnvVos.isEmpty() && prodEnvGroups.isEmpty()
|
||||||
|
&& testEnvVos.isEmpty() && testEnvGroups.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getSessionAppliedParamName() {
|
protected boolean process(HttpServletRequest req, HttpServletResponse res, AuthProcFilterCommonVars params) {
|
||||||
return APPLIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean process(HttpServletRequest req, HttpServletResponse res, FilterParams params) {
|
|
||||||
Set<Long> additionalVos = new HashSet<>();
|
|
||||||
Set<Long> additionalGroups = new HashSet<>();
|
|
||||||
|
|
||||||
PerunUser user = params.getUser();
|
PerunUser user = params.getUser();
|
||||||
|
|
||||||
if (user == null || user.getId() == null) {
|
if (user == null || user.getId() == null) {
|
||||||
log.debug("{} - skip filter execution: no user provided", filterName);
|
log.debug("{} - skip filter execution: no user provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Facility facility = params.getFacility();
|
Facility facility = params.getFacility();
|
||||||
if (facility == null || facility.getId() == null) {
|
if (facility == null || facility.getId() == null) {
|
||||||
log.debug("{} - skip filter execution: no facility provided", filterName);
|
log.debug("{} - skip filter execution: no facility provided", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkMemberValidInGroupsAndVos(user, facility, res, params, allEnvVos, allEnvGroups,
|
if (!checkMemberValidInGroupsAndVos(user, allEnvVos, allEnvGroups)) {
|
||||||
PerunUnapprovedController.UNAPPROVED_NOT_IN_MANDATORY_VOS_GROUPS)) {
|
redirectCannotAccess(res, facility, user, params.getClientIdentifier(), PerunUnapprovedController.UNAPPROVED_NOT_IN_MANDATORY_VOS_GROUPS);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerunAttributeValue isTestSp = perunAdapter.getFacilityAttributeValue(facility.getId(), facilityAttrsConfig.getTestSpAttr());
|
PerunAttributeValue isTestSpAttrValue = perunAdapter.getFacilityAttributeValue(facility.getId(), facilityAttrsConfig.getTestSpAttr());
|
||||||
boolean isTestSpBool = false;
|
boolean testService = false;
|
||||||
if (isTestSp != null) {
|
if (isTestSpAttrValue != null) {
|
||||||
isTestSpBool = isTestSp.valueAsBoolean();
|
testService = isTestSpAttrValue.valueAsBoolean();
|
||||||
}
|
}
|
||||||
log.debug("{} - service {} in test env", filterName, (isTestSpBool ? "is" : "is not"));
|
|
||||||
if (isTestSpBool) {
|
|
||||||
additionalVos.addAll(testEnvVos);
|
|
||||||
additionalGroups.addAll(testEnvGroups);
|
|
||||||
|
|
||||||
if (!checkMemberValidInGroupsAndVos(user, facility, res, params, additionalVos,
|
log.debug("{} - service {} in test env", getFilterName(), (testService ? "is" : "is not"));
|
||||||
additionalGroups, PerunUnapprovedController.UNAPPROVED_NOT_IN_TEST_VOS_GROUPS)) {
|
|
||||||
return false;
|
Set<Long> vos = new HashSet<>();
|
||||||
}
|
Set<Long> groups = new HashSet<>();
|
||||||
|
String unapprovedMapping;
|
||||||
|
if (testService) {
|
||||||
|
vos.addAll(testEnvVos);
|
||||||
|
groups.addAll(testEnvGroups);
|
||||||
|
unapprovedMapping = PerunUnapprovedController.UNAPPROVED_NOT_IN_TEST_VOS_GROUPS;
|
||||||
} else {
|
} else {
|
||||||
additionalVos.addAll(prodEnvVos);
|
vos.addAll(prodEnvVos);
|
||||||
additionalGroups.addAll(prodEnvGroups);
|
groups.addAll(prodEnvGroups);
|
||||||
|
unapprovedMapping = PerunUnapprovedController.UNAPPROVED_NOT_IN_PROD_VOS_GROUPS;
|
||||||
if (!checkMemberValidInGroupsAndVos(user, facility, res, params, additionalVos,
|
}
|
||||||
additionalGroups, PerunUnapprovedController.UNAPPROVED_NOT_IN_PROD_VOS_GROUPS)) {
|
if (!checkMemberValidInGroupsAndVos(user, vos, groups)) {
|
||||||
return false;
|
log.info("{} - Redirecting to unapproved page with mapping '{}'", getFilterName(), unapprovedMapping);
|
||||||
}
|
redirectCannotAccess(res, facility, user, params.getClientIdentifier(), unapprovedMapping);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("{} - user satisfies the membership criteria", filterName);
|
log.info("{} - user satisfies the membership criteria", getFilterName());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Long> getIdsFromParam(AuthProcFilterParams params, String propKey) {
|
private void redirectCannotAccess(HttpServletResponse res, Facility facility, PerunUser user,
|
||||||
|
String clientId, String mapping)
|
||||||
|
{
|
||||||
|
FiltersUtils.redirectUserCannotAccess(config.getConfigBean().getIssuer(), res, facility, user,
|
||||||
|
clientId, facilityAttrsConfig, perunAdapter, mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> getIdsFromParam(AuthProcFilterInitContext params, String propKey) {
|
||||||
Set<Long> result = new HashSet<>();
|
Set<Long> result = new HashSet<>();
|
||||||
|
|
||||||
String prop = params.getProperty(propKey);
|
String prop = params.getProperty(propKey, "");
|
||||||
if (StringUtils.hasText(prop)) {
|
if (StringUtils.hasText(prop)) {
|
||||||
String[] parts = prop.split(",");
|
String[] parts = prop.split(",");
|
||||||
for (String idStr: parts) {
|
for (String idStr: parts) {
|
||||||
|
@ -155,26 +160,11 @@ public class ValidUserFilter extends AuthProcFilter {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkMemberValidInGroupsAndVos(
|
private boolean checkMemberValidInGroupsAndVos(PerunUser user, Set<Long> vos, Set<Long> groups) {
|
||||||
PerunUser user,
|
|
||||||
Facility facility,
|
|
||||||
HttpServletResponse response,
|
|
||||||
FilterParams params,
|
|
||||||
Set<Long> vos,
|
|
||||||
Set<Long> groups,
|
|
||||||
String redirectUrl
|
|
||||||
) {
|
|
||||||
if (!perunAdapter.isValidMemberInGroupsAndVos(user.getId(), vos, groups)) {
|
if (!perunAdapter.isValidMemberInGroupsAndVos(user.getId(), vos, groups)) {
|
||||||
log.info("{} - user is not member in required set of vos and groups", filterName);
|
log.info("{} - user is not member in required set of vos and groups", getFilterName());
|
||||||
log.debug("{} - user: '{}', vos: '{}', groups: '{}'",
|
log.debug("{} - user: '{}', vos: '{}', groups: '{}'",
|
||||||
filterName, user.getId(), vos, groups);
|
getFilterName(), user.getId(), vos, groups);
|
||||||
|
|
||||||
Map<String, PerunAttributeValue> facilityAttributes = perunAdapter.getFacilityAttributeValues(
|
|
||||||
facility, facilityAttrsConfig.getMembershipAttrNames());
|
|
||||||
|
|
||||||
FiltersUtils.redirectUserCannotAccess(config.getConfigBean().getIssuer(), response, facility, user,
|
|
||||||
params.getClientIdentifier(), facilityAttrsConfig, facilityAttributes, perunAdapter, redirectUrl);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl.mdc;
|
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.slf4j.MDC;
|
|
||||||
|
|
||||||
public class RemoteAddressMDCFilter {
|
|
||||||
|
|
||||||
private static final String[] IP_HEADER_CANDIDATES = {
|
|
||||||
"X-Forwarded-For",
|
|
||||||
"Proxy-Client-IP",
|
|
||||||
"WL-Proxy-Client-IP",
|
|
||||||
"HTTP_X_FORWARDED_FOR",
|
|
||||||
"HTTP_X_FORWARDED",
|
|
||||||
"HTTP_X_CLUSTER_CLIENT_IP",
|
|
||||||
"HTTP_CLIENT_IP",
|
|
||||||
"HTTP_FORWARDED_FOR",
|
|
||||||
"HTTP_FORWARDED",
|
|
||||||
"HTTP_VIA",
|
|
||||||
"REMOTE_ADDR"
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final String REMOTE_ADDR = "remoteAddr";
|
|
||||||
|
|
||||||
public void doFilter(ServletRequest servletRequest) {
|
|
||||||
MDC.put(REMOTE_ADDR, getRemoteAddr((HttpServletRequest) servletRequest));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getRemoteAddr(HttpServletRequest request) {
|
|
||||||
if (request.getRemoteAddr() != null) {
|
|
||||||
return request.getRemoteAddr();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String header: IP_HEADER_CANDIDATES) {
|
|
||||||
String ipList = request.getHeader(header);
|
|
||||||
if (ipList != null && ipList.length() != 0 && !"unknown".equalsIgnoreCase(ipList)) {
|
|
||||||
return ipList.split(",")[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package cz.muni.ics.oidc.server.filters.impl.mdc;
|
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.slf4j.MDC;
|
|
||||||
|
|
||||||
public class SessionIdMDCFilter {
|
|
||||||
|
|
||||||
private static final int SIZE = 12;
|
|
||||||
private static final String SESSION_ID = "sessionID";
|
|
||||||
|
|
||||||
public void doFilter(ServletRequest servletRequest) {
|
|
||||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
|
||||||
if (req.getSession() != null) {
|
|
||||||
String id = req.getSession().getId();
|
|
||||||
if (id != null && id.length() > SIZE) {
|
|
||||||
id = id.substring(0, SIZE);
|
|
||||||
}
|
|
||||||
MDC.put(SESSION_ID, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -36,7 +36,7 @@ public class AupController {
|
||||||
|
|
||||||
public static final String URL = "aup";
|
public static final String URL = "aup";
|
||||||
public static final String NEW_AUPS = "newAups";
|
public static final String NEW_AUPS = "newAups";
|
||||||
public static final String APPROVED = "approved";
|
public static final String APPROVED = "aup_approved";
|
||||||
public static final String RETURN_URL = "returnUrl";
|
public static final String RETURN_URL = "returnUrl";
|
||||||
public static final String USER_ATTR = "userAttr";
|
public static final String USER_ATTR = "userAttr";
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cz.muni.ics.oidc.web.controllers;
|
package cz.muni.ics.oidc.web.controllers;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_ACCEPTED;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_ACCEPTED;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_TARGET;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_TARGET;
|
||||||
|
|
||||||
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
import cz.muni.ics.oidc.web.WebHtmlClasses;
|
import cz.muni.ics.oidc.web.WebHtmlClasses;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package cz.muni.ics.oidc.web.controllers;
|
package cz.muni.ics.oidc.web.controllers;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_CLIENT_ID;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_CLIENT_ID;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_HEADER;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_HEADER;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_MESSAGE;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_MESSAGE;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_REASON;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_REASON;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_TARGET;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_TARGET;
|
||||||
|
|
||||||
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
import cz.muni.ics.oauth2.model.ClientDetailsEntity;
|
||||||
import cz.muni.ics.oauth2.service.ClientDetailsEntityService;
|
import cz.muni.ics.oauth2.service.ClientDetailsEntityService;
|
||||||
|
@ -12,8 +12,6 @@ import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
|
||||||
import cz.muni.ics.oidc.web.WebHtmlClasses;
|
import cz.muni.ics.oidc.web.WebHtmlClasses;
|
||||||
import cz.muni.ics.openid.connect.view.HttpCodeView;
|
import cz.muni.ics.openid.connect.view.HttpCodeView;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
package cz.muni.ics.openid.connect.web.endpoint;
|
package cz.muni.ics.openid.connect.web.endpoint;
|
||||||
|
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_POST_LOGOUT_REDIRECT_URI;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_POST_LOGOUT_REDIRECT_URI;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_STATE;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_STATE;
|
||||||
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_TARGET;
|
import static cz.muni.ics.oidc.server.filters.AuthProcFilterConstants.PARAM_TARGET;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
Loading…
Reference in New Issue