Different authentication on localhost vs public IP address - spring

I have an issue that seems something like this one but I'm not using AJAX for logging in/authentication.
When I access my local Tomcat 7 instance, I can correctly evaluate this block to true when the user is not logged in:
<security:authorize access="!isFullyAuthenticated()">
<div class="col-xs-12 col-md-2 login_button">
<button class="btn btn-success" style="line-height: 1.42857"><spring:message code="label.logIn"/> <i class="fa fa-sign-in"></i></button>
</div>
</security:authorize>
However, it evaluates to false when I deploy it to our public QA and public production instances, hiding the button. I also tried changing the access to !isAuthenticated() but the behavior didn't change.
I'm using Spring 4.1.0.RELEASE and Spring Security 3.2.4.RELEASE. I am not completely sure but it may not have had this behavior in a previous version of Spring.
What could cause a difference in the code block evaluation between servers?
UPDATE:
Spring security config:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<beans:bean id="authSuccessHandler" class="com.companyname.web.RoleBasedAuthenticationSuccessHandler" />
<http auto-config="true" use-expressions="true">
<form-login login-page="/login"
authentication-success-handler-ref="authSuccessHandler"
authentication-failure-url="/login?login_error=true"
login-processing-url="/j_spring_security_check" />
<intercept-url pattern="/sample/**" access="hasAnyRole('ROLE_SAMPLE','ROLE_CO_SAMPLE')" />
<intercept-url pattern="/other/**" access="hasAnyRole('ROLE_OTHER', 'ROLE_CO_OTHER','ROLE_SAMPLE','ROLE_CO_SAMPLE')" />
<logout logout-success-url="/index" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="myUserDetailsService"
class="com.companyname.service.UserDetailsServiceImpl" />
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<global-method-security secured-annotations="enabled" pre-post-annotations="enabled">
<expression-handler ref="expressionHandler"/>
</global-method-security>
<beans:bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<beans:property name="permissionEvaluator">
<beans:bean id="permissionEvaluator" class="com.companyname.web.security.MethodsPermissionEvaluator"/>
</beans:property>
</beans:bean>
</beans:beans>
EDIT:
Also tried Spring Security 3.2.8.RELEASE, but no luck.

This issue was solved by a fellow developer by updating the web.xml to contain the Spring Security Filter Chain higher up in the file:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<servlet-name>Spring Security Filter Chain</servlet-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
We also had to make sure that the updated file was deployed to the correct environment. The discrepancy in environments is attributed to different web.xml files for each environment.

Related

Spring CSRF multiparfilter breaks

I have a multipart form with a file upload which gets posted as seen below in Chrome developer tools -
------WebKitFormBoundaryUkhJ5180JIBYXzLm
Content-Disposition: form-data; name="_csrf"
8d7f28ad-f436-473c-964e-fe41c42c80e4
------WebKitFormBoundaryUkhJ5180JIBYXzLm
Content-Disposition: form-data; name="_csrf"
8d7f28ad-f436-473c-964e-fe41c42c80e4
------WebKitFormBoundaryUkhJ5180JIBYXzLm--
The data seems to have a proper multipart boundary and the _csrf token included. My Spring application is configured as below for CSRF and multipartfilter -
Beans -
<bean id="tokenRepo"
class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">
</bean>
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage"
value="/WEB-INF/files/AccessDenied.html" />
</bean>
<bean id="csrfFilter" class="org.springframework.security.web.csrf.CsrfFilter">
<constructor-arg ref="tokenRepo" />
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map>
<sec:filter-chain pattern="/**" filters="
csrfFilter" />
</sec:filter-chain-map>
</bean>
<bean id="multipartFilter" class="org.springframework.web.multipart.support.MultipartFilter">
</bean>
web.xml -
<filter>
<filter-name>multipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter>
<filter-name>filterChainProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>filterChainProxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
security.xml -
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<http />
</b:beans>
I am using Spring Framework version 4.1.6.RELEASE and Spring Security version 4.0.2.RELEASE and Tomcat 7.
With this setup, the request does not pass multipartfilter and/or CSRF filter - I do not see it entering the filter placed after these 2 in web.xml.
If I change my server's context.xml opening context tag to include allowCasualMultipartParsing="true", the request passes into the next filter after multipartfilter and CSRF filter but when it reaches my controller, Apache Commons FileUpload finds it empty. I have tried wrapping the request in HttpServletRequestWrapper in order to typecast it in different ways but I could not salvage the request.

