记住我由 Spring Security 提供的功能
Posted
技术标签:
【中文标题】记住我由 Spring Security 提供的功能【英文标题】:Remember me functionality provided by Spring Security 【发布时间】:2014-07-23 18:12:18 【问题描述】:我是 Spring Security 的新手,正在尝试实现 Spring Security 提供的“记住我”功能。我关注了几个博客,但对我没有帮助。这是我实现的示例代码,现在遇到了一些问题。
jsfspring-sec-bean-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<beans:bean id="navigator" name="navigator" class="com.mumz.jsfspringsec.beans.Navigator" scope="session">
</beans:bean>
<beans:bean id="loginBean" name="loginBean" class="com.mumz.jsfspringsec.beans.LoginBean" scope="prototype">
<beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
<beans:property name="rememberMeServices" ref="rememberMeServices"></beans:property>
</beans:bean>
<beans:bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<beans:property name="key" value="jsfspring-sec" />
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="alwaysRemember" value="true" />
<beans:property name="tokenValiditySeconds" value="60" />
</beans:bean>
<beans:bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<beans:property name="key" value="jsfspring-sec"/>
</beans:bean>
<beans:bean id="rememberMeFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<beans:property name="rememberMeServices" ref="rememberMeServices"/>
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
jsfspring-sec-security-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<sec:http auto-config="true" use-expressions="true">
<sec:intercept-url pattern="/pages/secure/**" access="hasRole('ROLE_USER')" />
<sec:intercept-url pattern="/pages/unsecure/**" access="permitAll"/>
<sec:intercept-url pattern="/pages/common/**" access="permitAll"/>
<sec:intercept-url pattern="/**" access="permitAll"/>
<sec:form-login login-page="/pages/common/login.jsf"/>
<sec:remember-me key="jsfspring-sec" services-ref="rememberMeServices"/>
<sec:logout
invalidate-session="true"
delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE"
logout-success-url="/pages/common/login.jsf"></sec:logout>
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="rememberMeAuthenticationProvider"></sec:authentication-provider>
<sec:authentication-provider >
<sec:user-service id="userDetailsService">
<sec:user authorities="ROLE_USER" name="admin" password="admin" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
login.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<div align="right" style="">
<h:form id="loginFormId" prependId="false">
<div id="loginFieldsPnlId">
<div id="loginFieldUsrContId">
<h:outputText id="outTxtUserNameId" value="Username:" name="outTxtUserNameNm"></h:outputText>
<h:inputText id="userName" required="true" value="#loginMgmtBean.userName" requiredMessage="Please enter username"></h:inputText>
<h:outputLabel id="outLblUserNameId" for="userName" name="outLblUserNameNm"></h:outputLabel>
</div>
<div id="loginFieldPassContId">
<h:outputText id="outTxtPasswordId" value="Password:" name="outTxtPasswordNm"></h:outputText>
<h:inputSecret id="password" required="true" value="#loginMgmtBean.password" requiredMessage="Please enter password"></h:inputSecret>
<h:outputLabel id="outLblPasswordId" for="password" name="outLblPasswordNm"></h:outputLabel>
</div>
<div id="loginFieldPassContId">
<h:selectBooleanCheckbox id="rememberMe" value="#loginMgmtBean.rememberMe" label="Remember Me">Remember Me</h:selectBooleanCheckbox>
</div>
</div>
<div id="loginBtnPanelId">
<h:commandButton id="btnLoginId" value="Login" action="#loginMgmtBean.login" styleClass="loginPanelBtn"></h:commandButton>
<h:commandButton id="btnCancelId" value="Cancel" action="#loginMgmtBean.cancel" styleClass="loginPanelBtn" immediate="true" update="loginFormId"></h:commandButton>
</div>
</h:form>
</div>
<div>
<h:messages></h:messages>
</div>
</h:body>
</html>
LoginBean.java
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.RememberMeAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.RememberMeServices;
/**
* The Class LoginBean.
*/
@ManagedBean(name = "loginMgmtBean")
@RequestScoped
public class LoginBean
/** The user name. */
private String userName = null;
/** The password. */
private String password = null;
/** The remember me. */
private String rememberMe = null;
/** The authentication manager. */
@ManagedProperty(value = "#authenticationManager")
private AuthenticationManager authenticationManager = null;
/** The remember me services. */
@ManagedProperty(value = "#rememberMeServices")
private RememberMeServices rememberMeServices = null;
@ManagedProperty(value="#userDetailsService")
private UserDetailsService userDetailsService = null;
/**
* Login.
*
* @return the string
*/
public String login()
try
Authentication result = null;
if ("TRUE".equalsIgnoreCase(this.getRememberMe()))
UserDetails userDetails = userDetailsService.loadUserByUsername(getUserName());
RememberMeAuthenticationToken rememberMeAuthenticationToken = new RememberMeAuthenticationToken(
"jsfspring-sec", userDetails,
userDetails.getAuthorities());
HttpServletRequest httpServletRequest = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
rememberMeServices.loginSuccess(httpServletRequest, httpServletResponse, rememberMeAuthenticationToken);
result = rememberMeAuthenticationToken;
else
Authentication request = new UsernamePasswordAuthenticationToken(
this.getUserName(), this.getPassword());
result = authenticationManager.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
catch (AuthenticationException e)
e.printStackTrace();
return "Secured";
/**
* Cancel.
*
* @return the string
*/
public String cancel()
return null;
/**
* Logout.
*
* @return the string
*/
public String logout()
SecurityContextHolder.clearContext();
/**
* Delete Cookies
*/
HttpServletRequest httpServletRequest = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
Cookie cookie = new Cookie("SPRING_SECURITY_REMEMBER_ME_COOKIE", null);
cookie.setMaxAge(0);
cookie.setPath(httpServletRequest.getContextPath().length() > 0 ? httpServletRequest.getContextPath() : "/");
httpServletResponse.addCookie(cookie);
return "loggedout";
/**
* Gets the user name.
*
* @return the user name
*/
public String getUserName()
return userName;
/**
* Sets the user name.
*
* @param userName
* the new user name
*/
public void setUserName(String userName)
this.userName = userName;
/**
* Gets the password.
*
* @return the password
*/
public String getPassword()
return password;
/**
* Sets the password.
*
* @param password
* the new password
*/
public void setPassword(String password)
this.password = password;
/**
* Gets the remember me.
*
* @return the remember me
*/
public String getRememberMe()
return rememberMe;
/**
* Sets the remember me.
*
* @param rememberMe
* the new remember me
*/
public void setRememberMe(String rememberMe)
this.rememberMe = rememberMe;
/**
* Gets the authentication manager.
*
* @return the authentication manager
*/
public AuthenticationManager getAuthenticationManager()
return authenticationManager;
/**
* Sets the authentication manager.
*
* @param authenticationManager
* the new authentication manager
*/
public void setAuthenticationManager(
AuthenticationManager authenticationManager)
this.authenticationManager = authenticationManager;
/**
* Gets the remember me services.
*
* @return the remember me services
*/
public RememberMeServices getRememberMeServices()
return rememberMeServices;
/**
* Sets the remember me services.
*
* @param rememberMeServices
* the new remember me services
*/
public void setRememberMeServices(RememberMeServices rememberMeServices)
this.rememberMeServices = rememberMeServices;
public UserDetailsService getUserDetailsService()
return userDetailsService;
public void setUserDetailsService(UserDetailsService userDetailsService)
this.userDetailsService = userDetailsService;
每当我尝试运行此代码时,我都会收到一些错误消息,指出 userDetailsService 没有 bean 初始化。现在 userDetailsService 指的是一个接口 org.springframework.security.core.userdetails.UserDetailsService。另外我不确定它如何与数据库交互以进行用户 ID 和密码验证。
这是我收到的错误消息
19:42:08,387 ERROR [org.springframework.web.context.ContextLoader] (MSC service thread 1-8) Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rememberMeServices' defined in ServletContext resource [/WEB-INF/jsfspring-sec-bean-config.xml]: Cannot resolve reference to bean 'userDetailsService' while setting bean property 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userDetailsService' is defined
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1317) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1076) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:563) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:872) [spring-context-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.__refresh(AbstractApplicationContext.java:423) [spring-context-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java) [spring-context-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276) [spring-web-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197) [spring-web-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47) [spring-web-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3392) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3850) [jbossweb-7.0.13.Final.jar:]
at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) [rt.jar:1.6.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [rt.jar:1.6.0_45]
at java.lang.Thread.run(Unknown Source) [rt.jar:1.6.0_45]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userDetailsService' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:510) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1056) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:274) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(Bean DefinitionValueResolver.java:322) [spring-beans-3.0.2.RELEASE.jar:3.0.2.RELEASE]
... 24 more
更新
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>MyPortal</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<!-- Richfaces skin -->
<context-param>
<param-name>org.richfaces.skin</param-name>
<param-value>customBlueSky</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.enableControlSkinning</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.push.jms.enabled</param-name>
<param-value>true</param-value>
</context-param>
<error-page>
<error-code>500</error-code>
<location>/pages/errorPage.jsf</location>
</error-page>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/pages/login.jsf</location>
</error-page>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!-- Add Support for Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<!-- <listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener> -->
<!-- BIRT Support -->
<!-- Default locale setting. -->
<context-param>
<param-name>BIRT_VIEWER_LOCALE</param-name>
<param-value>en-US</param-value>
</context-param>
<!-- Default timezone setting. Examples: "Europe/Paris", "GMT+1". Defaults
to the container's timezone. -->
<context-param>
<param-name>BIRT_VIEWER_TIMEZONE</param-name>
<param-value></param-value>
</context-param>
<!-- Report resources directory for preview. Defaults to $birt home -->
<context-param>
<param-name>BIRT_VIEWER_WORKING_FOLDER</param-name>
<param-value></param-value>
</context-param>
<!-- Temporary document files directory. Defaults to $birt home/documents -->
<context-param>
<param-name>BIRT_VIEWER_DOCUMENT_FOLDER</param-name>
<param-value></param-value>
</context-param>
<!-- Flag whether the report resources can only be accessed under the working
folder. Defaults to true -->
<context-param>
<param-name>WORKING_FOLDER_ACCESS_ONLY</param-name>
<param-value>true</param-value>
</context-param>
<!-- Settings for how to deal with the url report path. e.g. "http://host/repo/test.rptdesign".
Following values are supported: <all> - All paths. <domain> - Only the paths
with host matches current domain. Note the comparison is literal, "127.0.0.1"
and "localhost" are considered as different hosts. <none> - URL paths are
not supported. Defaults to "domain". -->
<context-param>
<param-name>URL_REPORT_PATH_POLICY</param-name>
<param-value>domain</param-value>
</context-param>
<!-- Temporary image/chart directory. Defaults to $birt home/report/images -->
<context-param>
<param-name>BIRT_VIEWER_IMAGE_DIR</param-name>
<param-value></param-value>
</context-param>
<!-- Engine log directory. Defaults to $birt home/logs -->
<context-param>
<param-name>BIRT_VIEWER_LOG_DIR</param-name>
<param-value></param-value>
</context-param>
<!-- Report engine log level -->
<context-param>
<param-name>BIRT_VIEWER_LOG_LEVEL</param-name>
<param-value>WARNING</param-value>
</context-param>
<!-- Directory where to store all the birt report script libraries (JARs).
Defaults to $birt home/scriptlib -->
<context-param>
<param-name>BIRT_VIEWER_SCRIPTLIB_DIR</param-name>
<param-value></param-value>
</context-param>
<!-- Resource location directory. Defaults to $birt home -->
<context-param>
<param-name>BIRT_RESOURCE_PATH</param-name>
<param-value></param-value>
</context-param>
<!-- Preview report rows limit. An empty value means no limit. -->
<context-param>
<param-name>BIRT_VIEWER_MAX_ROWS</param-name>
<param-value></param-value>
</context-param>
<!-- Max cube fetch levels limit for report preview (Only used when previewing
a report design file using the preview pattern) -->
<context-param>
<param-name>BIRT_VIEWER_MAX_CUBE_ROWLEVELS</param-name>
<param-value></param-value>
</context-param>
<context-param>
<param-name>BIRT_VIEWER_MAX_CUBE_COLUMNLEVELS</param-name>
<param-value></param-value>
</context-param>
<!-- Memory size in MB for creating a cube. -->
<context-param>
<param-name>BIRT_VIEWER_CUBE_MEMORY_SIZE</param-name>
<param-value></param-value>
</context-param>
<!-- Defines the BIRT viewer configuration file -->
<context-param>
<param-name>BIRT_VIEWER_CONFIG_FILE</param-name>
<param-value>WEB-INF/viewer.properties</param-value>
</context-param>
<!-- Flag whether to allow server-side printing. Possible values are "ON"
and "OFF". Defaults to "ON". -->
<context-param>
<param-name>BIRT_VIEWER_PRINT_SERVERSIDE</param-name>
<param-value>ON</param-value>
</context-param>
<!-- Flag whether to force browser-optimized HTML output. Defaults to true -->
<context-param>
<param-name>HTML_ENABLE_AGENTSTYLE_ENGINE</param-name>
<param-value>true</param-value>
</context-param>
<!-- Filename generator class/factory to use for the exported reports. -->
<context-param>
<param-name>BIRT_FILENAME_GENERATOR_CLASS</param-name>
<param-value>org.eclipse.birt.report.utility.filename.DefaultFilenameGenerator</param-value>
</context-param>
<!-- Viewer Filter used to set the request character encoding to UTF-8. -->
<filter>
<filter-name>ViewerFilter</filter-name>
<filter-class>org.eclipse.birt.report.filter.ViewerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ViewerFilter</filter-name>
<servlet-name>ViewerServlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>ViewerFilter</filter-name>
<servlet-name>EngineServlet</servlet-name>
</filter-mapping>
<!-- Viewer Servlet Context Listener -->
<listener>
<listener-class>org.eclipse.birt.report.listener.ViewerServletContextListener</listener-class>
</listener>
<!-- Viewer HttpSession Listener -->
<listener>
<listener-class>org.eclipse.birt.report.listener.ViewerHttpSessionListener</listener-class>
</listener>
<!-- Viewer Servlet, Supports SOAP -->
<servlet>
<servlet-name>ViewerServlet</servlet-name>
<servlet-class>org.eclipse.birt.report.servlet.ViewerServlet</servlet-class>
</servlet>
<!-- Engine Servlet -->
<servlet>
<servlet-name>EngineServlet</servlet-name>
<servlet-class>org.eclipse.birt.report.servlet.BirtEngineServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ViewerServlet</servlet-name>
<url-pattern>/frameset</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ViewerServlet</servlet-name>
<url-pattern>/run</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>EngineServlet</servlet-name>
<url-pattern>/preview</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>EngineServlet</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>EngineServlet</servlet-name>
<url-pattern>/parameter</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>EngineServlet</servlet-name>
<url-pattern>/document</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>EngineServlet</servlet-name>
<url-pattern>/output</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>EngineServlet</servlet-name>
<url-pattern>/extract</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>JBoss BIRT Servlet</servlet-name>
<servlet-class>org.jboss.tools.birt.servlet.JBossBirtServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>JBoss BIRT Servlet</servlet-name>
<url-pattern>/embed</url-pattern>
</servlet-mapping>
<jsp-config>
<taglib>
<taglib-uri>/birt.tld</taglib-uri>
<taglib-location>/WEB-INF/tlds/birt.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
【问题讨论】:
你能附上你的 web.xml 吗? @VladimírSchäfer : 请同时查看 web.xml 文件,如果有问题请告诉我。 【参考方案1】:由于您尝试实例化接口,这就是您收到错误的原因。 尝试通过实现 UserDetailsService 接口创建一个类,然后尝试实例化该类对象。
【讨论】:
以上是关于记住我由 Spring Security 提供的功能的主要内容,如果未能解决你的问题,请参考以下文章
Spring WebFlux + Security - 我们有“记住我”功能吗?