Why does the following Java Spring Security code throws "Bad Credential Exception"? - java

Following is the code and I have already inserted data in database using BCrypt password encoder. While inserting I did BCrypt in java code. I am adding Spring Security to my project. As a first stage, I have added BCrypt to my spring-security.xml and I try to log in and I debug the code and I see "Bad Credentials Exception"
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_2_5.xsd" version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml,
/WEB-INF/spring/appServlet/spring-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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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/spring-security.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>
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="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-3.0.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-4.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<tx:annotation-driven transaction-manager="transactionManager"/>
<b:bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
<security:authentication-manager >
<security:authentication-provider user-service-ref="personService">
<security:password-encoder ref="encoder"/>
</security:authentication-provider>
</security:authentication-manager>
<security:global-method-security secured-annotations="enabled"/>
<b:bean id="personDAO" class="com.cT.www.dao.PersonDAOImpl">
<b:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</b:bean>
<!-- For hashing and salting user passwords -->
<b:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<b:bean id="personService" class="com.cT.www.service.PersonServiceImpl">
<b:property name="personDAO" ref="personDAO"></b:property>
</b:bean>
<security:http use-expressions='true'>
<security:form-login login-page="/login" default-target-url="/loginSuccess"
authentication-failure-url="/home"
username-parameter="mobile_Number"
password-parameter="password"/>
<security:intercept-url pattern="/home" access="permitAll" />
<security:intercept-url pattern="/RankOption/**" access="hasRole('ROLE_ADMIN')" />
<security:logout logout-url="/logout"/>
</security:http>
<b:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<b:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<b:property name="url"
value="jdbc:mysql://121.0.0.1:3306/testDB" />
<b:property name="username" value="root" />
<b:property name="password" value="" />
</b:bean>
<!-- Form Validator -->
<b:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<b:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</b:bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<b:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<b:property name="dataSource" ref="dataSource" />
<b:property name="packagesToScan">
<b:list>
<b:value>com.cT.www.model</b:value>
</b:list>
</b:property>
<b:property name="hibernateProperties">
<b:props>
<b:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</b:prop>
<b:prop key="hibernate.show_sql">true</b:prop>
</b:props>
</b:property>
</b:bean>
<context:component-scan base-package="com.cT.www" />
<!-- 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 -->
<b:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<b:property name="prefix" value="/WEB-INF/views/" />
<b:property name="suffix" value=".jsp" />
</b:bean>
</b:beans>
PersonServiceImpl.java
package com.cT.www.service;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.cT.www.dao.PersonDAO;
import com.cT.www.model.Best_Option_Questions;
import com.cT.www.model.Options;
import com.cT.www.model.Person;
import com.cT.www.model.Questions;
import com.cT.www.model.Rank_Option_Questions;
import com.cT.www.model.Reset_Password;
import com.cT.www.model.UserSignUp;
import com.cT.www.model.UserVerification;
import com.cT.www.model.Yes_Or_No;
#Service
public class PersonServiceImpl implements PersonService, UserDetailsService {
private PersonDAO personDAO;
public void setPersonDAO(PersonDAO personDAO) {
this.personDAO = personDAO;
}
#Override
#Transactional
public List getMobile_Number_N_Password(String mobile_Number) {
// TODO Auto-generated method stub
return this.personDAO.getMobile_Number_N_Password(mobile_Number);
}
#Override
#Transactional
public UserDetails loadUserByUsername(String mobile_Number)
throws UsernameNotFoundException {
// TODO Auto-generated method stub
// return this.getMobile_Number_N_Password(Long.parseLong(mobile_Number));
List result = personDAO.getMobile_Number_N_Password(mobile_Number);
String existing_Password = null;
Boolean verification_Boolean = false;
if(result != null){
if(result.get(0) != null){
for(Iterator itr = result.iterator(); itr.hasNext();){
Object[] myResult = (Object[]) itr.next();
existing_Password = (String) myResult[0];
verification_Boolean = (Boolean) myResult[1];
}
}
}
if(result == null){
throw new UsernameNotFoundException("No user found with mobile number" + mobile_Number);
}
return new org.springframework.security.core.userdetails.User(mobile_Number,
existing_Password,true, true, true, true, getGrantedAuthorities());
}
private List<GrantedAuthority> getGrantedAuthorities(){
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("VERIFIED_USER"));
return authorities;
}
}

