java - 使用基于表单的安全性时如何实现注销

标签 java security jakarta-ee ejb-3.0 java-ee-6

我使用基于 JDBC 表单的安全领域,我想实现注销,但是当我点击链接时,我看到了这个异常:

java.lang.RuntimeException: java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks) ... Caused by: java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks)

这是我为执行注销而创建的 EJB:

@Stateless(name = "ejbs/SessionSupportEJBImpl")
@DeclareRoles({"administrators","users"})
public class SessionSupportEJBImpl implements SessionSupportEJB {

    @PermitAll
    public void releaseUserState() {
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
                .getExternalContext().getSession(false);
        if (session != null) {
            session.invalidate();
        }
    }
}

这里我从辅助 bean 中调用它:

@Named("logoutBB")
@RequestScoped
public class LogoutBean {

    @EJB
    private SessionSupportEJB sessionSupportEJB;

    public String logout() {
        sessionSupportEJB.releaseUserState();
        return "index.xhtml?faces-redirect=true";
    }
}

这里是应该触发它的标记:

<h:form>
        <h:commandLink value="LOGOUT" action="#{logoutBB.releaseUserState}"/>
    </h:form>

我的疑问是:

  • 如何使注销功能起作用?

  • 是否必须始终在我的 EJB 上使用 ejbs 安全注释以允许访问?(使用安全领域时)

  • 我应该使用 servlet 而不是 EJB 来执行此操作吗?

  • 这种方法是否错误,我应该尝试其他方法来注销吗?

最佳答案

首先,我的建议是不要在 EJB 中调用 FacesContext,因为 FacesContext 是“ View 层”的一个元素。 EJB 的目的是代表“业务逻辑层”,最佳实践是将业务逻辑与 de View 隔离,因为您可以从多种类型的 View 访问业务逻辑。

关于如何关闭 session ,我建议执行以下操作:

创建一个 servlet 并实现方法 doGet 以关闭 session ,如下所示:

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
        HttpSession session= req.getSession();
        session.invalidate();
        RequestDispatcher rd = req.getRequestDispatcher("/login.xhtml"); //The url where go after logout
        rd.forward(req,res);
  }
}

因此您可以在您的 html/xhtml 页面中添加以下链接用于注销:

<a href="/logout">Logout</a>

如果您使用的是 JSF,要获取应用的上下文路径,您可以使用:

<a href="${request.contextPath}/logout">Logout</a>

免责声明:我假设您使用的是 Java EE 6。此外,我没有测试代码(但我知道它可以工作)如果您遇到编译问题请告诉我

关于java - 使用基于表单的安全性时如何实现注销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8256809/

相关文章:

java - SWT Widgets 绑定(bind)问题

java - 无法使用模拟来抛出异常 - 抛出的异常未被捕获

java - 重写匿名内部类方法不起作用

java - SoapUI 无法加密数据

java - JPQl 查询有错误

java - 自定义注释,用于从 HttpServletRequest 获取具有指定 @RequestHeaders 集的自定义对象

security - 我应该通过 Twitter 上的直接消息向用户提供丢失的凭据吗?

security - ASLR 如何有效?

java - Bean创建异常: Error creating bean with name 'sessionFactory'

java - 托管 bean 和 session bean 之间的区别