Spring Security role define

when i am trying to authenticate by giving username name as "sumit1" and password as "123" it is redirecting me to the login error page, though i have defined the same role as i have defined for username "sumit" .
this is my spring-security xml file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" access-denied-page="/sumit/auth/denied.jsp" >
<security:intercept-url pattern="/admin**" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/user**" access="ROLE_USER"/>
<security:form-login authentication-failure-url="/sumit/auth/invalid.jsp"/>
<!-- <security:form-login login-page="/sumit/auth/login.jsp"/> -->
<security:logout logout-success-url="/index.jsp"/>
</security:http>
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
<security:authentication-provider>
<security:user-service><security:user name="sumit" password="123" authorities="ROLE_ADMIN"/></security:user-service>
<security:user-service><security:user name="sumit1" password="123" authorities="ROLE_ADMIN"/></security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
<!-- An in-memory list of users. No need to access an external database layer.
See Spring Security 3.1 Reference 5.2.1 In-Memory Authentication -->
<!-- john's password is admin, while jane;s password is user -->
</beans>
As Pavel mentioned in his comment, you've two <security:user-service> tags. You only need one and can define multiple users under the same.
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="sumit" password="123" authorities="ROLE_ADMIN"/>
<security:user name="sumit1" password="123" authorities="ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>

Vaadin 7.1 + Spring-Security Integration running in Tomcat Server

Im new on vaadin and spring security, I want to know if anyone had a complete project example of the vaadin 7.1 + spring-security integration running in a tomcat server (not in jetty).
Vaadin 7 easy integrate with Spring Security. You should configure only 2 files. First - web.xml and second one spring-security.xml (user credentials and security settings). This is small example how to use base form for authentification.
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"
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>Vaadin7SpringSecurity</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/spring-security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- filter declaration for Spring Security -->
<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>
</filter-mapping>
</web-app>
spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http auto-config='true'>
<intercept-url pattern="/*" access="ROLE_USER" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user" password="password" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
For more details, how to extend spring-security.xml configuration you can use Spring resources.
You should have a look on this GitHub project. This is a Vaadin 7.1 + Spring 3.1.2.RELEASE + Spring-Vaadin integration 2.0.1 project. There is also a Jetty plugin inside, but you can run/deploy it also in tomcat without problems.
Here is a little project that integrates Vaadin and Spring Security. It's done in Scala, but obviously works in Java as well. Code is here.
For referring the above example by using the latest spring-security, I encountered the following errors and provide my soultions:
Error1
Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or spring-security-3.1.xsd schema or spring-security-3.2.xsd schema with Spring Security 4.0. Please update your schema declarations to the 4.0 schema.
You should check your spring-* version and update the header tag of spring-security.xml.
For example: I use spring-beans-4.1.6.RELEASE and
spring-security-4.0.2.RELEASE. So I update it as:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
Error2
HTTP Status 500 - Failed to evaluate expression 'ROLE_USER'
...
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'ROLE_USER' cannot be found on object of type 'org.springframework.security.web.access.expression.WebSecurityExpressionRoot' - maybe not public?
...
According to hints of this resource, you should revise intercept-url tag as following:
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
Error3
HTTP Status 403 - Expected CSRF token not found. Has your session expired?
That's because spring-security enables CSRF protection by default which conflicts with Vaadin. You should add a new tag inside http :
<csrf disabled="true" />
Here's my complete spring-security.xml for reference:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<http auto-config='true'>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<csrf disabled="true" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="yourUsername" password="yourPassoword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>

Need help creating "successful authentication" page for spring security cas client

