JSF and Spring securtiy Integration [duplicate] - spring

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Spring Security Authentication is not working as expected in my configuration
I tried integrating JSF and spring security i spent almost a day but there is no result
Developed an application using JSF,Spring MVC and Primfaces. I am almost done with my requirements, at the end i planned to integrate the spring security but i could n't and i did enough search on net. I feel it may be bug in related framework.
If anyone of you came across the same please post the solution. I post my approach over here
Step 1:
Created Login.jsp(to have customized login page)
Step 2:
Added below code in my web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
Step 3:
Created Springsecurity.xml
<sec:global-method-security
secured-annotations="enabled" />
<sec:http auto-config="true" use-expressions="true"
once-per-request="false">
<sec:intercept-url pattern="pages/secured/**"
access="ROLE_USER" />
<sec:form-login login-page="/login.jsp"
default-target-url="/pages/secured/products.xhtml"
authentication-failure-url="/login.html?login_error=1" />
<sec:logout logout-url="/logout" logout-success-url="/login.jsp" />
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider>
<sec:user-service>
<sec:user name="vijay" authorities="ROLE_USER" password="vijay"/>
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
Executed the application and got the login.jsp as first page since i defind in web.xml. On login authentication its forwarding to the Products.xhtml but i could even access the rest of pages which all are comes under the secured folder with out logging in.
Please suggest a better approach or other alternatives.

For your access attribute have your tried. Your first slash was missing in the pattern.
<sec:intercept-url pattern="/pages/secured/**"
access="hasRole('ROLE_USER')" />

Related

Spring Security Context is null when accessing Tomcat application without trailing slash

