Spring Security sends AuthenticationEvent twice - jsf-2

I've embeded Spring Security in my existing JSF 2 application running on Glassfish 3.1.2.
To do it, I used approach using forwarding to /j_spring_security_check, described in the following article:
http://ocpsoft.org/java/acegi-spring-security-jsf-login-page/
My code is almost 1-to-1 copy of the code of the article.
Here is 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>
Here is my login 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;
}
}
And this is declaration of security context:
<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>
Then I created a listener to catch all AbstractAuthenticationEvent:
public class AuthenticationListener implements
ApplicationListener<AbstractAuthenticationEvent> {
private final static Log log = LogFactory.getLog(AuthenticationListener.class);
#Override
public void onApplicationEvent(AbstractAuthenticationEvent e) {
// some processing
}
}
The problem is: after each successefull login, the AuthenticationEvent is generated twice, not once, as it could be suggested.
Would somebody explain, what is wrong ?
Some addition: the event is generated twice, because (I don't understand why), there is automatic logout right after login and then new authentication. Here is the snippet from log:
INFO: ** trying to retrieve user
INFO: ** user is found
INFO: Hibernate: insert into audit (EVENT_TYPE, EVENT_TIMESTAMP,
USER_ID) values (?, ?, ?)
INFO: Current Session destroyed :3ee7b951888eb8920d07fefceaec by
org.apache.catalina.session.StandardSessionFacade#57ac8e Logging out
user...
INFO: Logging out
INFO: Current Session created : 3f1fd377302220f2f27313c06cdc at Mon
Jun 25 16:00:57 CEST 2012 by
org.apache.catalina.session.StandardSessionFacade#912e6a
INFO: Hibernate: insert into audit (EVENT_TYPE, EVENT_TIMESTAMP,
USER_ID) values (?, ?, ?)
Here is the the log with debugging on (sorry for the long list):
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

Related

Struts 2 - Exception starting filter struts2

I just started with this Struts 2 HelloWorld Tutorial [1] and exactly followed the steps explained in this tutorial but there is a problem with starting the filters. Here is the console output:
[1] https://www.tutorialspoint.com/struts_2/struts_examples.htm
Jun 06, 2017 4:53:35 PM org.apache.catalina.core.AprLifecycleListener init
INFORMATION: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.8.0_112\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jre1.8.0_131/bin/server;C:/Program Files/Java/jre1.8.0_131/bin;C:/Program Files/Java/jre1.8.0_131/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Enterprise Vault\EVClient\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\eclipse;;.
Jun 06, 2017 4:53:35 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNUNG: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:HelloWorldStruts2' did not find a matching property.
Jun 06, 2017 4:53:36 PM org.apache.coyote.AbstractProtocol init
INFORMATION: Initializing ProtocolHandler ["http-bio-18080"]
Jun 06, 2017 4:53:36 PM org.apache.catalina.startup.Catalina load
INFORMATION: Initialization processed in 428 ms
Jun 06, 2017 4:53:36 PM org.apache.catalina.core.StandardService startInternal
INFORMATION: Starting service Catalina
Jun 06, 2017 4:53:36 PM org.apache.catalina.core.StandardEngine startInternal
INFORMATION: Starting Servlet Engine: Apache Tomcat/7.0.52
Jun 06, 2017 4:53:39 PM org.apache.catalina.startup.TaglibUriRule body
INFORMATION: TLD skipped. URI: /struts-tags is already defined
Jun 06, 2017 4:53:39 PM org.apache.catalina.core.ApplicationContext log
INFORMATION: No Spring WebApplicationInitializer types detected on classpath
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
Jun 06, 2017 4:53:39 PM org.apache.catalina.core.StandardContext filterStart
SCHWERWIEGEND: Exception starting filter struts2
java.lang.reflect.InvocationTargetException - Class: com.opensymphony.xwork2.inject.ContainerImpl$ConstructorInjector
File: ContainerImpl.java
Method: construct
Line: 427 - com/opensymphony/xwork2/inject/ContainerImpl.java:427:-1
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:450)
at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4809)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5485)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.opensymphony.xwork2.inject.ContainerImpl$ConstructorInjector.construct(ContainerImpl.java:427)
at com.opensymphony.xwork2.inject.ContainerBuilder$5.create(ContainerBuilder.java:218)
at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:52)
at com.opensymphony.xwork2.inject.ContainerBuilder$3.create(ContainerBuilder.java:91)
at com.opensymphony.xwork2.inject.ContainerBuilder$7.call(ContainerBuilder.java:571)
at com.opensymphony.xwork2.inject.ContainerBuilder$7.call(ContainerBuilder.java:568)
at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:560)
at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:568)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.createBootstrapContainer(DefaultConfiguration.java:278)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:160)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:390)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:437)
... 14 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.opensymphony.xwork2.inject.ContainerImpl$ConstructorInjector.construct(ContainerImpl.java:410)
... 26 more
Caused by: java.lang.NoSuchMethodError: org.apache.commons.lang3.text.StrSubstitutor.setValueDelimiter(Ljava/lang/String;)Lorg/apache/commons/lang3/text/StrSubstitutor;
at com.opensymphony.xwork2.config.providers.EnvsValueSubstitutor.<init>(EnvsValueSubstitutor.java:32)
... 31 more
Jun 06, 2017 4:53:39 PM org.apache.catalina.core.StandardContext startInternal
SCHWERWIEGEND: Error filterStart
Jun 06, 2017 4:53:39 PM org.apache.catalina.core.StandardContext startInternal
SCHWERWIEGEND: Context [/HelloWorldStruts2] startup failed due to previous errors
Jun 06, 2017 4:53:39 PM org.apache.coyote.AbstractProtocol start
INFORMATION: Starting ProtocolHandler ["http-bio-18080"]
Jun 06, 2017 4:53:39 PM org.apache.catalina.startup.Catalina start
INFORMATION: Server startup in 3183 ms
I think there is no need to paste my code here as it is exactly the code as stated in the tutorial link above. Except I replaced
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
with
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
as proposed in this answer, which did not resolve the issue: java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.FilterDispatcher
I am using struts 2.3.4, but tried it also with struts 2.2 and 2.5 - neither works.
I found the flaw: I have left the struts 2.5 jars in the "Deployment Assembly", since some other post proposed this when it showed some other exception. I removed them and booom.. now it works. Thanks, Aleksandr!