Related

Spring MVC + REST + AngularJs 404 Not Found

Facing problem in calling a REST Controller with Json. Getting 404 error. But not able to find the problem. The Controller is defined. No Spelling mistake.
P.S. To use REST do we need configuration in web.xml or servlet-config.xml .
I have jackson-databind and jax-rs in dependencies.
NewBie in Spring Angular . Need help.
I am trying to call '/addintoexp' controller File
File : expense.js
'use strict';
var addexp=angular.module('emsExpenseApp',[ ]);
addexp.controller('addExpCtrl',[ '$scope', '$http', '$location' ,function($scope,$http,$location){
console.log("Reached the Angular controller");
var vm=this;
vm.expense={};
vm.expense.expense_name="GROFERS MONTHLY";
// add-expense button implementation
vm.submit=function(){
console.log("Inside Submit Function");
console.log(vm.expense);
$http({
method: 'POST',
url: addintoexp,
data: vm.expense,
dataType: 'application/json',
headers: {'Content-Type': 'application/json'}
}).success(function(response) {
alert(' Success ');
console.dir(response);
//alert('Success');
// redirect path
//$location.path('dashboard/users');
}).error(function(response){
alert('Error');
});
}
}]);
File: ExpenseController.java
package com.ems.controller;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.ems.model.Expense;
import com.ems.model.User;
import com.sun.media.jfxmedia.logging.Logger;
/**
*
* #author Ankit
*
* In this controller , methods like add_expense, del_expense, view_expense, edit_expense
* all accordingly to the user_id
*
*
*
*/
#RestController
public class ExpenseController {
#RequestMapping(value="/add-exp", method=RequestMethod.GET)
public ModelAndView addExpense(){
ModelAndView m=new ModelAndView("add-expense");
return m;
}
/*
#RequestMapping(value="/addintoexp", method=RequestMethod.POST)
public String addExpense(#RequestParam("exp-name") String expname,
#RequestParam("exp-desc") String expdesc,
#RequestParam("exp-amount") String expamount,
#RequestParam("exp-date") String expdate,
#RequestParam("exp-notes") String expnotes,
#RequestParam("exp-category") String expcategory
){
System.out.println(
" Expense Name : "+expname +
" Expense Desc : "+expdesc +
" Expense Amount : " +expamount+
" Expense Date : "+expdate+
" Expense Notes : "+expnotes+
" Expense Category : "+expcategory
);
return "redirect:/add-exp.html";
}
*/
//404 Error getting for this controller
#RequestMapping(value = "/addintoexp",method = RequestMethod.POST,headers="Accept=application/json")
public ResponseEntity<Void> addexpenser(#RequestBody Expense e){
System.out.println("Inside the Adding Exp Controller. Hurrah. REST is working");
System.out.println(e.getExpense_name());
System.out.println(e.getExpense_category());
System.out.println(e.getExpense_desc());
HttpHeaders header = new HttpHeaders();
return new ResponseEntity<Void>(header,HttpStatus.CREATED);
}
//Rest API Add Expense
}
File: 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"
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_3_0.xsd"
id="WebApp_ID" version="3.0">
<servlet>
<servlet-name>expTrackerServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/servlet-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>expTrackerServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<display-name>Archetype Created Web Application</display-name>
</web-app>
File: Servlet-Config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:resources location="/static" mapping="/static/**"/>
<mvc:annotation-driven/>
<context:component-scan base-package="com.ems"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="expenseDaoImpl" class="com.ems.dao.ExpenseDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="loginDaoImpl" class="com.ems.dao.LoginDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/exms" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>

How to secure a Spring soap service with certificates