I have a Spring based web application deployed on Tomcat 7. What I do to run it is copy the application.war archive into the webapps directory and start the server, so my application root is available under https://localhost:8443/application/.
Then I wanted to add Spring security (3.2.4) to it. My intention is to secure the entire application, not only parts of it. The Spring security configuration I have:
<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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<http auto-config="true">
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="admin" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
And in web.xml:
<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>
It's a basic configuration which can be found in the official docs and many tutorials. Everything works fine, when I'm not authenticated Spring redirects me to it's default login page. I can then log in and can access the application until the session expires or I navigate to the logout url.
The problem begins to show up when I access the application root without the trailing slash: https://localhost:8443/application.
Spring fails to find the security context:
2016-07-19 17:48:36,650 DEBUG: security.web.FilterChainProxy - / at position 1 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-07-19 17:48:36,650 DEBUG: web.context.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-07-19 17:48:36,650 DEBUG: web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#53b1e801. A new one will be created.
I then get redirected to the login page, but after I log in I get redirected to the original URL without the slash, Spring fails again and I see the login form again.
Does anybody know why is this happening? My configuration is minimal, uses out of the box defaults. The use case is also very simple and it feels weird that this is not working as expected. I feel I'm missing something fundamental, either with Spring or Tomcat.
Any help will be appreciated, thanks.
The problem was with the JSESSIONID cookie path -- Tomcat set it automatically to /application/, so any requests accessing the application root without a trailing slash were treated as new users which required authentication. Setting the cookie path to /application solved the problem for me.
just try this
<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>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<http auto-config="true">
<!-- my be this can`t match -->
<intercept-url pattern="/**" access="ROLE_USER" />
<!-- add this for try -->
<intercept-url pattern="/" access="ROLE_USER" />
</http>

Is it the true way to implement spring security & CXF webservice

i create a webservice as below:
web.xml
<display-name>MyService</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/beans.xml,/WEB-INF/spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!-- Spring Security Filter -->
<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>
beans.xml
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<context:component-scan base-package="com.*" />
<jaxrs:server id="employeeService" address="/employeeservices">
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</jaxrs:providers>
<jaxrs:serviceBeans>
<ref bean="empService" />
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="xml" value="application/xml" />
<entry key="json" value="application/json" />
</jaxrs:extensionMappings>
</jaxrs:server>
<bean id="empService" class="com.service.impl.EmployeeServiceImpl"/>
<bean id="employeeDao" class="com.dao.EmployeeDao"/>
spring-security.xml
<http auto-config="true" use-expressions="true" create-session="stateless" >
<csrf disabled="true"/>
<http-basic entry-point-ref="restAuthenticationEntryPoint"></http-basic>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
</http>
<beans:bean id="userAuthorService" class="com.auth.UserAuthorService"/>
<beans:bean id="restAuthenticationEntryPoint" class="com.auth.UserBasicAuthenticationEntryPoint">
<beans:property name="realmName" value="Name Of Your Realm"/>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userAuthorService">
<password-encoder ref="bcryptPasswordEncoder"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="bcryptPasswordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="5" />
</beans:bean>
<beans:bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener"/>
By this configuration, is it flow of request process? :
request -> Spring security(check authentication) -> cxf -> response.
Are there any issues in this configuration when I deploy it in the real sever? what is the standard configuration when using cxf and spring ?
when i call right uri:http://localhost:8089/MyService/rest/employeeservices/getemployeedetals?employeeId=004. its ok.
But call wrong uri: http://localhost:8089/MyService/rest/employeeservices/getemployeedetallll?employeeId=004. It throw exception:
WARNING: No operation matching request path "/MyService/rest/employeeservices/getemployeedetallll" is found, Relative Path: /getemployeedetal, HTTP Method: GET, ContentType: /, Accept: /,. Please enable FINE/TRACE log level for more details.
Jun 07, 2016 1:55:17 PM org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse
WARNING: javax.ws.rs.ClientErrorException
at org.apache.cxf.jaxrs.utils.SpecExceptions.toHttpException(SpecExceptions.java:110)
at org.apache.cxf.jaxrs.utils.ExceptionUtils.toHttpException(ExceptionUtils.java:149)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.findTargetMethod(JAXRSUtils.java:477)
So how can i filter the right uri before access controller class.
Please help me. Thank you.
By this configuration, is it flow of request process? : request ->
Spring security(check authentication) -> cxf -> response.
Yes, because J2EE filters are executed around J2EE servlets (before and after euqeust), so springSecurityFilterChain will be executed before CXFServlet
Are there any issues in this configuration when I deploy it in the
real sever?
This is not necessary with latests versions of CXF
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
Also you are catching in CXFServlet /rest/* but in auth *. Is this an issue? Do you need rest services without authentication? Is difficult to analyze issues if we do not know the context of your system. Detail your doubts and I could try to help
what is the standard configuration when using cxf and spring ?
There is no any recommended configuration, because CXF can be used with spring or standalone, jax-ws or jax-rs, as a server or acting as a client, with authentication executed via spring security or integrated with RequestContextFilter or inInterceptor in jax-rs server or even at global level in CXF bus.
If you are talking about the necessary modules to configure so CXF was executed with spring, you have the needed ones.
For authentication, you could consider use a JWT token instead of a bcrypt passwod.
when i call right
uri:http://localhost:8089/MyService/rest/employeeservices/getemployeedetals?employeeId=004.
its ok. But call wrong uri:
http://localhost:8089/MyService/rest/employeeservices/getemployeedetallll?employeeId=004.
It throw exception:
WARNING: No operation matching request path
This warning is normal. The server is responding with an http error code 404-Not found because there is no resource available at rest/employeeservices/getemployeedetallll
So how can i filter the right uri before access controller class.
CXF is doing for you by returning a 404 if the path is not found. It is the correct behaviour. Do you mean CXF uri filter be executed before spring-security? You can not with this configuration because auth filter is previous.

Allow Specific URL patterns to bypass Spring Security Login

I have a web application protected by spring security. However, there is one particular URL pattern that I do not want to apply any security to. I've tried a few different approaches, but none of them seem to be working. Whenever I attempt to go to that specific URL, I am forwarded to the spring_security_login page.
A piece of the web.xml:
<!-- NOT SECURE -->
<servlet>
<servlet-name>dontSecureServlet</servlet-name>
<servlet-class>org.com.gov.lol.DontSecure</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dontSecureServlet</servlet-name>
<url-pattern>/dontSecure</url-pattern>
</servlet-mapping>
<!-- SECURE -->
<servlet>
<servlet-name>secureServlet</servlet-name>
<servlet-class>org.com.gov.lol.Secure</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>secureServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<!-- SECURITY FILTER -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
A piece of the security-context.xml:
<!-- This did not work -->
<http pattern="/dontSecure" security="none" />
<http entry-point-ref="entryPoint" use-expressions="true">
<custom-filter ref="customFilter" position="PRE_AUTH_FILTER" />
<!-- I've also tried adding the following here (with no luck) -->
<intercept-url pattern="/dontSecure" filters="none" />
<intercept-url pattern="/secureMe" requires-channel="https" />
<intercept-url pattern="/secureUs" requires-channel="https" />
</http>
<!-- I have even tried adding a separate <http> block just for /dontSecure -->
<http>
<intercept-url pattern="/dontSecure" security="none" />
</http>
Again, with any combination of the above configuration, the url /dontSecure is still forwarded to the spring login page.
Any ideas as to what could be causing this?
Cheers.
UPDATE
From the server logs, it seems that the /dontSecure url is loading the dontSecureServlet. However, an error seems to be generated and I am being forwareded the 404 error page (which is configured as /404.htm, which must be what brings me back to the login page).
I've included some extra snippits from the web.xml that I didn't think were relevant at first.
Try to change your intercept-url in your configuration with this one:
<intercept-url pattern="/dontSecure/**" access="permitAll" />
not in a separate <http> tag
The problem might be caused by the fact that your custom filter is getting applied to all the paths. You have to find a way to register your custom filter only for certain paths (I could show you how to do this in Spring Boot, but you probably aren't using it).

SecurityContextHolder.getContext().getAuthentication() is null for Ajax call

I have a situation where we have two separate home pages for signed in and non-signed in users. But we are trying to cache these pages using cloudfront. One part of the home page is dynamic and we are trying to set this using an Ajax/jquery calling restful service and setting the output values in template javascript. This javascript is executed on load of signed in JSP.
I believe SecurityContextHolder.getContext().setAuthentication() is being called after logging in.
In Restful webservice called by Ajax I am trying to get Loggedin User using
SecurityContextHolder.getContext().getAuthentication().getPrincipal(). But getAuthentication() is returning null.
My web.xml is as below
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/classes/persistence-context.xml
WEB-INF/xyz-servlet.xml
WEB-INF/classes/environment-context.xml
WEB-INF/classes/transactional-context.xml
WEB-INF/classes/spring-security-context.xml
WEB-INF/classes/services-context.xml
WEB-INF/classes/aop-context.xml
</param-value>
</context-param>
<!-- Spring Security Filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
In spring-security-context.xml I have below values
<http use-expressions="true" auto-config="false" create-session="never" entry-point-ref="authenticationProcessingFilterEntryPoint">
<access-denied-handler ref="exceptionResolver" />
<intercept-url pattern="/xyz/myaccount/**" access="hasRole('FRONT_END_USER')" />
<intercept-url pattern="/xyz/form-clickref*" access="hasRole('FRONT_END_USER')" />
<intercept-url pattern="/**" filters="none" />
<form-login login-page="/xyz/login" login-processing-url="/xyz/j_spring_security_check"
authentication-failure-handler-ref="xyzAuthenticationFailureHandler"
authentication-success-handler-ref="simpleUrlAuthenticationSuccessHandler" />
<logout logout-url="/xyz/logout" invalidate-session="true" success-handler-ref="logoutSuccessHandler" />
<remember-me services-ref="rememberMeServices" key="fe2c667b-d39e-4277-ba66-709ca0bee944" />
<anonymous enabled="false" />
<request-cache ref="nullRequestCache" />
<session-management session-fixation-protection="none" />
</http>
I guess, the application lost track of the users http session in your AJAX Requests.
Normally there are two (three) ways to track the session of an user:
using JSessionID a url query parameter
using a cookie that contains the JSessionID
(mixed mode: the sever decides which of the two above techniques to use)
I guess that your AJAX request is not sending the Cookie nor the JSessionId request parameter.
To understand the problem, I would use some tool/Firefoxplugin (FireBug, Http Live Headers, ...) to have a look at the REQUESTs sended to the server. I would check the "normal" requests, and have a look whether I can find the JSessionID (url query paramter, or session). Then I would have a look at the AJAX requests, and would look for the same information.
If there is a JSessionId in the normal requests, but not in the AJAX requests, then my guess is right. Then all you need to do, is to this information to the AJAX requests too. good luck

Websphere 8 / Spring security (LDAP) / not redirecting to login.xhtml

I try to get LDAP and Spring on a Websphere 8 running. It somehow does, but it does not forward any requests to my login.xhtml.
Means, that it looks like you are logged in, but you cannot click anything on that page and you are not forwarded to the login page.
If I call it directly (/faces/login.xhtml), log in and then click around, everything works as expected, so it is just that my application does not forward me to the required loginpage.
Hope you guys have a good idea.
My web.xml looks like that:
<!-- removed non-relevant parts-->
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
My applicationSecurity.xml looks like that:
<security:http pattern="/faces/ressources/**" security="none"/>
<security:http auto-config="true" pattern="/**">
<!-- Login pages -->
<security:form-login login-page="/faces/login.xhtml" default-target-url="/faces/index.xhtml"
login-processing-url="/faces/j_spring_security_check"
authentication-failure-url="/faces/login.xhtml" />
<security:logout logout-success-url="/faces/login.xhtml" />
<!-- Security zones -->
<!-- secured -->
<security:intercept-url pattern="/faces/index.xhtml" access="ROLE_APP_QPA_ADMIN,ROLE_APP_QPA_USER" />
<security:intercept-url pattern="/faces/datadictionary/**" access="ROLE_APP_QPA_ADMIN,ROLE_APP_QPA_USER" />
<security:intercept-url pattern="/faces/templates/**" access="ROLE_APP_QPA_ADMIN,ROLE_APP_QPA_USER" />
</security:http>
I have no clue what else I could do.
I use Spring as shared Library, if that matters.

Resources