We have asset-details page where we show asset details(metadata). we pass the dam asset path in the details page suffix.
The asset details are shown in the asset-details component in asset-details page.
we maintain the asset access level in asset metadata property itself like
user-access=public,private
or
user-access=public
or
user-access=private
We have following use cases.
1. if anonymous user access the public asset(user-access=public) then the asset details page should render properly
2. if sso logged-in user access the private or public asset(user-access=public,private) then the asset details page should render properly
3. if anonymous user access the private asset(user-access=private) then in the java code has to do saml authentication and land in the same page.
Note: In our site some pages we configured saml authentication and it is working fine but we didnt add the asset-details page path in the saml configuration because asset-datails page some time should act as public page.
Please need opinions on use-case #3 and thanks in advance.
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @saibul2 ,
To handle the use case where anonymous users trying to access private assets are redirected to SSO (SAML) authentication and then landed back on the same asset details page, you'll need to incorporate custom logic into your AEM component and potentially use a servlet or filter to manage the authentication flow. Here’s a step-by-step guide on how to achieve this:
Component Logic for Asset Access:
Servlet/Filter for SSO Redirection:
Update your asset-details component's Java class to check the asset metadata and user authentication status:
import com.day.cq.dam.api.Asset;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.propertytypes.ServiceDescription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.RepositoryException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
@Component(service = {Servlet.class})
@ServiceDescription("Asset Details Servlet")
public class AssetDetailsServlet extends SlingSafeMethodsServlet {
private static final Logger log = LoggerFactory.getLogger(AssetDetailsServlet.class);
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
String assetPath = request.getRequestPathInfo().getSuffix();
Resource assetResource = request.getResourceResolver().getResource(assetPath);
if (assetResource != null) {
Asset asset = assetResource.adaptTo(Asset.class);
if (asset != null) {
String userAccess = asset.getMetadataValue("user-access");
if (userAccess != null) {
boolean isUserAuthenticated = request.getUserPrincipal() != null;
boolean isPublicAsset = userAccess.contains("public");
boolean isPrivateAsset = userAccess.contains("private");
if (isPublicAsset || (isPrivateAsset && isUserAuthenticated)) {
// Render the asset details page
request.getRequestDispatcher("/content/asset-details-page.html").forward(request, response);
} else if (isPrivateAsset && !isUserAuthenticated) {
// Redirect to SSO login
String redirectUrl = "/content/sso/login?resource=" + request.getRequestURI();
response.sendRedirect(redirectUrl);
} else {
response.sendError(SlingHttpServletResponse.SC_FORBIDDEN, "Access denied");
}
}
} else {
response.sendError(SlingHttpServletResponse.SC_NOT_FOUND, "Asset not found");
}
} else {
response.sendError(SlingHttpServletResponse.SC_NOT_FOUND, "Resource not found");
}
}
}
Configure your SSO system to handle the resource parameter in the query string so that after successful authentication, the user is redirected back to the original asset details page.
In your SSO login handler, capture the resource parameter and use it to redirect the user post-authentication:
// Pseudo-code for SSO login handler
String resource = request.getParameter("resource");
if (resource != null && !resource.isEmpty()) {
response.sendRedirect(resource);
} else {
response.sendRedirect("/default-redirect-page");
}
You can also create an AEM filter to handle the logic of checking access levels and performing the redirection. This can help you centralize the access control logic.
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.engine.EngineConstants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.propertytypes.ServiceDescription;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component(service = Filter.class, property = {
EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST,
"sling.filter.pattern=/content/asset-details.*"
})
@ServiceDescription("Asset Access Control Filter")
public class AssetAccessControlFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
SlingHttpServletRequest request = (SlingHttpServletRequest) servletRequest;
SlingHttpServletResponse response = (SlingHttpServletResponse) servletResponse;
String assetPath = request.getRequestPathInfo().getSuffix();
Resource assetResource = request.getResourceResolver().getResource(assetPath);
if (assetResource != null) {
ValueMap properties = assetResource.getValueMap();
String userAccess = properties.get("user-access", String.class);
if (userAccess != null) {
boolean isUserAuthenticated = request.getUserPrincipal() != null;
boolean isPublicAsset = userAccess.contains("public");
boolean isPrivateAsset = userAccess.contains("private");
if (isPublicAsset || (isPrivateAsset && isUserAuthenticated)) {
filterChain.doFilter(servletRequest, servletResponse);
} else if (isPrivateAsset && !isUserAuthenticated) {
String redirectUrl = "/content/sso/login?resource=" + request.getRequestURI();
response.sendRedirect(redirectUrl);
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied");
}
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Resource not found");
}
}
@Override
public void destroy() {
}
}
By implementing these steps, you can ensure that your asset-details page handles public and private asset access appropriately and supports SSO authentication when necessary.
Views
Replies
Total Likes
Hi @saibul2 ,
To handle the use case where anonymous users trying to access private assets are redirected to SSO (SAML) authentication and then landed back on the same asset details page, you'll need to incorporate custom logic into your AEM component and potentially use a servlet or filter to manage the authentication flow. Here’s a step-by-step guide on how to achieve this:
Component Logic for Asset Access:
Servlet/Filter for SSO Redirection:
Update your asset-details component's Java class to check the asset metadata and user authentication status:
import com.day.cq.dam.api.Asset;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.propertytypes.ServiceDescription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.RepositoryException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
@Component(service = {Servlet.class})
@ServiceDescription("Asset Details Servlet")
public class AssetDetailsServlet extends SlingSafeMethodsServlet {
private static final Logger log = LoggerFactory.getLogger(AssetDetailsServlet.class);
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
String assetPath = request.getRequestPathInfo().getSuffix();
Resource assetResource = request.getResourceResolver().getResource(assetPath);
if (assetResource != null) {
Asset asset = assetResource.adaptTo(Asset.class);
if (asset != null) {
String userAccess = asset.getMetadataValue("user-access");
if (userAccess != null) {
boolean isUserAuthenticated = request.getUserPrincipal() != null;
boolean isPublicAsset = userAccess.contains("public");
boolean isPrivateAsset = userAccess.contains("private");
if (isPublicAsset || (isPrivateAsset && isUserAuthenticated)) {
// Render the asset details page
request.getRequestDispatcher("/content/asset-details-page.html").forward(request, response);
} else if (isPrivateAsset && !isUserAuthenticated) {
// Redirect to SSO login
String redirectUrl = "/content/sso/login?resource=" + request.getRequestURI();
response.sendRedirect(redirectUrl);
} else {
response.sendError(SlingHttpServletResponse.SC_FORBIDDEN, "Access denied");
}
}
} else {
response.sendError(SlingHttpServletResponse.SC_NOT_FOUND, "Asset not found");
}
} else {
response.sendError(SlingHttpServletResponse.SC_NOT_FOUND, "Resource not found");
}
}
}
Configure your SSO system to handle the resource parameter in the query string so that after successful authentication, the user is redirected back to the original asset details page.
In your SSO login handler, capture the resource parameter and use it to redirect the user post-authentication:
// Pseudo-code for SSO login handler
String resource = request.getParameter("resource");
if (resource != null && !resource.isEmpty()) {
response.sendRedirect(resource);
} else {
response.sendRedirect("/default-redirect-page");
}
You can also create an AEM filter to handle the logic of checking access levels and performing the redirection. This can help you centralize the access control logic.
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.engine.EngineConstants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.propertytypes.ServiceDescription;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component(service = Filter.class, property = {
EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST,
"sling.filter.pattern=/content/asset-details.*"
})
@ServiceDescription("Asset Access Control Filter")
public class AssetAccessControlFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
SlingHttpServletRequest request = (SlingHttpServletRequest) servletRequest;
SlingHttpServletResponse response = (SlingHttpServletResponse) servletResponse;
String assetPath = request.getRequestPathInfo().getSuffix();
Resource assetResource = request.getResourceResolver().getResource(assetPath);
if (assetResource != null) {
ValueMap properties = assetResource.getValueMap();
String userAccess = properties.get("user-access", String.class);
if (userAccess != null) {
boolean isUserAuthenticated = request.getUserPrincipal() != null;
boolean isPublicAsset = userAccess.contains("public");
boolean isPrivateAsset = userAccess.contains("private");
if (isPublicAsset || (isPrivateAsset && isUserAuthenticated)) {
filterChain.doFilter(servletRequest, servletResponse);
} else if (isPrivateAsset && !isUserAuthenticated) {
String redirectUrl = "/content/sso/login?resource=" + request.getRequestURI();
response.sendRedirect(redirectUrl);
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied");
}
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Resource not found");
}
}
@Override
public void destroy() {
}
}
By implementing these steps, you can ensure that your asset-details page handles public and private asset access appropriately and supports SSO authentication when necessary.
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies