[MGNLSSO-266] Multi type login - SSO or Form Login Created: 18/Apr/23  Updated: 22/Jun/23  Resolved: 22/Jun/23

Status: Closed
Project: Single Sign On
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Story Priority: Major
Reporter: Björn Eschle Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
duplicate
duplicates MGNLSSO-84 Ability to use default Magnolia login... Selected
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Date of First Response:

 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);
    }
} 


 Comments   
Comment by Mikaël Geljić [ 22/Jun/23 ]

Hi beschle,

Thank you for providing a custom solution, we're consolidating this use case under MGNLSSO-84. I'll give a pointer back to this ticket if I may, in case someone critically requires a solution before we support it in the module.

Cheers,
Mika

Generated at Mon Feb 12 10:52:38 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.