2015-06-23 2 views
0

В настоящее время я использую фильтр для проверки подлинности SSO. (SSO считается аутентифицированным, если заголовок запроса содержит переменную «Proxy-Remote-User»).Как интегрировать аутентификацию SSO с помощью JSF?

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. Я делаю это с сессионной областью действия фасоли:

@PostConstruct 
public void init { 
    Map<String, String> requestHeaderMap = FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderMap(); 
    String email = requestHeaderMap.get("Proxy-Remote-User"); 
    user = getPersonFromDB(email); 
} 

Это кажется достаточно простым, но я не уверен, если его «правильный» способ сделать это. Не похоже, чтобы полагаться на экземпляр компонента для проверки подлинности.

Одна из идей, которые у меня только что были: Используйте bei-интерфейс с сессией CDI и @ Вставьте его в фильтр. Затем вы можете сами проверить фильтр для действительного пользователя и, если он действителен, установить его в компоненте, зависящем от сеанса, в противном случае переслать его на страницу с ошибкой.

Это звучит как верное решение?

Другой подход мог бы иметь каждый чек страниц для аутентификации, прежде чем вид оказывается, с видом парам, как указано здесь:

JSF calls methods when managed bean constructor sends 404 ERROR CODE

<f:metadata> 
    <f:viewAction action="#{bean.checkForValidUser}" /> 
</f:metadata> 

Единственная проблема, у меня есть для это ... это потребует копирования/вставки одного и того же кода на каждую страницу, которая кажется излишней (или, по крайней мере, шаблон для всех их использования).

+0

У вас есть CDI под рукой? – BalusC

+0

К сожалению, я использую ManagedBeans, но у нас есть цель конвертировать в CDI в будущем. Я еще не изучил процедуру, но, если ее довольно легко, я, вероятно, мог бы перейти к ним, чтобы заставить это работать. – wsaxton

+0

Если я могу конвертировать в CDI, вы предполагаете, что мой CDI-решение выше будет действительным? – wsaxton

ответ

1

Вот ответ, который я придумал (благодаря некоторым советам от @BalusC).

Я проверяю, включена ли регистрация разработчика, или прошла аутентификация единого входа. Как только у меня есть адрес электронной почты, я вижу, если его действительный пользователь, проверьте, что сеанс 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()); 
    } 
} 
Смежные вопросы