如何将 SSO 身份验证与 JSF 集成?
How can I integrate SSO authentication with JSF?
我目前正在使用过滤器来检查 SSO 身份验证。 (如果请求 header 包含变量 "Proxy-Remote-User",则认为 SSO 已通过身份验证)。
if (!(isSsoLoggedIn(request)) {
response.sendRedirect(ERROR_PAGE);
return;
} else {
chain.doFilter(req, res);
}
private boolean isSsoLoggedIn(HttpServletRequest request) {
return request != null && request.getHeader("Proxy-Remote-User") != null
&& !request.getHeader("Proxy-Remote-User").equals("");
}
现在,一旦用户通过身份验证,我想将该变量(它是一个电子邮件地址)传递给 JSF。我用 session-scoped bean:
@PostConstruct
public void init {
Map<String, String> requestHeaderMap = FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderMap();
String email = requestHeaderMap.get("Proxy-Remote-User");
user = getPersonFromDB(email);
}
这看起来很简单,但我不确定它是否是 "right" 的方法。依靠 bean 的实例化来验证身份验证似乎是不正确的。
我的一个想法: 使用 CDI session-scoped bean 并将其@Inject 到过滤器中。然后,您可以让过滤器本身检查有效用户,如果有效,则将其设置在 session-scoped bean 中,否则将其转发到错误页面。
这听起来像是一个有效的解决方案吗?
另一种方法可以让每个页面在呈现视图之前检查身份验证,并使用此处提到的视图参数:
JSF calls methods when managed bean constructor sends 404 ERROR CODE
<f:metadata>
<f:viewAction action="#{bean.checkForValidUser}" />
</f:metadata>
我遇到的唯一问题是...这需要 copying/pasting 每个页面都使用相同的代码,这似乎是多余的(或者至少是供所有人使用的模板)。
这是我想出的答案(感谢@BalusC 的一些提示)。
我检查是否已启用开发者登录或是否已验证 SSO。获得电子邮件地址后,我会查看其是否为有效用户,验证 JSF 会话是否包含正确的用户,如果是,则转发他们。
/**
* This filter handles SSO login (or developer login) privileges to the web
* application.
*/
@WebFilter(servletNames = "Faces Servlet")
public class SecurityFilter implements Filter {
@Inject
private SessionManager sessionManager;
@EJB
private PersonWriteFacadeRemote personFacade;
private HttpServletRequest currentRequest;
private HttpServletResponse currentResponse;
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
currentRequest = (HttpServletRequest) req;
currentResponse = (HttpServletResponse) res;
HttpSession session = currentRequest.getSession();
String requestedPage = currentRequest.getRequestURI();
// check if the session is initialized
// if not, initialize it
if (!isSessionInitialized()) {
Person user = getCurrentUser();
// if we can't figure out who the user is, then send 401 error
if (user != null) {
initializeSession(user);
} else {
currentResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
// if it is initialized, check if it actually matches the current
// user
// if not, invalidate the session and redirect them back to the page
// to reinitialize it
} else if (!isSessionCurrentUsers()) {
session.invalidate();
currentResponse.sendRedirect(requestedPage);
return;
}
chain.doFilter(req, res); // If all looks good, continue the request
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
private Person getCurrentUser() {
try {
return personFacade.createFromEmail(getUserEmail());
} catch (InvalidAttributesException ex) {
Logger.getLogger(SecurityFilter.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
private String getUserEmail() {
return isDevLoginEnabled() ? getUserEmailFromJndi() : getUserEmailFromSso();
}
private String getUserEmailFromJndi() {
return JNDI.lookup("devLoginEmail");
}
private String getUserEmailFromSso() {
return currentRequest != null && currentRequest.getHeader("Proxy-Remote-User") != null
&& !currentRequest.getHeader("Proxy-Remote-User").equals("")
? currentRequest.getHeader("Proxy-Remote-User") : null;
}
private boolean isDevLoginEnabled() {
Boolean devLoginEnabled = JNDI.lookup("devLoginEnabled");
return (devLoginEnabled != null ? devLoginEnabled : false);
}
private boolean isSessionInitialized() {
return sessionManager.getUser() != null;
}
private void initializeSession(Person user) {
sessionManager.initializeSession(user);
}
private boolean isSessionCurrentUsers() {
return sessionManager.getUser() != null && sessionManager.getUser().getEmail() != null
&& sessionManager.getUser().getEmail().equals(getUserEmail());
}
}
我目前正在使用过滤器来检查 SSO 身份验证。 (如果请求 header 包含变量 "Proxy-Remote-User",则认为 SSO 已通过身份验证)。
if (!(isSsoLoggedIn(request)) {
response.sendRedirect(ERROR_PAGE);
return;
} else {
chain.doFilter(req, res);
}
private boolean isSsoLoggedIn(HttpServletRequest request) {
return request != null && request.getHeader("Proxy-Remote-User") != null
&& !request.getHeader("Proxy-Remote-User").equals("");
}
现在,一旦用户通过身份验证,我想将该变量(它是一个电子邮件地址)传递给 JSF。我用 session-scoped bean:
@PostConstruct
public void init {
Map<String, String> requestHeaderMap = FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderMap();
String email = requestHeaderMap.get("Proxy-Remote-User");
user = getPersonFromDB(email);
}
这看起来很简单,但我不确定它是否是 "right" 的方法。依靠 bean 的实例化来验证身份验证似乎是不正确的。
我的一个想法: 使用 CDI session-scoped bean 并将其@Inject 到过滤器中。然后,您可以让过滤器本身检查有效用户,如果有效,则将其设置在 session-scoped bean 中,否则将其转发到错误页面。
这听起来像是一个有效的解决方案吗?
另一种方法可以让每个页面在呈现视图之前检查身份验证,并使用此处提到的视图参数:
JSF calls methods when managed bean constructor sends 404 ERROR CODE
<f:metadata>
<f:viewAction action="#{bean.checkForValidUser}" />
</f:metadata>
我遇到的唯一问题是...这需要 copying/pasting 每个页面都使用相同的代码,这似乎是多余的(或者至少是供所有人使用的模板)。
这是我想出的答案(感谢@BalusC 的一些提示)。
我检查是否已启用开发者登录或是否已验证 SSO。获得电子邮件地址后,我会查看其是否为有效用户,验证 JSF 会话是否包含正确的用户,如果是,则转发他们。
/**
* This filter handles SSO login (or developer login) privileges to the web
* application.
*/
@WebFilter(servletNames = "Faces Servlet")
public class SecurityFilter implements Filter {
@Inject
private SessionManager sessionManager;
@EJB
private PersonWriteFacadeRemote personFacade;
private HttpServletRequest currentRequest;
private HttpServletResponse currentResponse;
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
currentRequest = (HttpServletRequest) req;
currentResponse = (HttpServletResponse) res;
HttpSession session = currentRequest.getSession();
String requestedPage = currentRequest.getRequestURI();
// check if the session is initialized
// if not, initialize it
if (!isSessionInitialized()) {
Person user = getCurrentUser();
// if we can't figure out who the user is, then send 401 error
if (user != null) {
initializeSession(user);
} else {
currentResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
// if it is initialized, check if it actually matches the current
// user
// if not, invalidate the session and redirect them back to the page
// to reinitialize it
} else if (!isSessionCurrentUsers()) {
session.invalidate();
currentResponse.sendRedirect(requestedPage);
return;
}
chain.doFilter(req, res); // If all looks good, continue the request
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
private Person getCurrentUser() {
try {
return personFacade.createFromEmail(getUserEmail());
} catch (InvalidAttributesException ex) {
Logger.getLogger(SecurityFilter.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
private String getUserEmail() {
return isDevLoginEnabled() ? getUserEmailFromJndi() : getUserEmailFromSso();
}
private String getUserEmailFromJndi() {
return JNDI.lookup("devLoginEmail");
}
private String getUserEmailFromSso() {
return currentRequest != null && currentRequest.getHeader("Proxy-Remote-User") != null
&& !currentRequest.getHeader("Proxy-Remote-User").equals("")
? currentRequest.getHeader("Proxy-Remote-User") : null;
}
private boolean isDevLoginEnabled() {
Boolean devLoginEnabled = JNDI.lookup("devLoginEnabled");
return (devLoginEnabled != null ? devLoginEnabled : false);
}
private boolean isSessionInitialized() {
return sessionManager.getUser() != null;
}
private void initializeSession(Person user) {
sessionManager.initializeSession(user);
}
private boolean isSessionCurrentUsers() {
return sessionManager.getUser() != null && sessionManager.getUser().getEmail() != null
&& sessionManager.getUser().getEmail().equals(getUserEmail());
}
}