JSF 2.0 简单登录页面

4
我需要限制应用程序的某一部分的访问。为了访问该部分,用户需要登录。我的数据库中有一个名为User的表格,其中包含用户名和哈希密码以及由两个输入和一个提交组成的登录表单。然而,我不知道应该使用哪些类/方法来登录用户(我假设JSF中支持此功能)。另外,据我所知,我需要编辑我的web.xml文件来支持身份验证。是否有人能提出典型的解决方案和我需要执行的一般步骤(链接、教程等)以获取该功能?
我还想知道如何限制未登录的人对另一页的访问,因此当用户键入页面的直接链接时,他将被重定向到主登录页面。
预先感谢您的任何帮助。 Grem.
2个回答

4
您可以使用Servlet 3.0中引入的HttpServletRequest API:
    /**
     * Performs authentication via HttpServletRequest API
     */
    public String login(String username, String password) throws IOException {
        try {
            getRequest().login(username, password);
            this.user = userDao.find(username);
        } catch (ServletException e) {
            JsfUtil.addErrorMessage(JsfUtil.getStringResource("loginFailed"));
            return null;
        }
        return "/index?faces-redirect=true";
    }

    public String logout() throws ServletException {
        this.user = null;
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        if (isAuthenticated())
           getRequest().logout();
        return "logout";
    }

    public boolean isAuthenticated() {
        return getRequest().getUserPrincipal() != null;
    }

    public static HttpServletRequest getRequest() {
        Object request = FacesContext.getCurrentInstance().getExternalContext().getRequest();
        return request instanceof HttpServletRequest
                ? (HttpServletRequest) request : null;
    }

2
这不是JSF 2的一部分。这是Servlet 3.0的一部分。因此,只有在Tomcat 7、Glassfish 3、JBoss AS 6等或更新版本上运行JSF 1.x / 2.x /任何版本时才有效。 - BalusC
@BalusC 感谢您指出这一点。我已相应地调整了答案。 - Theo
你有Servlet 2.5的解决方案吗?我使用的是使用Java5的JBoss5.1,所以我不能使用它。如果您有任何建议,那将非常好。 - Tioma
您可以使用基于表单的身份验证来使用 j_security_check。 - Theo

2
您可以使用 j_security_check 进行身份验证。您只需向其发送请求,它将根据您在 web.xml 中定义的领域和应用程序特定配置来处理身份验证。
根据您的应用服务器,还有一个额外的步骤,将已定义的角色(应用程序特定)链接到组(领域特定)。
以下是典型的配置:
<servlet>
    <servlet-name>Login</servlet-name>
    <servlet-class>com.example.Login</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Login</servlet-name>
    <url-pattern>/Login</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>Error</servlet-name>
    <servlet-class>com.example.Error</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Error</servlet-name>
    <url-pattern>/Error</url-pattern>
</servlet-mapping>
<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>example.com</realm-name>
    <form-login-config>
        <form-login-page>/Login</form-login-page>
        <form-error-page>/Error</form-error-page>
    </form-login-config>
</login-config>

<security-role>
    <role-name>arbitraryRoleName</role-name>
</security-role>

<security-constraint>
    <web-resource-collection>
        <web-resource-name>All Pages</web-resource-name>
        <url-pattern>/index.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>arbitraryRoleName</role-name>
    </auth-constraint>
</security-constraint>

请注意security-role。这仍需要链接到一个组,或者您正在定义的任何区别可以使用页面的用户和不能使用页面的用户。

非常感谢,Zack。难道只能使用j_security_check而没有其他办法吗?我知道有一个带有登录和注销方法的类可以使用,但是我不记得它的名称了。 - grem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接