如何在 JSF 上下文中替换经过身份验证的 javax.security.Principal?



我想在我的 JSF 应用程序中创建一个"模拟"功能。此功能将使管理员能够访问使用低级别用户进行身份验证的应用程序,甚至不知道密码。

我认为这将是一个简单的setUserPrincipal,类似于我用来获取当前登录用户的内容FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal(),但我在javax.faces.context.ExternalContext里面找不到任何"setUserPrincipal"方法......

简而言之,我想要以编程方式更改当前登录的用户,以便管理员可以模拟任何其他用户,而无需通知凭据。可能吗?

谢谢

我强烈建议不要使用身份验证/授权,除非您真的没有其他选择。

无论如何,省略JSF,它在游戏中出现得太晚了。

最简单的方法是提供自定义请求,并提供一个过滤器:

@WebFilter(filterName = "impersonateFilter", urlPatterns = "/*", asyncSupported = true)
public class ImpersonateFilter implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
// do nothing
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletRequest httpRequest = (HttpServletRequest) request;
ImpersonateRequest impersonateRequest = new ImpersonateRequest(httpRequest);
chain.doFilter(impersonateRequest, response);
}
@Override
public void destroy()
{
// do nothing
}
public static class ImpersonateRequest extends HttpServletRequestWrapper
{
protected Principal principal;
public ImpersonateRequest(HttpServletRequest request)
{
super(request);
HttpSession session = request.getSession(false);
if(session != null)
{
principal = (Principal) session.getAttribute(ImpersonateRequest.class.getName());
}
}
@Override
public Principal getUserPrincipal()
{
if(principal == null)
{
principal = super.getUserPrincipal();
}
return principal;
}
public void setUserPrincipal(Principal principal)
{
this.principal = principal;
getSession().setAttribute(ImpersonateRequest.class.getName(), principal);
}
@Override
public String getRemoteUser()
{
return principal == null ? super.getRemoteUser() : principal.getName();
}
}
}

这样的事情应该就足够了。

相关内容

最新更新