What is causing CouchDB changes_reader_died

I'm trying to configure a filtered replication bidirectionnal between two databases. Each database has a document into the _replicator database that set the replication towards the database. Each database have the same _design document with the filter and they got the same filter parameters.
Although I have been looking over the web, I didn't find the cause of my problem. I hope you guys can help me.
Log output :
[Fri, 26 Aug 2016 19:36:31 GMT] [error] [<0.22247.80>] ** Generic server <0.22247.80> terminating
** Last message in was {'EXIT',<0.22219.80>,changes_reader_died}
** When Server state == {state,<0.22219.80>,<0.22249.80>,20,
{httpdb,
"REPLACEDFORSECURITYREASONS",
nil,
[{"Accept","application/json"},
{"User-Agent","CouchDB/1.6.1"}],
30000,
[{socket_options,
[{keepalive,true},{nodelay,false}]}],
10,250,<0.22065.80>,20},
{httpdb,
"http:REPLACEDFORSECURITYREASONS",
nil,
[{"Accept","application/json"},
{"User-Agent","CouchDB/1.6.1"}],
30000,
[{socket_options,
[{keepalive,true},{nodelay,false}]}],
10,250,<0.22223.80>,20},
[],nil,nil,nil,
{rep_stats,0,0,0,0,0},
nil,nil,
{batch,[],0}}
** Reason for termination ==
** changes_reader_died
[Fri, 26 Aug 2016 19:36:31 GMT] [error] [<0.22243.80>] {error_report,<0.34.0>,
{<0.22243.80>,crash_report,
[[{initial_call,
{couch_replicator_worker,init,['Argument__1']}},
{pid,<0.22243.80>},
{registered_name,[]},
{error_info,
{exit,changes_reader_died,
[{gen_server,terminate,6,
[{file,"gen_server.erl"},{line,744}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,239}]}]}},
{ancestors,
[<0.22219.80>,couch_replicator_job_sup,
couch_primary_services,couch_server_sup,
<0.35.0>]},
{messages,[]},
{links,[<0.22244.80>]},
{dictionary,
[{last_stats_report,{1472,240191,741233}}]},
{trap_exit,true},
{status,running},
{heap_size,233},
{stack_size,27},
{reductions,158}],
[{neighbour,
[{pid,<0.22244.80>},
{registered_name,[]},
{initial_call,{erlang,apply,2}},
{current_function,
{couch_replicator_worker,queue_fetch_loop,5}},
{ancestors,[]},
{messages,[]},
{links,[<0.22243.80>]},
{dictionary,[]},
{trap_exit,false},
{status,waiting},
{heap_size,610},
{stack_size,10},
{reductions,4}]}]]}}
[Fri, 26 Aug 2016 19:36:31 GMT] [error] [<0.22247.80>] {error_report,<0.34.0>,
{<0.22247.80>,crash_report,
[[{initial_call,
{couch_replicator_worker,init,['Argument__1']}},
{pid,<0.22247.80>},
{registered_name,[]},
{error_info,
{exit,changes_reader_died,
[{gen_server,terminate,6,
[{file,"gen_server.erl"},{line,744}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,239}]}]}},
{ancestors,
[<0.22219.80>,couch_replicator_job_sup,
couch_primary_services,couch_server_sup,
<0.35.0>]},
{messages,[]},
{links,[<0.22249.80>]},
{dictionary,
[{last_stats_report,{1472,240191,741235}}]},
{trap_exit,true},
{status,running},
{heap_size,233},
{stack_size,27},
{reductions,162}],
[{neighbour,
[{pid,<0.22249.80>},
{registered_name,[]},
{initial_call,{erlang,apply,2}},
{current_function,
{couch_replicator_worker,queue_fetch_loop,5}},
{ancestors,[]},
{messages,[]},
{links,[<0.22247.80>]},
{dictionary,[]},
{trap_exit,false},
{status,waiting},
{heap_size,610},
{stack_size,10},
{reductions,4}]}]]}}
Best regards.
While doing a deep analyze of the log, I found that there was a timeout error before the changes_read_died.
The error was pretty explicit :
Fri, 26 Aug 2016 20:01:06 GMT] [info] [<0.2238.0>] Replication `"c48f6c26aa44689de43ee5ffaa18c7ad+continuous"` is using:
4 worker processes
a worker batch size of 500
20 HTTP connections
a connection timeout of 30000 milliseconds
10 retries per request
socket options are: [{keepalive,true},{nodelay,false}]
[Fri, 26 Aug 2016 20:01:06 GMT] [info] [<0.2204.0>] XXX.XXX.X.XX- - GET /akpaper/_changes?filter=global%2FbySite&IDSITE=MILLS2&feed=continuous&style=all_docs&since=0&heartbeat=10000 200
[Fri, 26 Aug 2016 20:01:06 GMT] [error] [<0.2204.0>] OS Process Error <0.204.0> :: {<<"compilation_error">>,
<<"Expression does not eval to a function. (ffunction(doc, req) { return doc._deleted || doc.IDSITE == req.query.IDSITE;})">>}
[Fri, 26 Aug 2016 20:01:06 GMT] [info] [<0.2204.0>] XXX.XXX.X.XX - - GET /akpaper/_changes?filter=global%2FbySite&IDSITE=MILLS2&feed=continuous&style=all_docs&since=0&heartbeat=10000 500
[Fri, 26 Aug 2016 20:01:06 GMT] [error] [<0.2204.0>] httpd 500 error response:
{"error":"compilation_error","reason":"Expression does not eval to a function. (ffunction(doc, req) { return doc._deleted || doc.IDSITE == req.query.IDSITE;})"}
All I did to correct the problem was just to correct my filter function wich could not be eval.
for me, the "changes" parser was failing, hence the message: changes_reader_dies
Looking at the replication doc, it seems that it setting the Content-Type to JSON and somehow failing to parse changes. Removing that line fixed it for me:
Bad:
{
"_id": "repl/...",
"_rev": "8-76d8a4dd87f5911b5dccb2527b2304",
"source": {
"url": "
"headers": {
"Authorization": "Basic FaBNwB...",
"Content-Type": "application/json"
}
"target": ...
...
}
Good:
{
"_id": "repl/...",
"_rev": "8-76d8a4dd87f5911b5dccb2527b2304",
"source": {
"url": "
"headers": {
"Authorization": "Basic FaBNwB..."
}
"target": ...
...
}

Spring zuul proxy not accepting bearer token

I have a zuul proxy (http://localhost:8765) serving an angular web app (http://localhost:8080/app). Behind the zuul proxy there is also an oauth2 server (http://localhost:8899).
The web resources are proxied under http://localhost:8765/web and the resources are proxied under http://localhost:8765/api.
The Zuul proxy serves the static web resources without authentication. So the first authentication is done through a JSON call (GET /api/user) which of course fails with 401.
Now I forward the page to "http://localhost:8899/uaa/oauth/authorize?response_type=token&client_id=web&redirect_uri=http://localhost:8765/web/index.html" to make an implicit grant oauth 2 flow. I can authorize now the web application and get forwarded back to my web app. The token is part of the url and I can parse it.
IMHO the only thing I now have to do is to add this token as Authorization header (e.g. Authorization:Bearer 2829d5e2-4fbe-4f91-b74d-c99b2fe894a7). But the zuul proxy won't accept this request as authorized.
I am using spring boot 1.3.2 and spring cloud Brixton.M4.
The Zuul Server Application can be found here and the security config here.
Here are my request headers:
Accept:application/json
Accept-Encoding:gzip, deflate, sdch
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Authorization:Bearer 2829d5e2-4fbe-4f91-b74d-c99b2fe894a7
Connection:keep-alive
Cookie:XSRF-TOKEN=a6ddea36-e3b7-4f22-b80c-b4c8b6fd7760; JSESSIONID=DAE4649D11386D586A0CF739148E505A; XSRF-TOKEN=3a7a57ad-68f6-4cc6-923b-4e8fe340fe1e
Host:localhost:8765
Referer:http://localhost:8765/web/index.html
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/48.0.2564.82 Chrome/48.0.2564.82 Safari/537.36
X-Auth-Token:2829d5e2-4fbe-4f91-b74d-c99b2fe894a7
X-Requested-With:XMLHttpRequest
X-XSRF-TOKEN:a6ddea36-e3b7-4f22-b80c-b4c8b6fd7760
My Zuul configuration is:
server:
context-path: /
security:
user:
password: none
oauth2:
sso:
loginPath: /login
client:
accessTokenUri: ${authserver.protocol}://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/oauth/token
userAuthorizationUri: ${authserver.protocol}://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/oauth/authorize
clientId: web
resource:
userInfoUri: ${authserver.protocol}://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/user
preferTokenInfo: false
zuul:
routes:
web-portal:
path: /web/**
url: http://localhost:8080/app
user:
path: /api/user/**
url: ${authserver.protocol}://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/user
authentication-service:
path: /uaa/**
stripPrefix: false
---
spring:
profiles: local
logging:
level:
org:
springframework:
security: DEBUG
authserver:
protocol: http
hostname: localhost
port: 8899
contextPath: uaa
The zuul server log is:
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/api/user' matched by universal pattern '/**'
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#5571734d. A new one will be created.
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#42c144ce
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using org.springframework.security.web.csrf.CsrfFilter$DefaultRequiresCsrfMatcher#4ad95822
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.util.matcher.AndRequestMatcher : Did not match
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 5 of 13 in additional filter chain; firing Filter: ''
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 6 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /api/user' doesn't match 'POST /logout
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 7 of 13 in additional filter chain; firing Filter: 'OAuth2ClientAuthenticationProcessingFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/login'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: DAE4649D11386D586A0CF739148E505A; Granted Authorities: ROLE_ANONYMOUS'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/index.html'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/home.html'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/web/**'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/uaa/oauth/**'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/user; Attributes: [authenticated]
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: DAE4649D11386D586A0CF739148E505A; Granted Authorities: ROLE_ANONYMOUS
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#77816ac4, returned: -1
2016-02-11 17:11:02.960 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
How can I force the authentication on the zuul proxy against the access token?
--- Edit:
If I enable the authentication for the static web resource by removing the http security exception for it, I get forwarded to the authorization page. When the request gets forwarded back everything works. The zuul proxy forwards to the oauth server with its /login URL as return address. This seems to be the correct way. I suppose it saves some information in its session and after that forwards back to the initial requesting page (in my case /web/index.html).
When I now restart the authentication service (like simulating expired token) the resources from the web application are served, but the request to /api/user (proxied to the authentication server) is denied.
Same happens when I come from a manually constructed authorize URL like
http://localhost:8899/uaa/oauth/authorize?response_type=token&client_id=web&redirect_uri=http://localhost:8765/web/index.html. First I get to the authorization page of the oauth server. This is correct. On click on authorize the request gets forwarded to the web app (/web/index.html). All static content is served without problem, but access to /api/user is again denied. This time with an error logged in the oauth server: Invalid access token: dff5121b-06e4-4bd7-b48e-08ad82d71404
zuul api not forward header by default so disable it we need to add it
zuul:
sensitive-headers: Cookie,Set-Cookie
You should move to Spring Boot 1.3x.
Then, you can annotate you Zulu Proxy with #EnableOAuath2Sso annotation.
In your application.yml for Zuul, specify the following (for Spring Boot 1.3x):
security:
user:
password: none
oauth2:
client:
accessTokenUri: ${oauthserver}:${oauthport}/oauth/token
userAuthorizationUri: ${oauthserver}:${oauthport}/oauth/authorize
clientId: acme
clientSecret: acme secret
Thanks to #Dave I can answer my own question:
To have the Zuul proxy acception the OAuth Bearer Token header, you have to configure it as a resource server instead a SSO server.
Remove the #EnableOAuth2Sso annotation and use the #EnableResourceServer annotation instead. First I had still my WebSecurityConfigurerAdapter in place. So this was fixed by changing
#Configuration
#EnableOAuth2Sso
public class OAuthConfiguration extends WebSecurityConfigurerAdapter {
to
#Configuration
#EnableResourceServer
public class OAuthConfiguration extends ResourceServerConfigurerAdapter {
If one should use the implicit authentication is another topic (see comment from Dave).
By default the Zuul Proxy will remove certain headers because it deems them to sensitive and no other server should receive them. It has a list of cookies and headers it needs to remove. This needs to be overridden. The way to do this for a particular route is:
zuul:
routes:
profile-service-chaining:
sensitiveHeaders:
stripPrefix: false
serviceId: profile-service-chaining
path: /services/profiles
The line 'sensitiveHeaders:' will empty the cookies headers. This will cause all headers to be past to the server the request will be sent to. This will allow the Authorization header to sent to the target server. As the Zuul documentation says make sure to always remove sensitive headers. To do this the add:
sensitiveHeaders: Cookie
The above will remove the Cookie header before it is passed to the next server as specified by the Zuul route.

Authenticated principal is lost after Zuul redirect to a microservice registered in Eureka

I have this set-up in order to work with the Netflix stack:
An Eureka Server
A module, exposed to the outside world with a Zuul proxy (registered to Eureka)
A number of back-end microservices (registered to Eureka)
My problem is, when I invoke an URL in the proxy (to be redirected to the microservice) for the second/third time, the autenthicated principal is lost.
These are the log entries:
09:14:31.300 INFO 8720 --- [nio-8080-exec-7] o.s.b.a.audit.listener.AuditListener : AuditEvent [timestamp=Mon Sep 14 09:14:31 CEST 2015, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={message=Access is denied, type=org.springframework.security.access.AccessDeniedException}]
09:14:33.387 INFO 8720 --- [io-8080-exec-10] o.s.b.a.audit.listener.AuditListener : AuditEvent [timestamp=Mon Sep 14 09:14:33 CEST 2015, principal=eadmin, type=AUTHENTICATION_SUCCESS, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails#fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: DE9DEDCB6A809133C54ABC3403A46B38}]
09:14:33.387 INFO 8720 --- [io-8080-exec-10] o.s.b.a.audit.listener.AuditListener : AuditEvent [timestamp=Mon Sep 14 09:14:33 CEST 2015, principal=eadmin, type=AUTHENTICATION_SUCCESS, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails#fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: DE9DEDCB6A809133C54ABC3403A46B38}]
09:14:35.407 INFO 8720 --- [nio-8080-exec-1] o.s.c.n.zuul.filters.ProxyRouteLocator : Finding route for path: /userregistryservice/user-registry/getAllRoles
09:23:40.119 INFO 8720 --- [nio-8080-exec-2] o.s.c.n.zuul.filters.ProxyRouteLocator : Finding route for path: /userregistryservice/user-registry/getAllRoles
09:24:06.689 INFO 8720 --- [nio-8080-exec-3] o.s.b.a.audit.listener.AuditListener : AuditEvent [timestamp=Mon Sep 14 09:24:06 CEST 2015, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={message=Access is denied, type=org.springframework.security.access.AccessDeniedException}]
I have implemented a Zuul proxy, where I pass the principal to the request headers to be redirected but when the request is sent for the second time, this filter is not invoked (Spring Security captures the request as it were an anonymous request).
Any ideas on what is going on here?
Thanks
EDIT: Investigating with Fiddler, I have found out that the request being reject is answered with a HTTP 302 code, after two successful requests:
EDIT #2: This is my SpringĀ“s boot security configuration
#Autowired
private RequestHeaderAuthenticationFilter siteminderFilter;
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.anonymous().and().addFilter(siteminderFilter)
.authorizeRequests()
.antMatchers("/authfallback/**", "/access_requests.css")
.permitAll()
.antMatchers("/auth/**")
.fullyAuthenticated()
.antMatchers("/**/metrics")
.hasAnyRole("SYSTEM", "ADMIN")
.antMatchers("/logs")
.hasAnyRole("SYSTEM", "ADMIN")
.antMatchers("/user-registry/**")
.hasAnyRole("SYSTEM", "ADMIN")
.antMatchers("/AdminTools/**", "/api-docs")
.hasAnyRole("ADMIN")
.antMatchers("/sdoc.jsp", "o2c.html")
.denyAll()
.antMatchers("/**")
.hasAnyRole("SYSTEM", "ENGINEERING", "CUSTOMER", "EXECUTIVE", "ADMIN").and().formLogin()
.loginPage("/authfallback/login").defaultSuccessUrl("/index.html", false)
.permitAll().and().logout()
.invalidateHttpSession(true).logoutUrl("/logout").logoutSuccessHandler(wamLogoutHandler).and()
.exceptionHandling().accessDeniedPage("/auth/authorizationrequest").and().csrf().disable();
// #formatter:on
}
Add the following property to zuul:
zuul.sensitiveHeaders:

Spring Security: HttpSession lost after authentication

I'm trying to use Spring Security 3.1, but I'm losing my HttpSession after the authentication. I'm getting: "No HttpSession currently exists" after having a correct HttpSession created.
I'm getting the following log:
08 janv. 2014 19:53:59 DEBUG HttpSessionSecurityContextRepository - SecurityContext stored to HttpSession: 'org.springframework.security.core.context.SecurityContextImpl#bce8a84f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#bce8a84f: Principal: org.springframework.security.core.userdetails.User#3b40b2f: Username: ADMIN; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#ffff6a82: RemoteIpAddress: 127.0.0.1; SessionId: qx1qn1vbjxx71xedid64oi977; Granted Authorities: ROLE_ADMIN'
08 janv. 2014 19:53:59 DEBUG DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'spring': assuming HandlerAdapter completed request handling
08 janv. 2014 19:53:59 DEBUG DispatcherServlet - Successfully completed request
08 janv. 2014 19:53:59 DEBUG ExceptionTranslationFilter - Chain processed normally
08 janv. 2014 19:53:59 DEBUG SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
08 janv. 2014 19:54:00 DEBUG FilterChainProxy - /index at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
08 janv. 2014 19:54:00 DEBUG HttpSessionSecurityContextRepository - No HttpSession currently exists
08 janv. 2014 19:54:00 DEBUG HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.
08 janv. 2014 19:54:00 DEBUG FilterChainProxy - /index at position 2 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
08 janv. 2014 19:54:00 DEBUG FilterChainProxy - /index at position 3 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
08 janv. 2014 19:54:00 DEBUG FilterChainProxy - /index at position 4 of 10 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
08 janv. 2014 19:54:00 DEBUG FilterChainProxy - /index at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
08 janv. 2014 19:54:00 DEBUG FilterChainProxy - /index at position 6 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
08 janv. 2014 19:54:00 DEBUG FilterChainProxy - /index at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
08 janv. 2014 19:54:00 DEBUG AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
What could be the problem?
UPDATE:
I found my problem... I had a file that I should have cared about before:
jetty-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
"http://jetty.mortbay.org/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="sessionHandler">
<Get name="sessionManager">
<Set name="usingCookies" type="boolean">false</Set>
</Get>
</Get>
</Configure>
I was disabling the cookies myself...
I found my problem... I had a file that I should have cared about before:
jetty-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
"http://jetty.mortbay.org/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="sessionHandler">
<Get name="sessionManager">
<Set name="usingCookies" type="boolean">false</Set>
</Get>
</Get>
</Configure>
I was disabling the cookies myself... I've deleted this file and it's now working.

Resources