How to use Spring Managed Hibernate Session in Seam? - spring

Most recent project I working where I trying to use Spring (3.1.1.RELEASE) Managed Hibernate Session into Seam (2.3.0.Final).
In JBoss Seam Documentation where they explain How to use Seam Managed Hibernate Session in Spring. But our requirement is invert than the documentation.
I got another solution Using Spring PlatformTransactionManagement but my requirement is use Spring Managed Hibernate Session in Seam. I don't want to use Seam manage Hibernate Session/Hibernate Entity Manager/Transaction. Only want to use Seam manage dependency injection to inject Spring bean into Seam manage bean via seam #In not Spring #Autowire.
If anybody faces such type of challenge please either help to configure Seam components.xml & Spring applicationContext.xml or provide me guide line to overcome this.

First Configure applicationContext.xml as usually you configured:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- hibernate Properties Here -->
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven/>
Then Configure components.xml as following:
<core:init debug="true" transaction-management-enabled="true" />
<spring:context-loader config-locations="classpath*:/META-INF/spring/applicationContext.xml"/>
<core:manager concurrent-request-timeout="500" conversation-timeout="120000" conversation-id-parameter="cid" parent-conversation-id-parameter="pid" />
<persistence:managed-hibernate-session name="hibernateSession" auto-create="true" session-factory="#{sessionFactory}"/>
<spring:spring-transaction platform-transaction-manager="#{transactionManager}"/>
Its very much easy to interact Spring(3.1.1.RELEASE) with Seam (2.3.0.Final) but never forget to configure web.xml for seam.
<listener>
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/resource/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>Seam Filter</filter-name>
<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Seam Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<session-config>
<session-timeout>10</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
For facelets your should add variable resolver in faces-config.xml
<application>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
Better to download Seam-2.3.0.Final. Uzip it, inside examples\spring\ folder you will got your desired configuration

Related

Spring mvc configuration to integrate with a custom SSO authentication