I managed to create a soap server and client that requires a username and password to call functions. The following code shows how i've done this
Client:
package hello;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor;
import org.springframework.ws.soap.security.xwss.callback.SpringUsernamePasswordCallbackHandler;
#Configuration
public class SoftlayerConfiguration {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("be.elision.soap.cloud");
return marshaller;
}
#Bean
public SoftlayerClient softlayerClient(Jaxb2Marshaller marshaller) {
SoftlayerClient client = new SoftlayerClient();
client.setDefaultUri("http://192.168.137.107:8080/ws");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
client.setInterceptors(new ClientInterceptor[]{securityInterceptor()});
return client;
}
#Bean
XwsSecurityInterceptor securityInterceptor() {
XwsSecurityInterceptor securityInterceptor = new XwsSecurityInterceptor();
securityInterceptor.setSecureRequest(true);
securityInterceptor.setValidateRequest(true);
securityInterceptor.setCallbackHandler(callbackHandler());
securityInterceptor.setPolicyConfiguration(new ClassPathResource("securityPolicy.xml"));
return securityInterceptor;
}
#Bean
SpringUsernamePasswordCallbackHandler callbackHandler() {
SecurityContextHolder.setContext(new SecurityContextImpl());
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("user", "password"));
return new SpringUsernamePasswordCallbackHandler();
}
}
Server:
package be.elision.main;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor;
import org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor;
import org.springframework.ws.soap.security.xwss.callback.SimplePasswordValidationCallbackHandler;
import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(
ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "devices")
public DefaultWsdl11Definition defaultWsdl11Definition(
XsdSchema devicesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("DevicesPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://elision.be/soap/cloud");
wsdl11Definition.setSchema(devicesSchema);
return wsdl11Definition;
}
// toevoegen van xsd aan bean
#Bean
public XsdSchema devicesSchema() {
return new SimpleXsdSchema(new ClassPathResource("devices.xsd"));
}
#Bean
XwsSecurityInterceptor securityInterceptor() {
XwsSecurityInterceptor securityInterceptor = new XwsSecurityInterceptor();
securityInterceptor.setCallbackHandler(callbackHandler());
securityInterceptor.setPolicyConfiguration(new ClassPathResource(
"securityPolicy.xml"));
return securityInterceptor;
}
#Bean
SimplePasswordValidationCallbackHandler callbackHandler() {
SimplePasswordValidationCallbackHandler callbackHandler = new SimplePasswordValidationCallbackHandler();
callbackHandler.setUsersMap(Collections
.singletonMap("user", "password"));
return callbackHandler;
}
#Bean
PayloadLoggingInterceptor payloadLoggingInterceptor() {
return new PayloadLoggingInterceptor();
}
#Bean
PayloadValidatingInterceptor payloadValidatingInterceptor() {
final PayloadValidatingInterceptor payloadValidatingInterceptor = new PayloadValidatingInterceptor();
payloadValidatingInterceptor.setSchema(new ClassPathResource(
"devices.xsd"));
return payloadValidatingInterceptor;
}
#Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(payloadLoggingInterceptor());
interceptors.add(payloadValidatingInterceptor());
interceptors.add(securityInterceptor());
}
}
Security policy:
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:UsernameToken digestPassword="false" useNonce="false" />
</xwss:SecurityConfiguration>
But now i want to replace this username and password authentication with a certificate. I prefere not to do this in xml, but rather implement this in my existing code as shown above.
We finaly figured this out some months ago, from what I remember our configuration looked like this.
add this to your web.xml
<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>
this needs to be present in your mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd">
<context:component-scan base-package="com.yourpackage" />
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory" />
<property name="defaultUri"
value="${backend.ip}devices" />
<property name="interceptors">
<list>
<ref local="xwsSecurityInterceptor" />
</list>
</property>
</bean>
<bean id="xwsSecurityInterceptor"
class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<property name="policyConfiguration" value="/WEB-INF/securityPolicy.xml" />
<property name="callbackHandlers">
<list>
<ref bean="keyStoreHandler" />
</list>
</property>
</bean>
<bean id="keyStore"
class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
<property name="password" value="yourpassword" />
<property name="location" value="/WEB-INF/yourkeystore.jks" />
</bean>
<bean id="keyStoreHandler"
class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
<property name="keyStore" ref="keyStore" />
<property name="privateKeyPassword" value="yourpassword" />
<property name="defaultAlias" value="client" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- LOAD PROPERTIES -->
<context:property-placeholder
location="WEB-INF/config.properties"
ignore-unresolvable="true" />
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
</beans>
The jks file is a java keystore file wich holds your certificate.
SecurityPolicy.xml
<xwss:SecurityConfiguration dumpMessages="true" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:Sign includeTimestamp="true">
<xwss:X509Token certificateAlias="yourcertificatealias" />
</xwss:Sign>
</xwss:SecurityConfiguration>
This is all done using the xws-security library from oracle, you need the following dependency for this.
<dependency>
<groupId>com.sun.xml.wss</groupId>
<artifactId>xws-security</artifactId>
<version>3.0</version>
<exclusions>
<exclusion>
<groupId>javax.xml.crypto</groupId>
<artifactId>xmldsig</artifactId>
</exclusion>
</exclusions>
</dependency>
We finnaly got this working after we found some good explanation about certificate authentication in this awesome book!
'Spring Web Services 2 Cookbook by Hamidreza Sattari'
If you have any further questions regarding this implementation then just ask away! :d

