I am using Spring MVC and JQUERY to implement a 2 step process to submit data from a form to the server:
A JQUERY ajax POST request would submit the file data from form to the server on click of file browse. This would store the file on file server and create an entry into the database storing the file information, with the mode set as draft.
When user clicks on form submit button, the other form data such as 'File Title' and so on, would be submitted to the server. The entry into database should now set the mode to 'Complete'.
At step 1 I am setting the file data such as Id of the column in database, name of file into a session attribute.
/**
* Upload single file using Spring Controller
*/
#RequestMapping(value = "/uploadFileDraft", method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.OK)
public void uploadFileDraft(#RequestParam("file") MultipartFile file,Model map, HttpSession httpSession) {
PostDto draftPost = new PostDto();
draftPost.setPostedDate(new Date());
draftPost.setStrRawFileName(file.getOriginalFilename());
//Logic to save this object into database.
postService.uploadPostDraft(draftPost);
//now set the data into session object
httpSession.setAttribute("filePostDraftDto", draftPost);
}
Now in step 2 I trying to retrieve this Dto object from session and calling another service. But he object does not exist into the session.
#RequestMapping(value = "/uploadFilePublish", method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.OK)
public void uploadVideoPublish(#RequestParam("strVideoTitle") String strVideoTitle, Model map, HttpSession httpSession) {
PostDto postDtoDraft = null;
if(null!= httpSession.getAttribute("filePostDraftDto"))
{
postDtoDraft = (PostDto)httpSession.getAttribute("filePostDraftDto");
}
if(null!=postDtoDraft )
{
System.out.println("file name from session is: "+postDtoDraft.getStrFileName());
}
else
{
System.out.println("error: postDtoDraft is null");
}
}
}
The following gets printed everytime: error: postDtoDraft is null
My web.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
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_3_0.xsd">
<display-name>WebConnect</display-name>
<!-- Spring Security Configuration File -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-security.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlet and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</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>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
<!-- session time out set as 30 minites -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
The applicationConfig.xml is:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.mycomp.myproj" />
<context:spring-configured />
<neo4j:config graphDatabaseService="graphDatabaseService" />
<neo4j:repositories base-package="com.mycomp.myproj.repository" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<property name="maxUploadSize" value="10000000000" />
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:default-servlet-handler />
<mvc:annotation-driven />
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />
The spring-security.xml is:
<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.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/resources/**" security="none" />
<http authentication-manager-ref="userAuthManager">
<intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/register" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page='/' authentication-failure-url="/" />
<logout invalidate-session="true" logout-success-url="/" logout-url="/j_spring_security_logout" />
<session-management invalid-session-url="/">
<concurrency-control max-sessions="1"
expired-url="/" />
</session-management>
</http>
<beans:bean id="userAuthManager" class="com.inw.pyt.security.UserAuthManager">
</beans:bean>
<beans:bean id="passwordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
The solution to this issue was with the class PostDto not being serializable. Once I changed PostDto to implement Serializable it started working. Seems like there is a restriction with Spring, which does not let objects to be stored in session unless they are serializable.
I found the issue when I tried to use Spring's own #SessionAttributes to set and get from the session, instead of the HttpSession. Then while setting the attribute into the Spring model I got the following error in the console:
StandardWrapperValve[mvc-dispatcher]: Servlet.service() for servlet mvc-dispatcher threw exception
java.lang.IllegalArgumentException: setAttribute: Non-serializable attribute with name filePostDraftDto
at org.apache.catalina.session.ManagerBase.checkSessionAttribute(ManagerBase.java:835)
at org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1840)
at org.apache.catalina.session.StandardSessionFacade.setAttribute(StandardSessionFacade.java:178)
at org.springframework.web.context.request.ServletRequestAttributes.setAttribute(ServletRequestAttributes.java:131)
at org.springframework.web.bind.support.DefaultSessionAttributeStore.storeAttribute(DefaultSessionAttributeStore.java:55)
at org.springframework.web.method.annotation.SessionAttributesHandler.storeAttributes(SessionAttributesHandler.java:124)
Related
I'm getting this error when I run my web application on Tomcat 7 and the server won't stop (just like an infinite loop), if anyone can help, I'm using Spring 4.2.0 with Spring Security 4.0.2.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException:............................................
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0':
CRMUserDetailsServiceImpl
#Configuration
#Component
#Service
public class CRMUserDetailsServiceImpl implements UserDetailsService{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-security.xml");
#Autowired
private CRMUserDAO userDAO = null;
#Autowired
public void setUserDAO(CRMUserDAO userDAO) {
this.userDAO = userDAO;
}
#Override
#Transactional(readOnly = true)
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
userDAO = (CRMUserDAO)context.getBean("CRMUserDAOImpl");
CRMUser user = userDAO.findByEmail(email);
if (user == null) {
throw new UsernameNotFoundException("User not found" + email);
}
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Privilege prvlg : user.getPrivileges()) {
grantedAuthorities.add(new SimpleGrantedAuthority(prvlg.getPrivilege()));
}
return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), grantedAuthorities);
}
}
spring-security.xml
<?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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/" access="hasRole('PRVG_ADMIN')"/>
<intercept-url pattern="/welcome" access="hasRole('PRVG_ADMIN')"/>
<form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/login?error" username-parameter="email" password-parameter="password"/>
<logout logout-success-url="/login?logout" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="CRMUserDetailsServiceImpl">
<password-encoder ref="encoder"></password-encoder>
</authentication-provider>
</authentication-manager>
<!-- defining CRMUserDAO bean -->
<beans:bean id="CRMUserDAOImpl" class="org.arw.crm.dao.CRMUserDAOImpl"/>
<!-- Defining CRMUserDetailsServiceImpl bean and injecting CRMUserDAO bean -->
<beans:bean id="CRMUserDetailsServiceImpl" class="org.arw.crm.service.CRMUserDetailsServiceImpl">
<beans:property name="userDAO" ref="CRMUserDAOImpl" />
</beans:bean>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11"/>
</beans:bean>
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/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<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>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/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
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="org.arw.crm" />
<default-servlet-handler/>
</beans:beans>
root-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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">
<!-- Root Context: defines shared resources visible to all other web components -->
<import resource="/mvc-dispatcher.xml" />
<import resource="classpath:spring-security.xml" />
<!-- Scans within the base package of the application for #Component classes to configure as beans -->
I am not able to find out my problem in spring security integration. I have spent 2-3 days already.So, please help me.
below is my web.xml file
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>cdl</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>startUpServlet</servlet-name>
<servlet-class>com.qait.cdl.commons.startup.StartUpServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>startUpServlet</servlet-name>
<url-pattern>/startUpServlet.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>CDL_ENV</param-name>
<param-value>staging</param-value>
</context-param>
<listener>
<listener-class>com.qait.cdl.commons.startup.CdlContextListner</listener-class>
</listener>
<!-- Session timeout -->
<session-config>
<session-timeout>600</session-timeout>
</session-config>
<!-- <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> -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/applicationContext.xml
WEB-INF/dispatcher-servlet.xml
</param-value>
</context-param>
</web-app>
Below is my applicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<import resource="classapth*:spring/SpringSecurityConfig.xml" />
<!-- <bean name="springSecurityFilterChain" class="org.springframework.web.filter.OncePerRequestFilter"/> -->
</beans>
Below is my SpringSecurityConfig.xml
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/displayAdminPage.htm" access="hasRole('ROLE_ADMIN')" />
<security:form-login login-page="/login.htm" authentication-failure-url="/login.htm"/>
<security:logout logout-url="/logout.htm" logout-success-url="/login.htm"/>
<security:access-denied-handler error-page="/login.htm" />
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService" >
</security:authentication-provider>
</security:authentication-manager>
below is my dispatcher-servlet.xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Message resource -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
<value>error</value>
</list>
</property>
</bean>
<!-- Imports all configuration files -->
<import resource="classpath*:spring/*.xml" />
<import resource="classpath*:spring/*/*.xml" />
<!-- Interceptor mapping -->
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<!-- <property name="interceptors" ref="cdlInterceptor" /> -->
<property name="interceptors" ref="cdlSessionInterceptor"></property>
</bean>
<!-- Tiles view resolver and configuration -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.tiles2.TilesView" />
<property name="order" value="1" />
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-defs.xml</value>
</list>
</property>
</bean>
<!-- XmlView Resolver -->
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location" value="/WEB-INF/spring-Xmlviews.xml" />
<property name="order" value="0" />
</bean>
<!-- MultipartResolver for file upload -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<bean id="rssViewer" class="com.qait.cdl.rssfeed.view.CustomRssViewer" />
<!-- Default view resolver mapping <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property
name="suffix"> <value>.jsp</value> </property> <property name="order" value="1"
/> </bean> -->
</beans>
I have following queries.
Is it necessary to give "filter" tag in web.xml, if yes than why?
In my application, I have two application context(one for spring security and other for dispatcher-servlet), is it possible for springSecurityConfig.xml to access bean definition which is defined in dispatcher-servlet.xml?
what is the flow of spring-security configuration.Upto my knowledge, i have understood that intercept-url tag intercept the request and check appropriate role using expression language.I am not able to understand how it looks appropriate role in DB via authentication-manager i've provided.
below is my userService bean definition in service.xml
<bean name="userService" class="com.qait.cdl.services.impl.UserServiceImpl">
<property name="userDao" ref="userDao" />
</bean>
below is userService interface
public interface UserService extends UserDetailsService{
}
this UserDetailsService is from springframework
below is UserServiceimpl class
public class UserServiceImpl implements UserService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
UserDetails userDetails = null;
if(username != null && !"".equals(username)){
User user = userDao.get(username);
if(user != null){
UserGroupAuthority groupAuthority = userDao.getUserAuthority(user);
if(groupAuthority != null){
Collection<GrantedAuthority> grantedAuthorities = getGrantedAuthorities(groupAuthority.getAuthority());
userDetails = new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
true, true, true, true, grantedAuthorities);
}
}
}
return userDetails;
}
#Override
public Collection<GrantedAuthority> getGrantedAuthorities(String authority) {
List<GrantedAuthority> grantedAuthorities = new LinkedList<GrantedAuthority>();
grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
return grantedAuthorities;
}
#Override
public UserGroupAuthority getUserAuthority(User user) {
return userDao.getUserAuthority(user);
}
}
Simply the problem is , it is not validating the given intercept-url. Where I am doing mistake?
Activate springSecurityFilterChain in your web.xml. It's an entry point of Spring Security. If springSecurityFilterChain is deactivated then Spring Security will never work.
I'm writing a GWT application secured with Spring security. Logging in works fine, but authorization doesn't.
I've tried using #Secured and #PreAuthorize annotations on my methods and that didn't work either.
For instance, this is a code snippet from AppUserServiceImpl
#Secured("ROLE_ADMINISTRATOR")
#Override
public List<AppUser> fetch(Integer startRow, Integer endRow, Map criteria) {
return appUserManagerBean.getUsers(criteria);
}
ApplicationContext.xml
<?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-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http auto-config="true">
<intercept-url pattern="/testapplication/**" access="ROLE_USER"/>
<intercept-url pattern="/gwt/**" access="ROLE_USER"/>
<intercept-url pattern="/**/*.html" access="ROLE_USER"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/security/*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/testapplication/appUserService*" access="ROLE_ADMIN"/>
<form-login
login-page="/login.jsp"
authentication-failure-url="/security/error.html"
login-processing-url="/j_spring_security_check"
/>
</http>
<beans:bean id="appUserService" class="com.test.testapplication.server.admin.appuser.AppUserServiceImpl"/>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
[DATASOURCE CONFIGURATION]
</beans:bean>
<global-method-security pre-post-annotations="enabled" secured-annotations="enabled" />
<authentication-manager>
<authentication-provider>
<password-encoder hash="sha" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,password,DECODE(enabled,'Y',1,'N',0) as enabled from APP_USER where username=?"
authorities-by-username-query="select u.username, ur.role from APP_USER u, APP_USER_ROLE ur
where u.id = ur.APP_USER_ID and u.username =? "
/>
</authentication-provider>
</authentication-manager>
To test, I'm trying to secure 'appUserService'.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<servlet>
<servlet-name>appUserService</servlet-name>
<servlet-class>com.test.testapplication.server.admin.appuser.AppUserServiceImpl</servlet-class>
</servlet>
<!-- 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>
<!-- Spring listener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>testapplication.html</welcome-file>
</welcome-file-list>
I'm looking for the simplest solution and I would prefer not to use AspectJ, help would be greatly appreciated
Where are you mapping your servlet to particular path?
I'm using gwt-sl for integration of RemoteServiceServlets and Spring.
Define Dispatcher servlet in your web.xml:
<servlet>
<servlet-name>gwtservice</servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
And declaration and mapping for your gwt-servlet:
<bean name="DeviceListenerServlet" class="your.package.your.SomeService"/>
<bean id="urlMappingGWT" class="org.gwtwidgets.server.spring.GWTHandler">
<property name="mappings">
<map>
<entry key="/service" value-ref="DriverServiceImpl"/>
</map>
</property>
</bean>
And change Annotation in your RemoteService class (in my example it will be #RemoteServiceRelativePath("gwtservice/service")).
Now you can use you #Secured annotation (if you added )
Hope this help.
Recently, I have begun a bit of a personal project, and I decided to implement Spring Security. I have attempted to do so before, but I had no better luck that time than I am now. I got around the problem then, but that method (accessing the security context directly from the code and checking the string of roles it contains for the current user) feels like a hack, and I would like to get it right this time.
Right now I have Spring Security MOSTLY functioning, as far as I know...I can attempt to go to a page with a role-based redirect, and it will redirect me to the login page. I can log in with good or bad information and be sent to the proper location. What I cannot do, what I have never managed to do, is get the #Secured or #PreAuthorize annotation to function as I would hope.
Let me try to explain (code will follow). My welcome/login page is index.jsp and, when you log in, Spring Security sends you to login.html which is where I have a method in my LoginController class mapped. Inside that method, I try to call a large set of other methods: none of this is supposed to be final, I am just trying to get prove to myself that things are running.
I call two methods that are secured by #Secured, and two methods that are secured by #PreAuthorize, one "ROLE_ADMIN" and one "ROLE_USER" each. The account that I am logging into only has the ROLE_USER authority. This being the case, I would expect to get redirected to my accessdenied.jsp page as per having set that as the target of my Spring Security's access-denied-page attribute. What I do not expect, and what I am seeing, is that every method is successfully called and run when I log in.
I have (at least attempted to) follow the tutorials. I have spent days on Google, reading everything that I can find. I have merged my security context into my context, and everything else that came to my attention as a potential solution. I apologize if I have been a mite long-winded, but I would rather provide too much information than too little. To that end, the following is my code:
index.jsp
<html>
<body>
<form action="j_spring_security_check" method="POST">
<label for="j_username">Name:</label>
<input id="j_username" type='text' name='j_username' />
<br />
<label for="j_password" class="passwordField">Password:</label>
<input id="j_password" type='password' name='j_password' />
<br />
<input id="proceed" type="submit" value="Submit" />
</form>
</body>
</html>
LoginController.java
package cribbage.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.jdbc.core.JdbcTemplate;
import cribbage.database.entity.Test;
#Controller
public class LoginController {
#Autowired
JdbcTemplate t;
#RequestMapping(value = "/login")
public ModelAndView login(HttpServletRequest request) {
test();
test2();
test3();
test4();
return new ModelAndView("test.jsp");
}
#Secured("ROLE_ADMIN")
public void test(){
System.out.println("Test One");
}
#Secured("ROLE_USER")
public void test2(){
System.out.println("Test Two");
}
#PreAuthorize("hasRole('ROLE_ADMIN')")
public void test3(){
System.out.println("Test Three");
}
#PreAuthorize("hasRole('ROLE_USER')")
public void test4(){
System.out.println("Test Four");
}
}
web.xml
<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">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<display-name>Spring Security Tutorial Application</display-name>
<!-- - Location of the XML file that defines the root application context
- Applied by ContextLoaderListener. -->
<context-param>
<description>Spring context file</description>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
</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>
<!-- - Provides core MVC application controller. See bank-servlet.xml. -->
<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/applicationContext.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<context:property-placeholder location="classpath:*.properties" />
<mvc:annotation-driven />
<!-- Which packages to scan when looking for beans defined with #Component -->
<context:component-scan scoped-proxy="targetClass"
base-package="cribbage.controller
cribbage.database.dao
cribbage.database.entity" />
<context:annotation-config />
<!-- Turn on AspectJ #Configurable support -->
<!-- Turn on #Autowired, #PostConstruct etc support -->
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<!-- Add Transaction support -->
<!-- Use #Transaction annotations for managing transactions -->
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource" />
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver"
p:defaultLocale="en_US" />
<!-- For database, uses maven filtering to fill in place holders -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="1" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
<security:global-method-security
secured-annotations="enabled" pre-post-annotations="enabled" />
applicationContext-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.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/CSS/**" security="none" />
<http auto-config="true" use-expressions="true" access-denied-page="/accessdenied.jsp">
<form-login always-use-default-target="false"
login-processing-url="/j_spring_security_check" default-target-url="/login.html"
login-page="/index.jsp" authentication-failure-url="/loginFailed.jsp" />
<logout logout-url="/j_spring_security_logout" />
<intercept-url pattern="/test.jsp" access="hasRole('ROLE_USER')" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,user_password,enabled from users where username=?"
authorities-by-username-query="select username,authority,enabled from users where username=?" />
</authentication-provider>
</authentication-manager>
Thank you for any help that you can provide.
actully spring security works only if aspect/security interceptor involved. In your code test(),test2(),test3(),test4() are invoked directly from controller method login. so there will not be any aspect involvement causing security to be bypassed.
if test methods are part of another spring bean then this should work as you have been expecting.
or if they are in same class then it should be invoked with spring bean instead of this (current object).
I am using spring 3.0.2
My scheduled method is invoked twice..
am i making some mistake..?
please help me to figure it out..
#Component("happySundayGreetTask")
public class HappySundayGreetTask {
#Autowired
private JavaMailSender mailSender;
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
#Value("${mail.sender}")
private String fromAddress;
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
#Autowired
private VelocityEngine velocityEngine;
public void setVelocityEngine(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}
#Autowired
private SpitterDAO spitterDAO;
public void setSpitterDAO(SpitterDAO spitterDAO) {
this.spitterDAO = spitterDAO;
}
#Scheduled(cron="0 58 18 ? * SUN")
public void greetSundayToSpitters(){
try {
System.out.println("task started..");
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper mimeHelper = new MimeMessageHelper(message, true);
List<String> spittersEmail = spitterDAO.getSpittersEmail(true);
String toAddress[] = spittersEmail.toArray(new String[spittersEmail.size()]);
String templateLoc = "com/spitter/task/sundayGreetEmailTemplate.vm";
String emailText = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, templateLoc, null);
mimeHelper.setFrom(fromAddress);
mimeHelper.setTo(toAddress);
mimeHelper.setSubject("Sunday Greeting from Spitter");
mimeHelper.setText(emailText, true);
mailSender.send(message);
}
catch (MessagingException ex) {
Logger.getLogger(HappySundayGreetTask.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
// spitter-servlet.xml
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
">
<!-- Defining a PropertyPlaceholderConfigurer -->
<context:property-placeholder
location="classpath:/com/spitter/dao/db.properties,
classpath:/com/spitter/service/alerts/mailserver.properties"/>
<!-- Declaring security aspects to those beans annotated with #PreAutorize -->
<security:global-method-security pre-post-annotations="enabled" />
<!-- Support for annotation driven validation, message conversion -->
<mvc:annotation-driven/>
<!-- Automatically registering controllers & service objects as beans -->
<context:component-scan base-package="com.spitter"/>
<!-- Autowiring enabled using annotations -->
<context:annotation-config/>
<!-- Using annotation driven transaction facility -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Configuring a mail sender -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<!-- Configuring mail server properties -->
<property name="host" value="${mailserver.host}"/>
<property name="port" value="${mailserver.port}"/>
<property name="username" value="${mailserver.username}"/>
<property name="password" value="${mailserver.password}"/>
<!-- Other mail properties -->
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">${mail.transport.protocol}</prop>
<prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
<prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop>
<prop key="mail.debug">${mail.debug}</prop>
</props>
</property>
</bean>
<!-- Velocity email template used for sending email alerts -->
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<props>
<prop key="resource.loader">class</prop>
<prop key="class.resource.loader.class">org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader</prop>
</props>
</property>
</bean>
<!-- support for scheduled and asynchronous backgorund jobs -->
<task:annotation-driven/>
</beans>
//spitter-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: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
">
<import resource="spitter-servlet.xml"/>
<security:http auto-config="true" use-expressions="true">
<security:remember-me key="spitterKey" token-validity-seconds="86400"/>
<security:form-login login-page="/login" authentication-failure-url="/login?login_error=t"
login-processing-url="/static/j_spring_security_check"
default-target-url="/home"/>
<security:logout logout-url="/logout" logout-success-url="/login?logout=success"/>
<security:intercept-url pattern="/login" access="isAnonymous()"/>
<security:intercept-url pattern="/spitters" access="isAnonymous()"/>
<security:intercept-url pattern="/logout" access="isAuhenticated()"/>
<security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="spitterServiceImpl">
<security:password-encoder hash="md5"/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
//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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spitter-security.xml
</param-value>
</context-param>
<filter>
<description>Filter used to identify requests for PUT & DELETE requests as the case with RESTFul verbs</description>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<description>Spring security servlet filter delegates to spring managed security filter(Spring security filter)</description>
<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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>spitter</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<description>Handles static content</description>
<servlet-name>staticHandler</servlet-name>
<servlet-class>com.spitter.servlet.StaticServlet</servlet-class>
<load-on-startup>5</load-on-startup>
</servlet>
<servlet>
<servlet-name>SpitterServiceEndPoint</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spitter</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>staticHandler</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SpitterServiceEndPoint</servlet-name>
<url-pattern>/SpitterServiceEndPoint</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
I am using spring 3.0.2
My scheduled method is invoked twice..
am i making some mistake..?
please help me to figure it out..
Found in the documentation of spring :
Make sure that you are not initializing multiple instances of the same #Scheduled annotation class at runtime, unless you do want to schedule callbacks to each such instance. Related to this, make sure that you do not use #Configurable on bean classes which are annotated with #Scheduled and registered as regular Spring beans with the container: You would get double initialization otherwise, once through the container and once through the #Configurable aspect, with the consequence of each #Scheduled method being invoked twice.
Maybe this is the reason
It looks like your cron syntax is wrong - My guess is that you have typed in ? and * accidentally. You should change it to:
#Scheduled(cron="0 58 18 * SUN")
If you specify 6 parameters (like you had in your original syntax), cron expects the 6th element to be the year. SUN is a 'day of the week' parameter, and should be specified in 5th position, so cron is getting confused.