I'm failing to integrate an existing custom Single-sign-on service (for the authentication of my spring mvc application -aka. myApp-).
Once I map the spring DispatcherServlet to "/", myApp skips the authentication process against the SSO application, no matter if there's session or not.
Web.xml (Spring Configuration)
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<!-- Spring MVC DispatcherServlet -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Here is the configuration that I need to integrate in myApp web.xml, to integrate the SSO authentication:
Web.xml (Custom SSO Configuration)
<filter>
<filter-name>SSOAuthenticationFilter</filter-name>
<filter-class>custom.sso.SSOAuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SSOAuthenticationFilter</filter-name>
<url-pattern>/WEB-INF/views/*</url-pattern>
</filter-mapping>
<!-- Context Params -->
<context-param>
<param-name>myAppId</param-name>
<param-value>65asd5a4sd65asd65a4sd65asd4</param-value>
</context-param>
<context-param>
<param-name>loginPath</param-name>
<param-value>login.jsp</param-value>
</context-param>
<context-param>
<param-name>ssoAppPath</param-name>
<param-value>http://localhost:8080/SSO_AuthenticationApp</param-value>
</context-param>
<!-- SSO Login Servlet -->
<servlet>
<servlet-name>SSOloginServlet</servlet-name>
<servlet-class>custom.sso.SSOLoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SSOloginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<!-- SSO properties (myAppId, ssoAppPath, loginPath) -->
<listener>
<listener-class>custom.sso.SSOPropertiesRetriever</listener-class>
</listener>
How can I configurate spring to let the SSO servlet to do the authentication process?
I was thinking if there's a way of declaring the customSSO servlet as a bean in the spring dispatcher-servlet-config.xml?
Or maybe implementing it in a #Controller?
(My hands are tied about the sso, I'm forced to use it for the authentication, cause myApp will be just another in a family of applications login through this custom sso... I would prefer to use spring security instead).
Thanks.
EDITED:
I finally opted for a migration to Spring Boot, seems way more clear to configure a project that way.
For the filter you can use a SpringFilter and implement the logic in a bean:
<filter>
<filter-name>springFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>authenticationFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springFilter</filter-name>
<url-pattern>/some-url</url-pattern>
</filter-mapping>
For the servlet I guess you may have to change your mappings to something that looks like the following:
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>my.package.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
Here I'm assuming that everything goes in the same WEB.xml file

Spring security +Jsf2

I'm newbie at spring security it's my first use to spring security at me APP
My application has developed using jsf2 , primefaces , spring , hibernate
after developing it I'm trying to integrate it with Spring security framework
there are two problems
1- when access any URL from app , my app isn't navigate him to login page
2- when one user logged in and someone else tried to access the application in the same time , he see that someone is logged in and conflicts are happenned and at end throw exceptions meaning there is no new created session for the second user
My applicationContext-Security.xml is
<context:property-placeholder location="classpath:resources/jdbc.properties" />
<!-- For Spring auto wiring -->
<tx:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="main.com.zc.attSys" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager" />
<http use-expressions="true">
<form-login login-page="/pages/courseFeedBack/ask/login.xhtml"
authentication-failure-url="/pages/courseFeedBack/ask/login.xhtml" />
</http>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
</beans:beans>
my web.xml is :
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<!-- Add Support for Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.faces.conf
ig.ConfigureListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<!-- <context-param> <param-name>primefaces.THEME</param-name> <param-value>none</param-value>
</context-param> -->
<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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>
any help please ?

Spring Security 3.2: #Secured annotations not taken into account

I am trying to secure my RESTful API using Spring 3.2.4 and Spring Security 3.2 using the #Secured annotations. I have the following setup:
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:spring/*.xml
/WEB-INF/classes/security/security-context.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 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>
<!-- Servlet configuration -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/servlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
servlet-context.xml:
<context:component-scan base-package="com.mycompany.rest.controller" />
<security:global-method-security secured-annotations="enabled" />
security-context.xml
<beans:bean id="merchantUserDetailsService" class="com.mycompany.rest.security.CustomUserDetailsService" />
<http auto-config="false" create-session="never">
<http-basic />
</http>
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService" />
</authentication-manager>
I am programmatically assigning custom roles (ROLE_GROUP, ROLE_DIVISION, ROLE_READ, ROLE_WRITE) in the customUserDetailsService to the user and this works fine.
One of my controllers:
#Secured("ROLE_DIVISION")
#RequestMapping(method = RequestMethod.GET)
ResponseEntity<List<CustomerResource>> getCustomer() throws ResourceDoestNotExistException {
List<Customer> providers = // retrieve providers from DAO
List<CustomerResource> resources = customerResourceAssembler.toResources(customers);
return new ResponseEntity<>(resources, HttpStatus.OK);
}
Now to my problem, the #Secured annotations are being ignored. I want to use the #Secured annotation to avoid having to define multiple 's in the configuration. Spring Security works fine when I add at least one , but how can avoid defining them and instead rely on the #Secured annotations?
I can now access the method above with an user with the role "ROLE_GROUP".
Looks like you have everything right except that you've enabled the wrong type of annotations. If you check the documentation for global-method-security you'll see there's a separate attribute called secured-annotations which enables #Secured.

Integrate JSF 2.1 and Spring 3.2

I want to use my Spring Beans in my JSF application, letting Spring inject my services/repositories in my JSF Managed Beans.
I found a lot of solutions in the Internet, but the only one that worked was the following lines of code:
ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
albumRepository = (AlbumRepository) ctx.getBean("albumRepository");
albumRepository is the Spring Bean I'm trying to inject.
The problem is that it's really lame, I don't wanna do this in every class, for every injection. I'd like to use anotations, like "#Inject".
Searching an answer in Google, I found that I should integrate JSF and Spring using the following config in faces-config.xml:
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
Then, I should be able to use my Spring Beans with the annotation "#ManagedProperty(value="#{albumRepository}")". I tried it, but I aways get the error "The property albumRepository for the managed bean does not exist".
Searching again in Google I found out that I could use the Spring annotations to do my injections, the only thing i'd need would be to register the package where my managed beans are located in the applicationContext.xml. I've done it, but Spring just ignores my annotations (#Inject and #Autowired, I tried both).
After all these failures I tried to stop using the JSF annotations (#ManagedBean and #ViewScoped), instead, I used Spring ones (#Controller and #Scope). Now JSF doesn't even recognize the beans.
What am I doing wrong?
Edit: My ApplicationContext.xml
<context:annotation-config/>
<jpa:repositories base-package="com.ae.repository" />
<context:component-scan base-package="com.ae.client.web, com.ae.service" />
<!-- Data Source -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3306/academia</value></property>
<property name="username"><value>root</value></property>
<property name="password"><value>root</value></property>
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="persistenceXmlLocation" value="/META-INF/persistence-web.xml"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
Edit: My web.xml
<!-- Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- JSF -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<!-- Primefaces -->
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
In your web.xml has context param like this ?
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/*Context.xml</param-value>
</context-param>
Also can you send listener about spring in your web.xml
If you want Spring IOC container to manage all your beans. Use one of #Component, #Named or javax.annotation.ManagedBean annotation and you can inject them using #Autowired or #Inject. Don't forget to use Spring's #Scope for any of those.
See Documentation
If you want to use JSF IOC container as well along with Spring IOC container, you can inject Spring beans into a JSF bean using #ManagedProperty.
See Also:
#Scope("request") not working
How does Spring autowire by name when more than one matching bean is found?

spring 3 mvc multiple application context instances

here is my 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">
<!-- Enables clean URLs with JSP views e.g. /welcome instead of /app/welcome -->
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</context-param>
<!-- Handles all requests into the application -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Maps all /app requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Why there are two instances of application context created?
When I add a scheduled method with #Scheduled it is invoked twice, because of those two application contexts.
You are loading twice times the same spring config files. Of course you have two separate application contexts. At first I would rename the servlet name for the DispatcherServerlet to "spring3mvc". The servlet definition should look like this:
<servlet>
<servlet-name>spring3Mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
If you have it in this way, you should have a spring config file "spring3Mvc-servlet.xml" in your "WEB-INF" directory. Spring will find this file automatically because of the right naming convention. In this file you should just have the beans who are important for springMVC. It could look like this:
<context:component-scan base-package="org.company.gui.controller"/>
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".view.jsp"/>
</bean>
This should fix your problem.
I noticed that you have
<load-on-startup>1</load-on-startup>
in the following block
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
try removing that... it worked for me
Do you have any other spring filters or jsp pages in your web.xml not shown in your code snippet?
I ask, to answer your question, because I believe this quote from Spring documentation could explain what might be happening...
"In the web MVC framework, each
DispatcherServlet has its own
WebApplicationContext, which inherits
all the beans already defined in the
root WebApplicationContext. These
inherited beans defined can be
overridden in the servlet-specific
scope, and new scope-specific beans
can be defined local to a given
servlet instance."
If you answered "yes" to my web.xml question, then my guess is that Spring instantiates a root WebApplicationContext when a spring filter is created (via ContextLoaderListener). So, this would happen BEFORE...
Then, when the DispatcherServlet is created, the "contextConfigLocation" refers to the same files (that is, the same bean names), so a new WebApplicationContext gets overridden bean names local to that servlet!
I wonder, even if you answered "no", whether this might still happen anyway. Since you set "contextConfigLocation" (used by the ContextLoaderListener) and "override" it in DispatcherServlet configuration; I assume Spring is not checking whether those configurations are using the same file set.
You can run these scenarios through a debugger and put breakpoints on WebApplicationContext methods to find out for sure.
Workaround:
To solve the problem, either:
1) make sure your 2 contextConfigLocations don't overlap in files they use
Or:
2) break out the Scheduling bean in its own xml file and make sure it's referred to by only one of the 2 contextConfigLocations

Resources