Spring security using http authentication based on xml

I am trying to implement a spring security in my project my requirements are
First user will login with url that will generate a secuirty code -
http://localhost:8181/SpringSecurity/login
After successfully loggedIn I hit secuired API call like -
http://localhost:8181/SpringSecurity/admin with secured key generated by login method
I am using crome postman to hit APIs
Although I am loggedIn with a user having ROLE_ADMIN but still it is not allow me to access secured APIs
my web.xml is
<?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>
<!-- 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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/spring-security.xml
</param-value>
</context-param>
<!-- 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>
servlet-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" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<mvc:annotation-driven/>
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.ha.**"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="savedRequestAwareAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="targetUrlParameter" value="targetUrl" />
</bean>
<context:component-scan base-package="com.ha.**" />
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="prefixJson" value="false" />
<property name="supportedMediaTypes" value="application/json" />
</bean>
<import resource="../spring-security.xml"/>
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"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<security:global-method-security secured-annotations="enabled"/>
<http auto-config="true">
<intercept-url pattern="/admin**" access="ROLE_ADMIN" />
<custom-filter ref="tokenProcessingFilter" after="FORM_LOGIN_FILTER" />
</http>
<beans:bean
class="com.ha.security.AuthenticationTokenAndSessionProcessingFilter"
id="tokenProcessingFilter">
<beans:constructor-arg name="principal" value="ANONYMOUS" />
<beans:constructor-arg name="authority" value="anonymousUser" />
<beans:constructor-arg name="tokenStore" ref="inMemoryTokenStore" />
</beans:bean>
<beans:bean class="com.ha.security.InMemoryTokenStore" id="inMemoryTokenStore" />
<authentication-manager>
<authentication-provider>
<user-service>
<user name="hr" password="123456" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
Controller file is
package com.ha.security;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ha.model.UserEntity;
import com.ha.services.IUserService;
/**
* Handles requests for the application home page.
*/
#Controller
public class HomeController {
#Autowired
private InMemoryTokenStore tokenStore;
#Autowired
IUserService userServices;
/* #RequestMapping(value = { "/" }, method = RequestMethod.GET)
public String welcomePage() {
return "index";
} */
#RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
#Secured("ROLE_ADMIN")
public #ResponseBody String defaultPage() {
List<UserEntity> userEntity = userServices.getUsersList();
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
return gson.toJson(userEntity);
}
#RequestMapping(value = "/admin", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
#ResponseStatus(value = HttpStatus.OK)
#ResponseBody
public ResponseDto adminPage() {
return new ResponseDto("Can Access Admin");
}
#RequestMapping(value = "/login", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
#ResponseStatus(value = HttpStatus.OK)
#ResponseBody
public ResponseDto login(#RequestBody UserLoginDto loginDto) {
String userName = loginDto.getUserName();
String password = loginDto.getPassword();
if (StringUtils.hasText(userName) && StringUtils.hasText(password)
&& userServices.validateAdminUser(loginDto)) {
ArrayList<GrantedAuthority> objAuthorities = new ArrayList<GrantedAuthority>();
SimpleGrantedAuthority objAuthority = new SimpleGrantedAuthority(
"ROLE_ADMIN");
objAuthorities.add(objAuthority);
User user = new User(userName, password, objAuthorities);
return new ResponseDto(this.tokenStore.generateAccessToken(user));
} else {
return new ResponseDto("Not Valid User");
}
}
}
AuthenticationTokenAndSessionProcessingFilter
package com.ha.security;
import java.io.IOException;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;
public class AuthenticationTokenAndSessionProcessingFilter extends
GenericFilterBean {
private final InMemoryTokenStore tokenStore;
private final Object principal;
private final List<GrantedAuthority> authorities;
public AuthenticationTokenAndSessionProcessingFilter(
InMemoryTokenStore tokenStore, String authority, String principal) {
this.tokenStore = tokenStore;
this.principal = principal;
this.authorities = AuthorityUtils.createAuthorityList(authority);
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
throw new RuntimeException("Expecting a HTTP request");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
String authToken = null;
UserDetails objUserDetails = null;
if (StringUtils.hasText(httpRequest.getHeader("Authorization"))) {
authToken = httpRequest.getHeader("Authorization");
objUserDetails = this.tokenStore
.readAccessToken(authToken);
}
setAuthentication(objUserDetails, httpRequest);
chain.doFilter(request, response);
}
private void setAuthentication(UserDetails objUserDetails,
HttpServletRequest request) {
UsernamePasswordAuthenticationToken authentication = null;
if (null != objUserDetails) {
authentication = new UsernamePasswordAuthenticationToken(
objUserDetails, null, objUserDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource()
.buildDetails(request));
SecurityContextHolder.getContext()
.setAuthentication(authentication);
} else {
authentication = new UsernamePasswordAuthenticationToken(
this.principal, null, this.authorities);
SecurityContextHolder.getContext()
.setAuthentication(authentication);
}
}
}
I believe you need to use hasRole method
<intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />
And also I noticed that you have only one user in your users list with role "ROLE_USER" hope you have added the admin user as well.
Thanks for your support, Problem get solved now and It was with importing style of security action. I was importing securty xml file multiple times
I had import securty in
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/spring-security.xml
</param-value>
</context-param>
as well as in spring-context.xml file
<import resource="../spring-security.xml"/>
due to that multiple instances creted of inMemoryTokenStore and while validating it checking user token with different one.
After removed entry from spring-context.xml and adding following qualifer in HomeController my code is working fine
#Qualifier("inMemoryTokenStore")
private InMemoryTokenStore tokenStore;
Thanks evertybuddy....:)