I am using Spring MVC to write a client application that will authenticate against a Spring Security CAS server.
The problem that I am running into is, after a user authenticates successfully, the browser shows a 404 error. I am not sure how to set up a "success" page in my application. Or do I need to define a callback url somewhere in the CAS server properties? Here is my code so far:
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/applicationContext-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
applicationContext-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- Enable security, let the casAuthenticationEntryPoint handle all intercepted
urls. The CAS_FILTER needs to be in the right position within the filter
chain. -->
<security:http entry-point-ref="casAuthenticationEntryPoint"
auto-config="true">
<security:intercept-url pattern="/**" access="ROLE_USER"></security:intercept-url>
<security:custom-filter position="CAS_FILTER"
ref="casAuthenticationFilter"></security:custom-filter>
</security:http>
<!-- Required for the casProcessingFilter, so define it explicitly set and
specify an Id Even though the authenticationManager is created by default
when namespace based config is used. -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="casAuthenticationProvider"></security:authentication-provider>
</security:authentication-manager>
<!-- This section is used to configure CAS. The service is the actual redirect
that will be triggered after the CAS login sequence. -->
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service"
value="https://localhost:8443/cas/j_spring_cas_security_check"></property>
<property name="sendRenew" value="false"></property>
</bean>
<!-- The CAS filter handles the redirect from the CAS server and starts
the ticket validation. -->
<bean id="casAuthenticationFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"></property>
</bean>
<!-- The entryPoint intercepts all the CAS authentication requests. It redirects
to the CAS loginUrl for the CAS login page. -->
<bean id="casAuthenticationEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://localhost:8443/cas/login"></property>
<property name="serviceProperties" ref="serviceProperties"></property>
</bean>
<!-- Handles the CAS ticket processing. -->
<bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="userDetailsService" ref="userService"></property>
<property name="serviceProperties" ref="serviceProperties"></property>
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://localhost:8443/cas">
</constructor-arg>
</bean>
</property>
<property name="key" value="cas"></property>
</bean>
<!-- The users available for this application. -->
<security:user-service id="userService">
<security:user name="user" password="user" authorities="ROLE_USER"></security:user>
</security:user-service>
I would appreciate any help!
The above code was used from the following tutorial: http://www.oudmaijer.com/2009/12/28/spring-3-spring-security-3-cas-3-3-4-integration/
Update: Here is the network flow (taken from Firebug):
User clicks on https://localhost:8443/SpringMVC_CAS/secure/index.jsp
Browser performs a "302 Moved Temporarily" from /myapp/secure/index.jsp
CAS prompts log-in https://localhost:8443/cas/login?service=https%3A%2F%2Flocalhost%3A8443%2Fcas%2Fj_spring_cas_security_check
https://localhost:8443/cas/j_spring_cas_security_check?ticket=ST-17-RHf3OTJXAWePgzVGP2nc-cas
Browser shows https://localhost:8443/cas/login?ticket=ST-17-RHf3OTJXAWePgzVGP2nc-cas
You can do that by adding an AuthenticationSuccessHandler like this:
<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/casfailed.jsp"/>
</bean>
</property>
<property name="authenticationSuccessHandler">
<bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/"/>
</bean>
</property>
</bean>
If you set alwaysUseDefaultTargetUrl property to true also, then the defaultTargetUrl will be used for the destination otherwise a redirect to the the original destination before the authentication process commenced will tke place.
See also:
SavedRequestAwareAuthenticationSuccessHandler
SimpleUrlAuthenticationSuccessHandler

Spring "alias is required"

I'm new in Spring and I'm trying to create a application using Spring Blazeds Integration (Flex + Blazeds + Spring + Java) and when I run the application I got this error:
02:51:21,852 INFO [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/security-config.xml]
02:51:23,937 ERROR [ContextLoader] Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: alias is required.
Offending resource: ServletContext resource [/WEB-INF/spring/security-config.xml]
The security-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:security="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:http>
<security:anonymous enabled="false" />
<security:form-login default-target-url="/myContext/Index.html"
login-page="/myContext/Login.html" />
<security:remember-me key="myAppKey" services-ref="rememberMeServices" />
</security:http>
<beans:bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<beans:property name="key" value="myAppKey" />
<beans:property name="alwaysRemember" value="true" />
</beans:bean>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="john" password="john" authorities="ROLE_USER" />
<security:user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
<security:user name="guest" password="guest" authorities="ROLE_GUEST" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans:beans>
I'm using spring-flex 1.5.0, spring-security 2.0.6 and Spring 3.0.
Any ideas what is the problem?
Thanks in advance,
Andre
I'm not very sure, but try to put an alias in security:authentication-manager:
<security:authentication-manager alias="authenticationManager">
Why don't you use Spring security 3?
As listed in the reference manual, Spring Flex 1.5.0 will not work with Spring Security 2. You must use Spring Security 3.
Other than this, jbbarquero is correct, assuming this is actually your problem.

Resources