Uploaded image for project: 'Single Sign On'
  1. Single Sign On
  2. MGNLSSO-266

Multi type login - SSO or Form Login

    XMLWordPrintable

Details

    • Story
    • Resolution: Duplicate
    • Major
    • None
    • None
    • None
    • None

    Description

      Implement the option to use both, sso or form login.

      We have implemented this on one of our projects with a custom Login/Logout filter.

      The form login can be used by adding a query param to the admincentral url (/author/.magnolia/admincentral?formLogin=true)

      MultiTypeLoginFilter:

      /server/filters/login@class

      import info.magnolia.cms.security.auth.login.FormLogin;
      import info.magnolia.cms.security.auth.login.LoginFilter;
      import info.magnolia.sso.SsoLoginFilter;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
      
      import javax.inject.Inject;
      import javax.servlet.FilterChain;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletRequestWrapper;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.lang.invoke.MethodHandles;
      import java.util.Collections;
      import java.util.List;
      import java.util.Map;
      import java.util.stream.Collectors;
      
      public class MultiTypeLoginFilter extends LoginFilter {
          private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
          private final SsoLoginFilter ssoLoginFilter;
      
          @Inject
          public MultiTypeLoginFilter(final SsoLoginFilter ssoLoginFilter) {
             this.ssoLoginFilter = ssoLoginFilter;
          }
      
          @Override
          public void doFilter(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException, ServletException {
             if (LoginTypeEvaluator.isFormLogin(request)) {
                LOG.info("Use default loginFilter - form login");
                final HttpServletRequestWrapper wrappedRequest = addRequestParams(request, Map.of(
                      FormLogin.PARAMETER_RETURN_TO, getRequestUriWithQueryParams(request)
                ));
                super.doFilter(wrappedRequest, response, chain);
             } else {
                ssoLoginFilter.doFilter(request, response, chain);
             }
          }
      
          private HttpServletRequestWrapper addRequestParams(final HttpServletRequest request, final Map<String, String> requestParams) {
             return new HttpServletRequestWrapper(request) {
                @Override
                public String getParameter(final String name) {
                   if(requestParams.containsKey(name)) {
                      return requestParams.get(name);
                   }
                   return super.getParameter(name);
                }
             };
          }
      
          private String getRequestUriWithQueryParams(final HttpServletRequest request) {
             return ServletUriComponentsBuilder.fromPath(request.getRequestURI()).query(request.getQueryString()).toUriString();
          }
      } 

      MultiTypeLogoutFilter

      /server/filters/logout@class

      import info.magnolia.cms.security.LogoutFilter;
      import info.magnolia.sso.SsoLogoutFilter;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      import javax.inject.Inject;
      import javax.servlet.FilterChain;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.lang.invoke.MethodHandles;
      
      public class MultiTypeLogoutFilter extends LogoutFilter {
          private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
          private final SsoLogoutFilter ssoLogoutFilter;
      
          @Inject
          public MultiTypeLogoutFilter(final SsoLogoutFilter ssoLogoutFilter) {
             this.ssoLogoutFilter = ssoLogoutFilter;
          }
      
          @Override
          public void doFilter(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException, ServletException {
             if (LoginTypeEvaluator.isMagnoliaUser()) {
                if(request.getParameterMap().containsKey(PARAMETER_LOGOUT)) {
                   LOG.info("Use default logoutFilter - form login");
                }
                super.doFilter(request, response, chain);
             } else {
                ssoLogoutFilter.doFilter(request, response, chain);
             }
          }
      } 

      SsoClientCallback
      /server/filters/securityCallback/clientCallbacks/magnolia-sso@class

      import info.magnolia.sso.UserInitiatedRedirectClientCallback;
      
      import javax.servlet.http.HttpServletRequest;
      
      public class SsoClientCallback extends UserInitiatedRedirectClientCallback {
          @Override
          public boolean accepts(final HttpServletRequest request) {
             if(LoginTypeEvaluator.isFormLogin(request)) {
                return false;
             }
             return super.accepts(request);
          }
      } 

      LoginTypeEvaluator

      import info.magnolia.cms.security.MgnlUser;
      import info.magnolia.context.MgnlContext;
      import org.springframework.http.HttpHeaders;
      
      import javax.servlet.http.HttpServletRequest;
      import java.util.Optional;
      
      public class LoginTypeEvaluator {
      
          public static boolean isMagnoliaUser() {
             return MgnlContext.getUser() instanceof MgnlUser;
          }
      
          public static boolean isFormLogin(HttpServletRequest request) {
             return Optional.ofNullable(request.getParameter("formLogin")).map(Boolean::valueOf).orElse(false);
          }
      } 

      Checklists

        Acceptance criteria

        Attachments

          Issue Links

            Activity

              People

                Unassigned Unassigned
                beschle Björn Eschle
                Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:

                  Checklists

                    Task DoD