Getter returning null SessionFactory

I am trying to develop Springs-Hibernate login application with springs security. When i am trying to retrieve users from DB with Hibernate. I have proper working Springs-Hibernate Configuration. Everytime getter returning sessionFactory null (I am printing address in getSessionFactory method). I have one method getLoginDetails() which is working perfectly if i am not invoking method at login time (Checked with just simple anchor tag), but when i am logging in its not working. Here is my code:
Springs-security.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: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/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" use-expressions="true" access-denied-page="/auth/denied" >
<security:intercept-url pattern="/auth/login" access="permitAll"/>
<security:intercept-url pattern="/main/admin" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/main/common" access="hasRole('ROLE_USER')"/>
<security:form-login
login-page="/auth/login"
authentication-failure-url="/auth/hi"
authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
<security:logout
invalidate-session="true"
logout-success-url="/loggedout" />
</security:http>
<!-- A custom service where Spring will retrieve users and their corresponding access levels -->
<bean id="customUserDetailsService" class="com.springs.service.CustomUserDetailsService"/>
<!--A service where spring will redirect to proper view after successfull login-->
<bean id="myAuthenticationSuccessHandler" class="com.springs.controller.MySimpleUrlAuthenticationSuccessHandler" />
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
</security:authentication-provider>
</security:authentication-manager>
</beans>
ApplicationContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="acquireIncrement" value="${c3p0.acquireIncrement}" />
<property name="minPoolSize" value="${c3p0.minPoolSize}" />
<property name="maxPoolSize" value="${c3p0.maxPoolSize}" />
<property name="maxIdleTime" value="${c3p0.maxIdleTime}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="DataSource"/>
<property name="packagesToScan" value="com.hibernate.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-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/task http://www.springframework.org/schema/task/spring-task-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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Scan only for #Controllers -->
<context:component-scan base-package="com.springs">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven />
<tx:annotation-driven/>
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
CustomerUserDetailsService.java
package com.springs.service;
import com.hibernate.model.DbUser;
import com.springs.dao.UserDAO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
#Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserDAO userDAO ;
#Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
UserDetails user = null;
try {
DbUser dbUser;
userDAO=new UserDAO();
dbUser = userDAO.getLoginDetails(username);
user = new User(
dbUser.getUsername(),
dbUser.getPassword().toLowerCase(),
true,
true,
true,
true,
getAuthorities(dbUser.getAccess()));
} catch (Exception e) {
System.out.println("\n\n\n\n\n");
e.printStackTrace();
throw new UsernameNotFoundException("Error in retrieving user");
}
return user;
}
public Collection<SimpleGrantedAuthority> getAuthorities(Integer access) {
List<SimpleGrantedAuthority> authList = new ArrayList<SimpleGrantedAuthority>(2);
if (access.compareTo(1) == 0) {
authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
} else {
authList.add(new SimpleGrantedAuthority("ROLE_USER"));
}
return authList;
}
}
UserDAO.java
#Repository
public class UserDAO {
#Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
System.out.println("session factory: "+sessionFactory);
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public int getdata(String username) {
String hql = "select count(*) from Userdetails";
Userdetails u = (Userdetails) getSessionFactory().openSession().get(Userdetails.class, username);
System.out.println(u.getName());
Long l = (Long) getSessionFactory().openSession().createQuery(hql).uniqueResult();
return l.intValue();
}
public DbUser getLoginDetails(String username) {
DbUser user = new DbUser();
Userdetails u = (Userdetails) getSessionFactory().openSession().get(Userdetails.class, username);
user.setUsername(u.getName());
user.setPassword(u.getPassword());
user.getAccess();
Set userroles = u.getUserroles();
Iterator it = userroles.iterator();
while (it.hasNext()) {
Userrole ux=(Userrole) it.next();
user.setAccess(ux.getRollid());
}
System.out.println("accss is: "+user.getAccess());
System.out.println("username is: "+user.getUsername());
System.out.println("pw is "+user.getPassword());
return user;
}
}
message in server log :
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/SpringSecurity] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.springs.dao.UserDAO.getdata(UserDAO.java:42)
at com.springs.controller.testController.getUser(testController.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
I am not able to figure out sessionFactory is null if i am using it at Login activity otherwise its not null. First I was missing tx annotation in xml which i added later for #Transactional annotation. How can i solve this?
Sorry, I do not see the problem. But I'd like to attache similar files from myy sample project regarding to security. I hope it helps you:
applicationContext-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.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
">
<!-- HTTP security configurations -->
<http auto-config="true" use-expressions="true">
<form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
<logout logout-url="/resources/j_spring_security_logout" />
<!-- Configure these elements to secure URIs in your application -->
<intercept-url pattern="/login-user/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/choices/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/member/**" access="isAuthenticated()" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/login/**" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
</http>
<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager">
<!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
<authentication-provider>
<password-encoder hash="sha-256" />
<user-service>
<user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN" />
<user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
<context:spring-configured/>
<context:component-scan base-package="org.sample.login">
<context:exclude-filter expression=".*_Roo_.*" type="regex"/>
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="1800000"/>
<property name="numTestsPerEvictionRun" value="3"/>
<property name="minEvictableIdleTimeMillis" value="1800000"/>
<property name="validationQuery" value="SELECT version();"/>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
MyUser.java:
package org.sample.login.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
#Table(name = "my_user")
#Entity
public class MyUser {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Version
#Column(name = "version")
private Integer version;
/**
*/
#NotNull
#Size(min = 6)
private String name;
/**
*/
#NotNull
#Size(min = 6)
private String password;
#Override
public String toString() {
return "MyUser [name=" + name + ", password=" + password + "]";
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getVersion() {
return this.version;
}
public void setVersion(Integer version) {
this.version = version;
}
}

managed bean field is null when invoke bean method primefaces jsf

I am developing a primefaces - spring framework application but i have a big problem with my beans
i'm using spring annotations in java code to discover my beans, services, or component
but the problem is when i start jboss 7.1 AS and the beans are created i can see that my bean ListUsersBean
is created succesfully and the autowired setters are set successfully, but after when i try to invoke a test() method
from jsf page the autowired attributes are null.
I dont know what is happening
thanks a lot if anyone may help me
i'm using
spring-framework 3.2.2
JBOSS AS 7.1
primefaces 3.5
this is my bean
package edu.unbosque.beans;
import java.io.Serializable;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ManagedProperty;
import edu.unbosque.model.User;
import edu.unbosque.services.IUserService;
import edu.unbosque.services.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
#Component
#ManagedBean
#SessionScoped
public class ListUsersBean implements Serializable{
/**
* Acceso A Datos De Usuario
*/
private IUserService userService;
private TestService testService;
/**
* Listado De Usuarios
*/
private List<User> usersList;
/**
* Usuario Seleccionado
*/
private User selectedUser;
/**
* Carga Los Usuarios
*/
private void populateUsers(){
this.usersList = this.userService.getUsers();
}
public IUserService getUserService() {
return userService;
}
#Autowired(required = true)
#Qualifier("userServiceImpl")
public void setUserService(IUserService userService) {
this.userService = userService;
}
public List<User> getUsersList() {
return usersList;
}
public void setUsersList(List<User> usersList) {
this.usersList = usersList;
}
public User getSelectedUser() {
return selectedUser;
}
public void setSelectedUser(User selectedUser) {
this.selectedUser = selectedUser;
}
public TestService getTestService() {
return testService;
}
#Autowired
public void setTestService(TestService testService) {
this.testService = testService;
}
public void test(){
this.testService = this.getTestService();
int i = 1;
i = i + 2;
}
}
this is my service
package edu.unbosque.services;
import java.util.List;
import javax.faces.bean.ManagedProperty;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import edu.unbosque.*;
import edu.unbosque.dao.UserDao;
import edu.unbosque.model.User;
import javax.inject.Named;
#Named("userServiceImpl")
public class UserServiceImpl implements IUserService{
#Autowired
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return (UserDetails) userDao.getUserByUserName(username);
}
#Override
public List<User> getUsers() {
return getUserDao().getUsers();
}
}
config files
faces-config.xml
*
<faces-config 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-facesconfig_2_0.xsd"
version="2.0">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
<lifecycle>
<phase-listener>edu.unbosque.listeners.LoginPhaseListener</phase-listener>
</lifecycle>
</faces-config>
*
spring-database.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:annotation-config />
<context:component-scan base-package="edu.unbosque.model" />
<context:component-scan base-package="edu.unbosque.dao" />
<context:component-scan base-package="edu.unbosque.services" />
<context:component-scan base-package="edu.unbosque.beans" />
<context:property-placeholder location="classpath:jdbc.properties" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager" />
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>edu.unbosque.model.User</value>
<value>edu.unbosque.model.Authority</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>
web.xml
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml,
/WEB-INF/spring-database.xml
</param-value>
</context-param>
<display-name>Semilleros Universidad El Bosque</display-name>
<!-- Change to "Production" when you are ready to deploy -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<!-- Welcome page -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- JSF mapping -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map these files with JSF -->
<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>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>bootstrap</param-value>
</context-param>
<!-- 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>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
</web-app>
The problem is you are mixing up jsf, CDI and spring annotations. Use #Component in your class UserServiceImpl. Because if you use #Named, the created bean's life cycle will be managed by CDI, because its a CDi annotation. So as you are using #Autowired annotation to inject the bean, which is unknown to Spring, will get null. So as you are using #Autowired while injecting the bean, the injecting bean must be in spring managed context and to do that you should have use #Component. For further reading you can see this nice tutorial.

Categories

Resources