JSF中的基本安全性

JSF中的基本安全性,jsf,login,Jsf,Login,我希望看到一个简单的登录应用程序,而不是像这样简单 我想要了解的是JSF是如何工作的,我已经开发了很多ASP.NET,在这里您可以隐藏代码,并且您可以检查登录时是否创建了会话 在JSF中使用类似的解决方案将非常好 这基本上就是我想要实现的目标: 登录页面 如果可以的话 创建会话并返回“成功” 如果失败 返回“失败” (成功和失败被映射到faces config.xml) 在success页面,我想确认用户已登录,因此不能导航到“success.jspx”如果您没有获得正确的会话。除了

我希望看到一个简单的登录应用程序,而不是像这样简单

我想要了解的是JSF是如何工作的,我已经开发了很多ASP.NET,在这里您可以隐藏代码,并且您可以检查登录时是否创建了会话

在JSF中使用类似的解决方案将非常好

这基本上就是我想要实现的目标:

  • 登录页面
  • 如果可以的话
    • 创建会话并返回“成功”
  • 如果失败
    • 返回“失败”
(成功和失败被映射到faces config.xml)


在success页面,我想确认用户已登录,因此不能导航到“success.jspx”如果您没有获得正确的会话。

除了能够使用组件
呈现的
属性等面向基于角色的安全性之外,核心JSF中没有固有的身份验证功能

默认情况下,JSF应用程序依赖于与包含它的web组件相同的容器管理的安全机制()。像这样的第三方框架可以提供替代方案

如果您想添加自己的应用程序安全性,a是一种更简单的机制

此筛选器保护
web.xml
中定义的
restricted
目录下的资源:

  <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 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;
  }
}
faces config.xml
中定义的登录bean:

  <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 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;
  }
}
restricted_login.jsp
页面中的JSF登录表单:

  <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/机制是为了简洁,而不是任何形式的最佳实践;有关更多选项,请参阅。)

如果您愿意尝试更高级的方法,那么我建议您研究spring security+JSF。它就像一个符咒

您可以编写应用程序,就好像它没有处于安全状态一样,然后只需配置应该使用方面保护的区域

春季安全:


教程:

最好的方法是使用容器管理的安全性


关于如何使用
glassfish
jsf

实现这一点,如果您使用模板,我发现您实际上不需要过滤器

index.jsp

<jsp:forward page="startup.faces"></jsp:forward>
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>

****
.
.  
.
.

这就是我的解决方案。我已经对它进行了非常彻底的测试,它似乎工作得很好。

您能否澄清这与容器管理的安全性有何不同在考虑了每个人的优点/缺点之后,如何选择一个而不是另一个?@Marcos-这真的应该是它自己的问题,可能是引用了这个名称。实际上我已经在这里发布了类似的内容:
StartupBean
中的
@ManagedBean
名称属性是不必要的,因为默认情况下它会得到这个名称。相关:或者如果您对第三方库(如Shiro)开放,那么
<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>