Shiro本地会话管理是否与JSF SessionScoped CDI Bean兼容

时间:2018-03-02 03:14:35

标签: session jsf cdi shiro

我遇到了Shiro原生会话管理和JSF CDI SessionScoped bean的问题。我使用的是Shiro 1.4.0和Payara 4.1.1.171(build 137)。这是一种复杂的交互,所以我创建了一个非常简单的场景来演示这个问题(参见下面的代码)。以下是发生的事情:

当我使用Shiro的默认(非本地)会话管理时,我可以登录测试应用程序并按“Say Something New”按钮(使用AJAX),我的屏幕将使用新消息正确更新。我可以根据需要多次重复按“Say Something New”按钮,屏幕将使用新消息正确更新。如果我然后单击“Go Away”按钮,我退出会话,我可以看到我的SessionScoped bean PreDestroy方法被调用,一切都很好。然后我可以再次登录并重复测试,没有任何问题,每次登录时,我都会看到我的SessionScoped bean的PostConstruct方法被正确调用。

但是,当我更改shiro.ini文件以使用本机会话管理时,测试不再有效。相反,这就是发生的事情:我登录到应用程序并看到Hello屏幕。然后我点击“Say Something New”。我立即被重定向回登录屏幕。如果我再次登录,当我点击“Say Something New”按钮时,整个过程会重复。登录似乎工作正常,但似乎使用本机会话管理,Shiro不再跟踪会话?例如,当使用F12开发者工具时,我可以看到JSESSIONID cookie值不断变化,它不应该。 (它没有随非本地会话管理而改变。)

我无论如何都不是四郎的专家,但我不知道我做错了什么?我的shiro.ini文件看起来像Shiro项目页面和Web上显示的许多示例。

我需要使用Shiro的本机会话管理的原因是我想为单点登录实现EhCache SessionDAO。否则,我只会继续使用默认(非本机)会话管理。但是,正如你从我的测试中看到的那样,我还没有实现任何特殊的缓存 - 这只是一个简单的应用程序,出于某种原因表现得很奇怪? (无论如何,对我来说。)我不明白为什么Shiro没有维持会议。

如果有人是Shiro + JSF集成的专家,我会非常感谢一些指针!谢谢!

hello.xhtml:

<!DOCTYPE html>
<html lang="en"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <title>Session Test</title>
        <f:facet name="first">
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        </f:facet>
    </h:head>
    <h:body>
        <h:form>
            <p><h:outputText value="Hi. Session created at: #{testBean.sessionTime}"/></p>
            <p><h:outputText value="Latest message: #{testBean.message}"/></p>
            <p><h:commandButton ajax="true" value="Say Something New" action="#{testBean.saySomethingNew}"/></p>
            <p><h:commandButton value="Go Away" action="#{testBean.sayGoodbye()}"/></p>
        </h:form>
    </h:body>
</html>

/*
 * Test Backing Bean
 */
package com.testco;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

/**
 * Session test bean
 */
@Named
@SessionScoped
public class TestBean implements java.io.Serializable {

    private static final Logger LOGGER = Logger.getLogger("com.testco");

    private Date sessionTime;

    private String message;

    @PostConstruct
    private void initialize() {
        LOGGER.log(Level.INFO, "PostConstruct/initialize method called.");
        sessionTime = new Date();
    }

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

    public void saySomethingNew() {
        setMessage("Something new at: " + new Date());
    }

    @PreDestroy
    private void shutdown() {
        LOGGER.log(Level.INFO, "PreDestroy/shutdown method called.");
    }

    public Date getSessionTime() {
        return sessionTime;
    }

    public void setSessionTime(Date sessionTime) {
        this.sessionTime = sessionTime;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

shiro.ini:

[main]
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager

# Authentication
# Some custom objects here but this all seems to work fine with non-native session management
authc =  com.qed.aes.system.security.VerboseFormAuthenticationFilter
authc.loginUrl = /faces/login.xhtml
aesrealm =  com.qed.aes.system.security.AESRealm
securityManager.realms = $aesrealm

# Set up logout behavior
logout.redirectUrl = /faces/hello.xhtml

[urls]
/faces/login.xhtml = authc
/faces/javax.faces.resource/** = anon
/faces/logout.xhtml = logout
/** = authc

0 个答案:

没有答案