Подтвердить что ты не робот

Базовая безопасность в JSF

Я бы хотел увидеть простое приложение для входа, но не так просто, как this.

То, что я хотел бы достичь, - это понимание того, как работает JSF, я разработал много ASP.NET, где у вас есть код, и где вы можете просто проверить, был ли сеанс создан при входе в систему.

Аналогичное решение в JSF было бы большим.

Это в основном то, чего я хочу достичь:

  • Страница входа
  • ЕСЛИ ОК
    • Создайте сеанс и верните "успех"
  • ЕСЛИ НЕИСПРАВНО
    • return "failure"

( "Успех" и "неудача" отображаются в faces-config.xml)

На странице успеха я хочу быть Определенный, который пользователь вошел в систему, поэтому не нужно переходить к "success.jspx", если у вас нет правильного сеанса.

4b9b3361

Ответ 1

В ядре JSF нет встроенных функций аутентификации, кроме возможности использовать такие атрибуты, как атрибуты rendered, ориентированные на защиту на основе ролей.

По умолчанию приложение JSF опирается на те же механизмы безопасности, управляемые контейнером, что и его веб-компонент (JEE5 tutorial). Сторонние структуры, такие как Seam, могут предоставить альтернативы.

Если вы хотите добавить свою собственную безопасность приложений, фильтр сервлетов является одним из более простых механизмов.

Этот фильтр защищает ресурсы в каталоге restricted, как определено в web.xml:

  <filter>
    <filter-name>AuthenticationFilter</filter-name>
    <filter-class>restricted.AuthenticationFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>AuthenticationFilter</filter-name>
    <url-pattern>/restricted/*</url-pattern>
  </filter-mapping>

Реализация класса фильтра:

public class AuthenticationFilter implements Filter {
  private FilterConfig config;

  public void doFilter(ServletRequest req, ServletResponse resp,
      FilterChain chain) throws IOException, ServletException {
    if (((HttpServletRequest) req).getSession().getAttribute(
        AuthenticationBean.AUTH_KEY) == null) {
      ((HttpServletResponse) resp).sendRedirect("../restricted_login.faces");
    } else {
      chain.doFilter(req, resp);
    }
  }

  public void init(FilterConfig config) throws ServletException {
    this.config = config;
  }

  public void destroy() {
    config = null;
  }
}

A login bean, определенный в faces-config.xml:

public class AuthenticationBean {
  public static final String AUTH_KEY = "app.user.name";

  private String name;
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }

  public boolean isLoggedIn() {
    return FacesContext.getCurrentInstance().getExternalContext()
        .getSessionMap().get(AUTH_KEY) != null;
  }

  public String login() {
    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(
        AUTH_KEY, name);
    return "secret";
  }

  public String logout() {
    FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
        .remove(AUTH_KEY);
    return null;
  }
}

Форма входа в JSF на странице restricted_login.jsp:

  <f:view>
    <p><a href="restricted/secret.faces">try to go to secret
    page</a></p>
    <h:form>
    Username:
    <h:panelGroup rendered="#{not authenticationBean.loggedIn}">
        <h:inputText value="#{authenticationBean.name}" />
        <h:commandButton value="login"
          action="#{authenticationBean.login}" />
      </h:panelGroup>
      <h:commandButton value="logout"
        action="#{authenticationBean.logout}"
        rendered="#{authenticationBean.loggedIn}" />
    </h:form>
  </f:view>

(URL-адрес переадресации был выбран для краткости, а не для какой-либо лучшей практики, см. Servlet API для получения дополнительных параметров.)

Ответ 2

Если вы захотите попробовать более продвинутый подход, я предлагаю заглянуть в spring -security + JSF. Он работает как шарм.

Вы можете написать свое приложение, как если бы оно не находилось под защитой, а затем просто настроить, какие области должны быть защищены с помощью аспектов.

Spring безопасность: http://static.springsource.org/spring-security/site/

A Учебное пособие: http://ocpsoft.com/java/acegi-spring-security-jsf-login-page/

Ответ 3

Лучший способ сделать это - использовать безопасность, управляемую контейнером.

Вот учебник о том, как достичь этого с помощью glassfish и jsf.

Ответ 4

Если вы используете шаблоны, я обнаружил, что вам не нужен фильтр.

index.jsp

<jsp:forward page="startup.faces"></jsp:forward>

startup.xhtml(.faces), на самом деле не пытается показать экран, он вызывает загрузку javascript startupSubmit() и нажимает кнопку. Это отправляет поток прямо к методу start() в StartupBean.java.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0     Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
.
.
 <script type="text/javascript">
 function startupSubmit() {
  **document.getElementById('startupForm:startupBtn').click();**
 }
 </script>
 <h:body onload="startupSubmit()">
 <h:form id="startupForm">
 <p:commandButton id="startupBtn" value="" action="#{startupBean.start}" ajax="false" />  
 </h:form>
 </h:body>
</html>

StartupBean.java(не является частью шаблона .xhtml ниже). Метод start() в StartupBean устанавливает переменную с именем true (по умолчанию она равна false), а затем переходит к first.xhtml. Вы можете использовать любые критерии, которые вы хотите определить, если авторизованный параметр установлен в true... например, критерии входа.

package gov.irs.eservices.managementBeans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name="startupBean")
@SessionScoped
public class StartupBean {

private boolean authorized;

public StartupBean() {
}

public String start() {
    **setAuthorized(true);**
    return "first";
}

public boolean isAuthorized() {
    return authorized;
}

public void setAuthorized(boolean authorized) {
    this.authorized = authorized;
}
}

template.xhtml. В template.xhtml, только внутри формы, вы помещаете h: или p: panelGrid и только визуализируете его, если startupBean.authorized - true. Единственный способ, которым пользователь может попасть на страницы, содержащиеся в шаблоне, - это сначала запустить StartupBean.java.

<f:view>
<div id="container">
<h:form id="templateForm">
**<p:panelGrid rendered="#{startupBean.authorized}">**
    <div id="header">
        <ui:include src="header.xhtml" />
    </div>

    <div id="wrapper">
        <div id="firstId">
            <ui:insert name="first"></ui:insert>
        </div>
.
.  <!-- MORE PAGES -->
.
.
    </div>

    <div id="footer">
        <ui:include src="footer.xhtml" />
    </div>
</p:panelGrid>
</h:form>
</div>      
</f:view>

Итак, это мое решение. Я тестировал его довольно тщательно, и, похоже, он работает нормально.