我已经在 Glassfish 3.1.2 上运行的现有 JSF 2 应用程序中嵌入了 Spring Security。为此,我使用了转发到 /j_spring_security_check 的方法,如下文所述:
http://ocpsoft.org/java/acegi-spring-security-jsf-login-page/
我的代码几乎是文章代码的一对一副本。
这是login.xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
template="/template/template.xhtml">
<ui:define name="content">
<h:form id="loginForm" prependId="false">
<h:panelGrid columns="2">
<h:outputText value="#{msg['loginDialog.login']}: " />
<h:inputText id="j_username" required="true" />
<h:outputText value="#{msg['loginDialog.password']}" />
<h:inputSecret id="j_password" required="true" />
</h:panelGrid>
<h:commandButton type="submit"
action="#{loginBean.doLogin}"
value="#{msg['loginDialog.register']}" />
</h:form>
</ui:define>
这是我的登录 bean:
public class LoginBean implements Serializable {
public String doLogin() throws IOException, ServletException {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
Map map = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String j_user = (String) map.get("j_username");
String j_pwd = (String) map.get("j_password");
RequestDispatcher dispatcher = ((ServletRequest) context.getRequest()).getRequestDispatcher("/j_spring_security_check?j_username=" + j_user + "&j_password=" + j_pwd);
dispatcher.forward((ServletRequest) context.getRequest(), (ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
return null;
}
}
这是安全上下文的声明:
<context:component-scan base-package="com.mycompany.package"/>
<security:global-method-security
secured-annotations="enabled">
</security:global-method-security>
<security:http auto-config="true"
access-denied-page="/accessDenied.xhtml">
<security:intercept-url pattern="/*"
access="ROLE_VIEWER,ROLE_CREATOR,ROLE_ADMIN" />
<security:form-login
login-processing-url="/j_spring_security_check"
login-page="/login.xhtml"
default-target-url="/main.xhtml"
authentication-failure-url="/login.xhtml" />
<security:logout logout-url="/logout*"
logout-success-url="/login.xhtml"
invalidate-session="true"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref='userDetailsService'/>
</security:authentication-manager>
然后我创建了一个监听器来捕获所有 AbstractAuthenticationEvent:
public class AuthenticationListener implements
ApplicationListener<AbstractAuthenticationEvent> {
private final static Log log = LogFactory.getLog(AuthenticationListener.class);
@Override
public void onApplicationEvent(AbstractAuthenticationEvent e) {
// some processing
}
}
问题是:每次成功登录后,AuthenticationEvent 会生成两次,而不是一次,正如它所建议的那样。
有人会解释,有什么问题吗?
一些补充:事件生成两次,因为(我不明白为什么),登录后立即自动注销,然后进行新的身份验证。这是来自日志的片段:
INFO: * * 试图检索用户
INFO: * * 找到用户
信息:休眠:插入审计(EVENT_TYPE、EVENT_TIMESTAMP、USER_ID)值(?、?、?)
信息:当前会话被 org.apache.catalina.session.StandardSessionFacade@57ac8e 注销用户销毁:3ee7b951888eb8920d07fefceaec...
信息:注销
信息:当前会话已创建:3f1fd377302220f2f27313c06cdc 于 2012 年 6 月 25 日星期一 16:00:57 CEST 由 org.apache.catalina.session.StandardSessionFacade@912e6a
信息:休眠:插入审计(EVENT_TYPE、EVENT_TIMESTAMP、USER_ID)值(?、?、?)
这是带有调试功能的日志(对不起,列表很长):
26 Jun 2012 12:47:58,703 DEBUG HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
26 Jun 2012 12:47:58,703 DEBUG SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
26 Jun 2012 12:48:04,078 DEBUG FilterChainProxy : /login.xhtml at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
26 Jun 2012 12:48:04,078 DEBUG HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
26 Jun 2012 12:48:04,078 DEBUG HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@10fbf9. A new one will be created.
26 Jun 2012 12:48:04,078 DEBUG FilterChainProxy : /login.xhtml at position 2 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
26 Jun 2012 12:48:04,078 DEBUG FilterChainProxy : /login.xhtml at position 3 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
26 Jun 2012 12:48:04,078 DEBUG FilterChainProxy : /login.xhtml at position 4 of 10 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
26 Jun 2012 12:48:04,078 DEBUG FilterChainProxy : /login.xhtml at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
26 Jun 2012 12:48:04,078 DEBUG DefaultSavedRequest : pathInfo: both null (property equals)
26 Jun 2012 12:48:04,078 DEBUG DefaultSavedRequest : queryString: both null (property equals)
26 Jun 2012 12:48:04,078 DEBUG DefaultSavedRequest : requestURI: arg1=/mdmd/; arg2=/mdmd/login.xhtml (property not equals)
26 Jun 2012 12:48:04,093 DEBUG HttpSessionRequestCache : saved request doesn't match
26 Jun 2012 12:48:04,093 DEBUG FilterChainProxy : /login.xhtml at position 6 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
26 Jun 2012 12:48:04,093 DEBUG FilterChainProxy : /login.xhtml at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
26 Jun 2012 12:48:04,093 DEBUG AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@6faba4dc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232; Granted Authorities: ROLE_ANONYMOUS'
26 Jun 2012 12:48:04,093 DEBUG FilterChainProxy : /login.xhtml at position 8 of 10 in additional filter chain; firing Filter: 'SessionManagementFilter'
26 Jun 2012 12:48:04,093 DEBUG FilterChainProxy : /login.xhtml at position 9 of 10 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
26 Jun 2012 12:48:04,093 DEBUG FilterChainProxy : /login.xhtml at position 10 of 10 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
26 Jun 2012 12:48:04,093 DEBUG AntPathRequestMatcher : Checking match of request : '/login.xhtml'; against '/accessdenied*'
26 Jun 2012 12:48:04,093 DEBUG AntPathRequestMatcher : Checking match of request : '/login.xhtml'; against '/login*'
26 Jun 2012 12:48:04,093 DEBUG FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /login.xhtml; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
26 Jun 2012 12:48:04,093 DEBUG FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@6faba4dc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232; Granted Authorities: ROLE_ANONYMOUS
26 Jun 2012 12:48:04,093 DEBUG AffirmativeBased : Voter: org.springframework.security.access.vote.RoleVoter@88fcb2, returned: 0
26 Jun 2012 12:48:04,093 DEBUG AffirmativeBased : Voter: org.springframework.security.access.vote.AuthenticatedVoter@18620f5, returned: 1
26 Jun 2012 12:48:04,093 DEBUG FilterSecurityInterceptor : Authorization successful
26 Jun 2012 12:48:04,093 DEBUG FilterSecurityInterceptor : RunAsManager did not change Authentication object
26 Jun 2012 12:48:04,093 DEBUG FilterChainProxy : /login.xhtml reached end of additional filter chain; proceeding with original chain
26 Jun 2012 12:48:04,281 DEBUG FilterChainProxy : /j_spring_security_check?j_username=admin&j_password=admin at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
26 Jun 2012 12:48:04,281 DEBUG FilterChainProxy : /j_spring_security_check?j_username=admin&j_password=admin at position 2 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
26 Jun 2012 12:48:04,281 DEBUG FilterChainProxy : /j_spring_security_check?j_username=admin&j_password=admin at position 3 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
26 Jun 2012 12:48:04,281 DEBUG UsernamePasswordAuthenticationFilter : Request is to process authentication
26 Jun 2012 12:48:04,296 DEBUG ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
26 Jun 2012 12:48:04,296 INFO UserDetailsServiceImpl : ** trying to retrieve user
26 Jun 2012 12:48:06,203 INFO UserDetailsServiceImpl : ** user is found
26 Jun 2012 12:48:06,421 WARN LoggerListener : Authentication event AuthenticationSuccessEvent: admin; details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232
26 Jun 2012 12:48:06,421 DEBUG SessionFixationProtectionStrategy : Invalidating session with Id '7f9b291fe5d980eba4639fdcb232' and migrating attributes.
26 Jun 2012 12:48:06,468 DEBUG SessionFixationProtectionStrategy : Started new session: 7f9eb44f14616034a4b5169d6ac6
26 Jun 2012 12:48:06,468 DEBUG UsernamePasswordAuthenticationFilter : Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@be0d966d: Principal: org.mycompany.domain.security.UserDetailsImpl@1508a8b; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232; Granted Authorities: ROLE_ADMIN
26 Jun 2012 12:48:06,531 WARN LoggerListener : Authentication event InteractiveAuthenticationSuccessEvent: admin; details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232
26 Jun 2012 12:48:06,531 DEBUG SavedRequestAwareAuthenticationSuccessHandler : Redirecting to DefaultSavedRequest Url: 'http://localhost:9080/mdmd/'
26 Jun 2012 12:48:06,531 DEBUG DefaultRedirectStrategy : Redirecting to 'http://localhost:9080/mdmd/'
26 Jun 2012 12:48:06,531 DEBUG HttpSessionSecurityContextRepository : SecurityContext stored to HttpSession: 'org.springframework.security.core.context.SecurityContextImpl@be0d966d: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@be0d966d: Principal: org.mycompany.domain.security.UserDetailsImpl@1508a8b; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232; Granted Authorities: ROLE_ADMIN'
26 Jun 2012 12:48:06,562 DEBUG ExceptionTranslationFilter : Chain processed normally
26 Jun 2012 12:48:06,562 DEBUG SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
26 Jun 2012 12:48:06,593 DEBUG FilterChainProxy : /index.jsp at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
26 Jun 2012 12:48:06,609 DEBUG HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@be0d966d: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@be0d966d: Principal: org.mycompany.domain.security.UserDetailsImpl@1508a8b; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232; Granted Authorities: ROLE_ADMIN'
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 2 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 3 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 4 of 10 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : pathInfo: both null (property equals)
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : queryString: both null (property equals)
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : requestURI: arg1=/mdmd/; arg2=/mdmd/ (property equals)
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : serverPort: arg1=9080; arg2=9080 (property equals)
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : requestURL: arg1=http://localhost:9080/mdmd/; arg2=http://localhost:9080/mdmd/ (property equals)
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : scheme: arg1=http; arg2=http (property equals)
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : serverName: arg1=localhost; arg2=localhost (property equals)
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : contextPath: arg1=/mdmd; arg2=/mdmd (property equals)
26 Jun 2012 12:48:06,609 DEBUG DefaultSavedRequest : servletPath: arg1=/index.jsp; arg2=/index.jsp (property equals)
26 Jun 2012 12:48:06,609 DEBUG HttpSessionRequestCache : Removing DefaultSavedRequest from session if present
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 6 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
26 Jun 2012 12:48:06,609 DEBUG AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@be0d966d: Principal: org.mycompany.domain.security.UserDetailsImpl@1508a8b; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232; Granted Authorities: ROLE_ADMIN'
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 8 of 10 in additional filter chain; firing Filter: 'SessionManagementFilter'
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 9 of 10 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
26 Jun 2012 12:48:06,609 DEBUG FilterChainProxy : /index.jsp at position 10 of 10 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
26 Jun 2012 12:48:06,609 DEBUG AntPathRequestMatcher : Checking match of request : '/index.jsp'; against '/accessdenied*'
26 Jun 2012 12:48:06,625 DEBUG AntPathRequestMatcher : Checking match of request : '/index.jsp'; against '/login*'
26 Jun 2012 12:48:06,625 DEBUG AntPathRequestMatcher : Checking match of request : '/index.jsp'; against '/sessionexpired*'
26 Jun 2012 12:48:06,625 DEBUG AntPathRequestMatcher : Checking match of request : '/index.jsp'; against '/*'
26 Jun 2012 12:48:06,625 DEBUG FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /index.jsp; Attributes: [ROLE_AVIEWER, ROLE_BVIEWER, ROLE_ACREATOR, ROLE_BCREATOR, ROLE_AREGISTER, ROLE_BREGISTER, ROLE_ADMIN]
26 Jun 2012 12:48:06,625 DEBUG FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@be0d966d: Principal: org.mycompany.domain.security.UserDetailsImpl@1508a8b; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232; Granted Authorities: ROLE_ADMIN
26 Jun 2012 12:48:06,625 DEBUG AffirmativeBased : Voter: org.springframework.security.access.vote.RoleVoter@88fcb2, returned: 1
26 Jun 2012 12:48:06,625 DEBUG FilterSecurityInterceptor : Authorization successful
26 Jun 2012 12:48:06,625 DEBUG FilterSecurityInterceptor : RunAsManager did not change Authentication object
26 Jun 2012 12:48:06,625 DEBUG FilterChainProxy : /index.jsp reached end of additional filter chain; proceeding with original chain
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 2 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 3 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 4 of 10 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 6 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
26 Jun 2012 12:48:11,953 DEBUG AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@be0d966d: Principal: org.mycompany.domain.security.UserDetailsImpl@1508a8b; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffed504: RemoteIpAddress: 127.0.0.1; SessionId: 7f9b291fe5d980eba4639fdcb232; Granted Authorities: ROLE_ADMIN'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 8 of 10 in additional filter chain; firing Filter: 'SessionManagementFilter'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 9 of 10 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml at position 10 of 10 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
26 Jun 2012 12:48:11,953 DEBUG FilterChainProxy : /main.xhtml reached end of additional filter chain; proceeding with original chain