diff --git a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/config/AppConfig.java b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/config/AppConfig.java index da2a71cfdb7a171af4b198edea5c48e351cd9d2a..f20fec9411bc2d8e89a1e1ead674baac068c70f1 100644 --- a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/config/AppConfig.java +++ b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/config/AppConfig.java @@ -162,6 +162,12 @@ public class AppConfig extends BaseTicketCatalogConfigurer { @Value("${ip.header}") private String ipHeaderName; + @Value("${vitamui.cas.tenant.identifier}") + private Integer casTenantIdentifier; + + @Value("${vitamui.cas.identity}") + private String casIdentity; + @Bean public UserAuthenticationHandler userAuthenticationHandler() { return new UserAuthenticationHandler(servicesManager, principalFactory, casRestClient(), utils(), ipHeaderName); @@ -234,7 +240,7 @@ public class AppConfig extends BaseTicketCatalogConfigurer { @Bean public Utils utils() { - return new Utils(casRestClient(), tokenApiCas); + return new Utils(casRestClient(), tokenApiCas, casTenantIdentifier, casIdentity); } @Bean diff --git a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/config/WebflowConfig.java b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/config/WebflowConfig.java index 83a249ece138bf70d214b0b0ce46cb36a2ee46a2..65a538a03173ca366f309c460c40b3d40dd6ed24 100644 --- a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/config/WebflowConfig.java +++ b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/config/WebflowConfig.java @@ -207,7 +207,7 @@ public class WebflowConfig { @Bean public SelectRedirectAction selectRedirectAction() { - return new SelectRedirectAction(); + return new SelectRedirectAction(centralAuthenticationService.getObject()); } @Bean diff --git a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/util/Utils.java b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/util/Utils.java index ca84f9ef4b6d4e9e0150474d041f5b28a0184dda..025514611e9498315d229398d8efd9155fbfc6cc 100644 --- a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/util/Utils.java +++ b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/util/Utils.java @@ -44,7 +44,9 @@ import java.util.Optional; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; import org.apache.commons.lang.StringUtils; +import org.apereo.cas.CasProtocolConstants; import org.apereo.cas.authentication.Authentication; import org.apereo.cas.authentication.principal.Principal; import org.apereo.cas.authentication.surrogate.SurrogateAuthenticationService; @@ -54,7 +56,6 @@ import org.apereo.cas.web.support.WebUtils; import org.pac4j.core.util.CommonHelper; import org.pac4j.core.context.Pac4jConstants; import org.pac4j.saml.client.SAML2Client; -import org.springframework.beans.factory.annotation.Value; import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.execution.Action; import org.springframework.webflow.execution.Event; @@ -67,11 +68,14 @@ import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; import fr.gouv.vitamui.commons.rest.client.ExternalHttpContext; import fr.gouv.vitamui.iam.external.client.CasExternalRestClient; +import lombok.val; + /** * Helper class. * * */ +@RequiredArgsConstructor public class Utils { private static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(Utils.class); @@ -82,16 +86,9 @@ public class Utils { private final String casToken; - @Value("${vitamui.cas.tenant.identifier}") - private Integer casTenantIdentifier; - - @Value("${vitamui.cas.identity}") - private String casIdentity; + private final Integer casTenantIdentifier; - public Utils(final CasExternalRestClient casExternalRestClient, final String casToken) { - this.casExternalRestClient = casExternalRestClient; - this.casToken = casToken; - } + private final String casIdentity; public ExternalHttpContext buildContext(final String username) { return new ExternalHttpContext(casTenantIdentifier, casToken, "cas+" + username, casIdentity); @@ -99,8 +96,12 @@ public class Utils { public Event performClientRedirection(final Action action, final SAML2Client client, final RequestContext requestContext) throws IOException { final HttpServletResponse response = WebUtils.getHttpServletResponseFromExternalWebflowContext(requestContext); + val service = WebUtils.getService(requestContext); - final String url = CommonHelper.addParameter("clientredirect", Pac4jConstants.DEFAULT_CLIENT_NAME_PARAMETER, client.getName()); + String url = CommonHelper.addParameter("clientredirect", Pac4jConstants.DEFAULT_CLIENT_NAME_PARAMETER, client.getName()); + if (service != null) { + url = CommonHelper.addParameter(url, CasProtocolConstants.PARAMETER_SERVICE, service.getOriginalUrl()); + } response.sendRedirect(url); final ExternalContext externalContext = requestContext.getExternalContext(); diff --git a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/CustomDelegatedClientAuthenticationAction.java b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/CustomDelegatedClientAuthenticationAction.java index da43deda6df053773e0ddfb17d27837e66a9b9a7..c90475a1afef1ad60c9716dc86f0e7b1a0e081b5 100644 --- a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/CustomDelegatedClientAuthenticationAction.java +++ b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/CustomDelegatedClientAuthenticationAction.java @@ -81,7 +81,8 @@ import java.util.Optional; /** * Custom authentication delegation: * - automatic delegation given the provided IdP - * - extraction of the username/surrogate passed as a request parameter. + * - extraction of the username/surrogate passed as a request parameter + * - save the portalUrl in the webflow. * * */ @@ -139,12 +140,14 @@ public class CustomDelegatedClientAuthenticationAction extends DelegatedClientAu @Override public Event doExecute(final RequestContext context) { + // save a label in the webflow + final MutableAttributeMap<Object> flowScope = context.getFlowScope(); + flowScope.put(Constants.PORTAL_URL, vitamuiPortalUrl); + final Event event = super.doExecute(context); if ("error".equals(event.getId())) { - final MutableAttributeMap<Object> flowScope = context.getFlowScope(); - flowScope.put(Constants.PORTAL_URL, vitamuiPortalUrl); - + // extract and parse the request username if provided String username = context.getRequestParameters().get(Constants.USERNAME); if (username != null) { @@ -163,23 +166,25 @@ public class CustomDelegatedClientAuthenticationAction extends DelegatedClientAu } } + // get the idp if it exists + final HttpServletRequest request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context); + final String idp = getIdpValue(request); + LOGGER.debug("Provided idp: {}", idp); + if (StringUtils.isNotBlank(idp)) { - TicketGrantingTicket tgt = null; - final String tgtId = WebUtils.getTicketGrantingTicketId(context); - if (tgtId != null) { - tgt = ticketRegistry.getTicket(tgtId, TicketGrantingTicket.class); - } + TicketGrantingTicket tgt = null; + final String tgtId = WebUtils.getTicketGrantingTicketId(context); + if (tgtId != null) { + tgt = ticketRegistry.getTicket(tgtId, TicketGrantingTicket.class); + } - if (tgt == null || tgt.isExpired()) { - final HttpServletRequest request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context); - final HttpServletResponse response = WebUtils.getHttpServletResponseFromExternalWebflowContext(context); + // if no authentication + if (tgt == null || tgt.isExpired()) { - // get the idp and redirect if it exists - final String idp = getIdpValue(request); - LOGGER.debug("Provided idp: {}", idp); - if (StringUtils.isNotBlank(idp)) { + // if it matches an existing IdP, save it and redirect final Optional<IdentityProviderDto> optProvider = identityProviderHelper.findByTechnicalName(providersService.getProviders(), idp); if (optProvider.isPresent()) { + final HttpServletResponse response = WebUtils.getHttpServletResponseFromExternalWebflowContext(context); response.addCookie(utils.buildIdpCookie(idp, casProperties.getTgc())); final SAML2Client client = ((SamlIdentityProviderDto) optProvider.get()).getSaml2Client(); LOGGER.debug("Force redirect to the SAML IdP: {}", client.getName()); diff --git a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/DispatcherAction.java b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/DispatcherAction.java index e7bb07bea41634d1276f7d827b11f1bcf2dcdf1f..fcbc21509d1e3d50ba5924d97daa7e9059e1bea6 100644 --- a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/DispatcherAction.java +++ b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/DispatcherAction.java @@ -48,6 +48,7 @@ import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; import fr.gouv.vitamui.iam.common.utils.IdentityProviderHelper; import fr.gouv.vitamui.iam.external.client.CasExternalRestClient; +import lombok.RequiredArgsConstructor; import org.apache.commons.lang.StringUtils; import org.apereo.cas.authentication.credential.UsernamePasswordCredential; import org.apereo.cas.web.support.WebUtils; @@ -68,6 +69,7 @@ import java.util.Optional; * * */ +@RequiredArgsConstructor public class DispatcherAction extends AbstractAction { public static final String DISABLED = "disabled"; @@ -85,18 +87,6 @@ public class DispatcherAction extends AbstractAction { private final Utils utils; - public DispatcherAction(final ProvidersService providersService, - final IdentityProviderHelper identityProviderHelper, - final CasExternalRestClient casExternalRestClient, - final String surrogationSeparator, - final Utils utils) { - this.providersService = providersService; - this.identityProviderHelper = identityProviderHelper; - this.casExternalRestClient = casExternalRestClient; - this.surrogationSeparator = surrogationSeparator; - this.utils = utils; - } - @Override protected Event doExecute(final RequestContext requestContext) throws IOException { diff --git a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/SelectRedirectAction.java b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/SelectRedirectAction.java index c080f62ffcfd8d5d6c6bc3815eaf88b40d2cf4f4..3564f0c25f5a91a42109fc09d84e446c9ad8ab39 100644 --- a/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/SelectRedirectAction.java +++ b/cas/cas-server/src/main/java/fr/gouv/vitamui/cas/webflow/actions/SelectRedirectAction.java @@ -39,11 +39,10 @@ package fr.gouv.vitamui.cas.webflow.actions; import fr.gouv.vitamui.cas.webflow.CustomLoginWebflowConfigurer; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import lombok.RequiredArgsConstructor; import org.apereo.cas.CentralAuthenticationService; import org.apereo.cas.ticket.ServiceTicket; import org.apereo.cas.web.support.WebUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.webflow.action.AbstractAction; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; @@ -53,13 +52,12 @@ import org.springframework.webflow.execution.RequestContext; * * */ +@RequiredArgsConstructor public class SelectRedirectAction extends AbstractAction { private static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(SelectRedirectAction.class); - @Autowired - @Qualifier("centralAuthenticationService") - private CentralAuthenticationService centralAuthenticationService; + private final CentralAuthenticationService centralAuthenticationService; @Override protected Event doExecute(final RequestContext requestContext) { diff --git a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/IamSurrogateRestAuthenticationServiceTest.java b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/IamSurrogateRestAuthenticationServiceTest.java index 97b0ca50b7d0cb78c43ddd966c22047efa346637..d3e227c8c96a223e60c404dede1ba458bc7f1e4d 100644 --- a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/IamSurrogateRestAuthenticationServiceTest.java +++ b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/IamSurrogateRestAuthenticationServiceTest.java @@ -42,7 +42,7 @@ public final class IamSurrogateRestAuthenticationServiceTest { public void setUp() { casExternalRestClient = mock(CasExternalRestClient.class); - final Utils utils = new Utils(casExternalRestClient, null); + final Utils utils = new Utils(casExternalRestClient, null, 0, null); service = new IamSurrogateRestAuthenticationService(casExternalRestClient, mock(ServicesManager.class), utils); } diff --git a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/UserAuthenticationHandlerTest.java b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/UserAuthenticationHandlerTest.java index bd685858128d59b89749ee6841855e21a9d34b7b..853db4eaeda88eba7b19b7a17ac8bf144ef95201 100644 --- a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/UserAuthenticationHandlerTest.java +++ b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/UserAuthenticationHandlerTest.java @@ -61,7 +61,7 @@ public final class UserAuthenticationHandlerTest { @Before public void setUp() { casExternalRestClient = mock(CasExternalRestClient.class); - final Utils utils = new Utils(casExternalRestClient, null); + final Utils utils = new Utils(casExternalRestClient, null, 0, null); handler = new UserAuthenticationHandler(null, new DefaultPrincipalFactory(), casExternalRestClient, utils, null); credential = new UsernamePasswordCredential(USERNAME, PASSWORD); } diff --git a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/UserPrincipalResolverTest.java b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/UserPrincipalResolverTest.java index b130c464bb0fb706697ce35b49e85ded8bb42bb6..7267736ed479db8beee9c2219e9b37293f3adbd4 100644 --- a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/UserPrincipalResolverTest.java +++ b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/authentication/UserPrincipalResolverTest.java @@ -57,7 +57,7 @@ public final class UserPrincipalResolverTest { @Before public void setUp() { casExternalRestClient = mock(CasExternalRestClient.class); - final Utils utils = new Utils(casExternalRestClient, null); + final Utils utils = new Utils(casExternalRestClient, null, 0, null); resolver = new UserPrincipalResolver(false, new DefaultPrincipalFactory(), casExternalRestClient, utils); final RequestContext context = mock(RequestContext.class); RequestContextHolder.setRequestContext(context); diff --git a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/pm/IamRestPasswordManagementServiceTest.java b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/pm/IamRestPasswordManagementServiceTest.java index a6dc3e04f095fd927af7c0f474cb671d17216a16..8e73e8eae7adb149d507fd6caa4746fe9b0c32cf 100644 --- a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/pm/IamRestPasswordManagementServiceTest.java +++ b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/pm/IamRestPasswordManagementServiceTest.java @@ -76,7 +76,7 @@ public final class IamRestPasswordManagementServiceTest { identityProviderDto.setInternal(true); when(identityProviderHelper.findByUserIdentifier(any(List.class), eq(EMAIL))).thenReturn(Optional.of(identityProviderDto)); service = new IamRestPasswordManagementService(casExternalRestClient, null, providersService, identityProviderHelper); - final Utils utils = new Utils(casExternalRestClient, null); + final Utils utils = new Utils(casExternalRestClient, null, 0, null); service.setUtils(utils); final RequestContext context = mock(RequestContext.class); RequestContextHolder.setRequestContext(context); diff --git a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/provider/ProvidersServiceTest.java b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/provider/ProvidersServiceTest.java index b5c1c5c44c5a0d988c48708c2a045e8eabfdc75a..c57b64677da6aff04e1a02873456bd6dbb707e58 100644 --- a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/provider/ProvidersServiceTest.java +++ b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/provider/ProvidersServiceTest.java @@ -57,7 +57,7 @@ public final class ProvidersServiceTest { restClient = mock(IdentityProviderExternalRestClient.class); service.setIdentityProviderExternalRestClient(restClient); final CasExternalRestClient casExternalRestClient = mock(CasExternalRestClient.class); - final Utils utils = new Utils(casExternalRestClient, null); + final Utils utils = new Utils(casExternalRestClient, null, 0, null); service.setUtils(utils); provider = new IdentityProviderDto(); diff --git a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/webflow/actions/BaseWebflowActionTest.java b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/webflow/actions/BaseWebflowActionTest.java index 109049e4e970bdb934fb8b7fb5e325cbfbbf8cd2..ae75f1e3d45938f86572ed853670196e779ebba0 100644 --- a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/webflow/actions/BaseWebflowActionTest.java +++ b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/webflow/actions/BaseWebflowActionTest.java @@ -1,6 +1,7 @@ package fr.gouv.vitamui.cas.webflow.actions; import fr.gouv.vitamui.commons.api.identity.ServerIdentityAutoConfiguration; +import org.apereo.cas.authentication.principal.WebApplicationService; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; @@ -56,6 +57,7 @@ public abstract class BaseWebflowActionTest { flowParameters = new LocalAttributeMap<>(); when(context.getFlowScope()).thenReturn(flowParameters); + flowParameters.put("service", mock(WebApplicationService.class)); val flow = mock(Flow.class); when(flow.getVariable("credential")).thenReturn(mock(FlowVariable.class)); diff --git a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/webflow/actions/DispatcherActionTest.java b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/webflow/actions/DispatcherActionTest.java index b03f19bf2b0510510823387d238dfa1eaa8238c4..c6e8dbbeffcd83de360117ca40ab38e1277fa4e0 100644 --- a/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/webflow/actions/DispatcherActionTest.java +++ b/cas/cas-server/src/test/java/fr/gouv/vitamui/cas/webflow/actions/DispatcherActionTest.java @@ -64,7 +64,7 @@ public final class DispatcherActionTest extends BaseWebflowActionTest { identityProviderHelper = mock(IdentityProviderHelper.class); casExternalRestClient = mock(CasExternalRestClient.class); - final Utils utils = new Utils(casExternalRestClient, null); + final Utils utils = new Utils(casExternalRestClient, null, 0, null); action = new DispatcherAction(providersService, identityProviderHelper, casExternalRestClient, ",", utils); final SAML2Client client = new SAML2Client();