I am using AEM as a Cloud Service. 2 different systems are invoking the AEM publisher domain with respective request parameters. The requests are not authenticated and hence AEM is redirecting the request to the configured IDP. However while redirection, it is using the idpUrl configured on SAML Authentication Handler configuration on AEM. Therefore we are losing the request parameter.
I have tried setting "saml.sp.use.relaystate": true on AEM SAML Handler configuration, but that looks to be different or even might not be supported now, not sure.
I understand that this is OOB Handler functionality and the redirection is a POST request and not a GET. Still appending like a request parameter will work for us since IDP will be able to read that parameter and act accordingly. So please recommend the best approach to relay/append the same request parameter to the idpUrl redirection.
Sincere thanks for your kind help !
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Hi @Som_Adobe ,
AEMaaCS has stricter constraints than AMS or on-prem AEM (e.g., limited access to OSGi console, restricted SAML configs). So, here’s a Cloud-native workaround:
1. Use a Front-End Proxy or Dispatcher Rewrite (Preferred if possible)
If you control the entry point (e.g., a CDN like CloudFront, Azure Front Door, or Dispatcher), you can:
Encode the query params in a single RelayState-safe parameter (e.g., base64 or URL-encoded string).
Redirect to AEM with something like:
/content/mysite.html?relayState=base64(queryParams)
Then AEM just needs to preserve the relayState through SAML.
2. Custom Sling Filter to Capture Parameters and Redirect After Login:
Since OSGi checkbox options are not available in AEMaaCS, build a custom Sling Filter and a custom redirect servlet to simulate RelayState functionality:
Sling Filter (Runs Pre-authentication)
Stores the incoming full request URL (with query params) in a cookie or session attribute.
@Component(service = Filter.class,
property = {
Constants.SERVICE_RANKING + ":Integer=10000",
"sling.filter.scope=request"
})
public class SamlRelayStateFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();
if (req.getUserPrincipal() == null && req.getQueryString() != null) {
String fullUrl = req.getRequestURL().toString() + "?" + req.getQueryString();
session.setAttribute("customRelayState", fullUrl);
}
chain.doFilter(request, response);
}
}
Custom Redirect Servlet (Runs Post-authentication)
This servlet reads the stored URL and redirects the user after login
@Component(service = Servlet.class,
property = {
"sling.servlet.paths=/bin/custom/relayredirect",
"sling.servlet.methods=GET"
})
public class RelayRedirectServlet extends SlingAllMethodsServlet {
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
if (session != null) {
String relayUrl = (String) session.getAttribute("customRelayState");
if (relayUrl != null) {
session.removeAttribute("customRelayState");
response.sendRedirect(relayUrl);
return;
}
}
// Default fallback
response.sendRedirect("/content/mysite.html");
}
}
SAML Config Change
Set:
Default Redirect URL = /bin/custom/relayredirect
This will ensure the user is always returned to the original request after successful SAML login.
Note:
.
Hi @Som_Adobe ,
Use the RelayState parameter in the SAML SSO protocol, which is designed for preserving state between requests during SSO. The trick is to manually encode your query parameters into RelayState.
However, AEMaaCS’s SAML Authentication Handler does not automatically support appending raw request parameters to RelayState unless you customize it.
Try below solution:
1. Enable RelayState in SAML Auth Handler
Go to OSGi Console:
https://<author|publisher>/system/console/configMgr/com.adobe.granite.auth.saml.SamlAuthenticationHandler
Ensure these values are set:
Property : Value
Path : /content or specific paths
IDP URL : Your SAML Identity Provider URL
Service Provider Entity ID : AEM SP Entity ID
Handle SAML Request With POST : true
Use Encryption : false (or as per your config)
UserID Attribute : e.g., NameID
Autocreate CRX Users : true
Default Redirect URL : / or a custom path
Use RelayState : true =>this is critical
2. Custom Filter to Preserve Query Parameters
Create an AEM Sling Filter (in an AEM Project) that runs before authentication and saves query parameters into the session as RelayState.
Sample Java Filter:
@Component(service = Filter.class,
immediate = true,
property = {
Constants.SERVICE_RANKING + ":Integer=10000",
"sling.filter.scope=request",
"sling.filter.pattern=/content/.*"
})
public class SamlRelayStateFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
if (!request.getUserPrincipal() && request.getQueryString() != null) {
String query = request.getQueryString();
String originalUrl = request.getRequestURL() + "?" + query;
HttpSession session = request.getSession();
session.setAttribute("customRelayState", originalUrl);
}
chain.doFilter(req, res);
}
}
This saves the full original URL (with query params) into the session before redirection to IDP.
In your SAML config:
Set Default Redirect URL to /bin/custom/relayredirect
This way, after login, the user will be taken back to their original URL with all parameters.
Regards,
Amit
Views
Replies
Total Likes
Sure @AmitVishwakarma, Thank you so much !
I will try this out and let you know. Just to confirm, the exact property on SAML Configuration will be "saml.sp.use.relaystate": true - is that correct ?
Views
Replies
Total Likes
Hi @Som_Adobe ,
There is no need to set "saml.sp.use.relaystate": true manually in code or a config file.
Instead:
Go to the OSGi Config Manager (/system/console/configMgr)
Search for com.adobe.granite.auth.saml.SamlAuthenticationHandler
Find the checkbox labeled “Use RelayState”
Check it to enable RelayState
Regards,
Amit
Views
Replies
Total Likes
Hi @AmitVishwakarma we are using AEM as a Cloud Service where this property is not there. Please suggest what is the alternative we should follow for AEMaaCS.
Regards,
Som
Views
Replies
Total Likes
Hi @Som_Adobe ,
AEMaaCS has stricter constraints than AMS or on-prem AEM (e.g., limited access to OSGi console, restricted SAML configs). So, here’s a Cloud-native workaround:
1. Use a Front-End Proxy or Dispatcher Rewrite (Preferred if possible)
If you control the entry point (e.g., a CDN like CloudFront, Azure Front Door, or Dispatcher), you can:
Encode the query params in a single RelayState-safe parameter (e.g., base64 or URL-encoded string).
Redirect to AEM with something like:
/content/mysite.html?relayState=base64(queryParams)
Then AEM just needs to preserve the relayState through SAML.
2. Custom Sling Filter to Capture Parameters and Redirect After Login:
Since OSGi checkbox options are not available in AEMaaCS, build a custom Sling Filter and a custom redirect servlet to simulate RelayState functionality:
Sling Filter (Runs Pre-authentication)
Stores the incoming full request URL (with query params) in a cookie or session attribute.
@Component(service = Filter.class,
property = {
Constants.SERVICE_RANKING + ":Integer=10000",
"sling.filter.scope=request"
})
public class SamlRelayStateFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();
if (req.getUserPrincipal() == null && req.getQueryString() != null) {
String fullUrl = req.getRequestURL().toString() + "?" + req.getQueryString();
session.setAttribute("customRelayState", fullUrl);
}
chain.doFilter(request, response);
}
}
Custom Redirect Servlet (Runs Post-authentication)
This servlet reads the stored URL and redirects the user after login
@Component(service = Servlet.class,
property = {
"sling.servlet.paths=/bin/custom/relayredirect",
"sling.servlet.methods=GET"
})
public class RelayRedirectServlet extends SlingAllMethodsServlet {
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
if (session != null) {
String relayUrl = (String) session.getAttribute("customRelayState");
if (relayUrl != null) {
session.removeAttribute("customRelayState");
response.sendRedirect(relayUrl);
return;
}
}
// Default fallback
response.sendRedirect("/content/mysite.html");
}
}
SAML Config Change
Set:
Default Redirect URL = /bin/custom/relayredirect
This will ensure the user is always returned to the original request after successful SAML login.
Note:
.
Thank You so much @AmitVishwakarma for this detailed answer !
Views
Replies
Total Likes
Views
Likes
Replies