问题
Am having a problem with Shiro native session management and JSF CDI SessionScoped beans. Am using Shiro 1.4.0 and Payara 4.1.1.171 (build 137). This is kind of a complicated interaction, so I have created a very simple scenario to demonstrate the problem (see code below). Here is what is happening:
When I use Shiro's default (non-native) session management, I can log in to the test application and press the "Say Something New" button (which is using AJAX) and my screen will be properly updated with the new message. I can repeat pressing the "Say Something New" button as many times as I want, and the screen will be updated properly with the new message. If I then click the "Go Away" button, I am logged out of the session, and I can see that my SessionScoped bean PreDestroy method is called and all is well. I can then log in again and repeat the test with no problems, and each time I log in, I will see that my SessionScoped bean's PostConstruct method is called correctly.
However, the minute I change the shiro.ini file to use native session management, the test no longer works. Instead, this is what happens: I log in to the application and see the Hello screen. I then click "Say Something New." Immediately I am redirected back to the login screen. If I log in again, the whole process repeats when I click the "Say Something New" button. The login seems to work fine, but it appears that with native session management, Shiro is no longer tracking the session? For example, when using F12 Developer Tools I can see that the JSESSIONID cookie value is changing constantly, which it should not. (It did not change with the non-native session management.)
I am not an expert in Shiro by any means, but I don't see what I am doing wrong? My shiro.ini file looks like many of the examples that are shown on the Shiro project page and around the Web.
The reason I need to use Shiro's native session management is that I want to implement an EhCache SessionDAO for single-sign-on. Otherwise, I would simply stay with the default (non-native) session management. However, as you can see from my test, I am not implementing any special caching just yet- this is just a simple app that for some reason is behaving oddly? (To me anyway.) I don't understand why Shiro is not maintaining the session.
If there is anyone who is expert on Shiro + JSF integration, I would greatly appreciate some pointers!! Thanks!!
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
来源:https://stackoverflow.com/questions/49062280/is-shiro-native-session-management-compatible-with-jsf-sessionscoped-cdi-beans