I was trying to convert the following spring security java configuration to xml configuration;
Java config;
package com.careapple.webservice.security.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.careapple.webservice.security.filter.AuthenticationTokenFilter;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#EnableTransactionManagement
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
#Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public AuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
AuthenticationTokenFilter authenticationTokenFilter = new AuthenticationTokenFilter();
authenticationTokenFilter.setAuthenticationManager(super.authenticationManagerBean());
return authenticationTokenFilter;
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated();
// Custom JWT based authentication
httpSecurity
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
}
Converted xml configuration; spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<bean:beans
xmlns:bean="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<global-method-security secured-annotations="enabled"/>
<http realm="Protected API"
create-session="stateless"
entry-point-ref="authenticationEntryPoint"
authentication-manager-ref="authenticationManager">
<csrf disabled="true"/>
<custom-filter ref="authenticationTokenFilter" position="FORM_LOGIN_FILTER"/>
<intercept-url pattern="/login/**" access="permitAll"/>
<intercept-url pattern="/" access="isFullyAuthenticated()"/>
</http>
<bean:bean id="authenticationEntryPoint" class="com.careapple.webservice.security.EntryPointUnauthorizedHandler"/>
<bean:bean id="userDetailService" class="com.careapple.webservice.security.service.UserDetailsServiceImpl"/>
<bean:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<authentication-manager id="authenticationManager">
<authentication-provider user-service-ref="userDetailService">
<password-encoder ref="bcryptEncoder"></password-encoder>
</authentication-provider>
</authentication-manager>
<bean:bean id="authenticationTokenFilter" class="com.careapple.webservice.security.filter.AuthenticationTokenFilter"
c:authenticationManager-ref="authenticationManager"/>
</bean:beans>
I'm new to spring security, first thing i want is, have i converted the java config to xml correctly. Or have i missed anything.
Next up, if i run the application with this xml file i'm getting the following error;
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: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'authenticationTokenFilter' while setting constructor argument with key [3]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authenticationTokenFilter' defined in ServletContext resource [/WEB-INF/spring-security.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)
Where, authenticationTokenFilter is a custom filter that i'm using and it implements UsernamePasswordAuthenticationFilter of spring.
This 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"
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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>authenticationTokenFilter</filter-name>
<filter-class>com.careapple.webservice.security.filter.AuthenticationTokenFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>authenticationTokenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
I want too things now,
1. Whether all my configuration xml files are correct.
2. If so how to rectify the exception i'm getting.
Please give your suggestions, i'm struggling with this for a long time. I referred all the related stackoverflow question but i was not able to find a solution from them.
Edit:
This is my AuthenticationTokenFilter;
package com.careapple.webservice.security.filter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.careapple.webservice.security.TokenUtils;
import com.careapple.webservice.util.AppConstant;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class AuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter {
#Autowired
private TokenUtils tokenUtils;
#Autowired
private UserDetailsService userDetailsService;
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException{
tokenUtils = WebApplicationContextUtils
.getRequiredWebApplicationContext(this.getServletContext())
.getBean(TokenUtils.class);
userDetailsService = WebApplicationContextUtils
.getRequiredWebApplicationContext(this.getServletContext())
.getBean(UserDetailsService.class);
HttpServletResponse resp = (HttpServletResponse) response;
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
resp.setHeader("Access-Control-Max-Age", "3600");
resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, " + AppConstant.tokenHeader);
HttpServletRequest httpRequest = (HttpServletRequest) request;
String authToken = httpRequest.getHeader(AppConstant.tokenHeader);
System.out.println("Token: " + authToken);
String username = this.tokenUtils.getUsernameFromToken(authToken);
System.out.println("Username: " + username);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
System.out.println("inside first if");
if (this.tokenUtils.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
try {
chain.doFilter(request, response);
} catch (Exception e) {
Map<String, String> tokenExpired = new HashMap<>();
tokenExpired.put("TokenExpired", "Authentication token expired, please login again");
resp.setContentType("application/json");
resp.setStatus(HttpStatus.FORBIDDEN.value());
resp.getWriter().write(convertObjectToJson(tokenExpired));
}
}
public String convertObjectToJson(Object object) throws JsonProcessingException {
if (object == null) {
return null;
}
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
}
}
Your custom authentification filter needs to be defined only on the spring-security.xml file, looking at it, it should be fine.
On your web.xml, you need to remove your filter (it's a Spring Security filter not a JavaEE filter) and add the spring security filter. The error message from Spring is that it cannot find the Spring Security filter and thus refusing the parse the pring-security.xml file.
So remove your filter from web.xml and add the spring security with these lines and all should be fine
<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>
Regards,
Loïc
Related
I am trying to implement spring security in restweb service.
I am always getting "Entering commence due to failed Authentication" message. It is not going in CustomAuthenticationProvider.java. My code returns me from CustomEntryPoint. I think there's a misconfiguration.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:web="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value> WEB-INF/security-config.xml
</param-value>
</context-param>
<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/security-config.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>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- <welcome-file-list>
<welcome-file>/WEB-INF/index.jsp</welcome-file>
</welcome-file-list> -->
<!-- Tag Libary -->
</web-app>
Spring security file
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<sec:http entry-point-ref="customEntryPoint" use-expressions="true">
<sec:custom-filter ref="authenticationFilter"
before="PRE_AUTH_FILTER" />
<sec:intercept-url pattern="/**"
access="hasAuthority('AUTH_USER')" />
<sec:logout delete-cookies="JSESSIONID" />
<sec:csrf disabled="true" />
</sec:http>
<context:component-scan base-package="org.arpit.java2blog" />
<sec:authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</sec:authentication-manager>
<!-- <context:component-scan base-package="org.arpit.java2blog" /> -->
<beans:bean id="authenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="postOnly" value="false" />
<beans:property name="authenticationSuccessHandler" ref="customSuccessHandler" />
</beans:bean>
<beans:bean id="customSuccessHandler" class="org.arpit.java2blog.controller.CustomSuccessHandler" />
<beans:bean id="customAuthenticationProvider" class="org.arpit.java2blog.controller.CustomAuthenticationProvider" />
</beans:beans>
Class files
package org.arpit.java2blog.controller;
import java.util.Collections;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Override
public Authentication authenticate(Authentication auth)
throws AuthenticationException {
String username = auth.getName();
String password = auth.getCredentials()
.toString();
System.out.println(username +"::"+password);
if ("user".equals(username) && "pass".equals(password)) {
return new UsernamePasswordAuthenticationToken
(username, password, Collections.emptyList());
} else {
throw new
BadCredentialsException("External system authentication failed");
}
}
#Override
public boolean supports(Class<?> auth) {
return auth.equals(UsernamePasswordAuthenticationToken.class);
}
}
package org.arpit.java2blog.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
#Component
public class CustomEntryPoint implements AuthenticationEntryPoint
{
#Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException
{
System.out.println("Entering commence due to failed Authentication");
response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized Access!" );
}
}
package org.arpit.java2blog.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
public class CustomSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler
{
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException
{
System.out.println("authentication successful!");
}
}
Looks like you are braking filter chain with that customEntryPoint because it is run before any authentification and since it sends response.sendError, chain if broken. So, remove that entry point bean.
You can register custom success and failure handlers by adding this inside sec:http secition:
<sec:form-login
authentication-failure-handler-ref="authenticationFailedHandler"
authentication-success-handler-ref="authenticationSuccessHandler" />
where success handler is:
#Component
public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
// success
}
}
and failed handler:
#Component
public class AuthenticationFailedHandler extends SimpleUrlAuthenticationFailureHandler {
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
// super.onAuthenticationFailure(request, response, exception);
// failed
}
}
Hope it helps.
I am writing test to check the working of spring MVC interceptor.
I have my working controller for which i have introduced interceptor code.
Everything is working fine except interceptor is not being executed.
No error nothing.
Interceptor:
package com.neha.javabrains;
import java.util.Calendar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
#Component
public class TimeBasedInterceptor extends HandlerInterceptorAdapter{
private int openingTime=9;
private int closingTime=18;
public int getOpeningTime() {
return openingTime;
}
public void setOpeningTime(int openingTime) {
this.openingTime = openingTime;
}
public int getClosingTime() {
return closingTime;
}
public void setClosingTime(int closingTime) {
this.closingTime = closingTime;
}
public boolean preHandle(HttpServletRequest httpRequest,HttpServletResponse httpResponse) throws Exception
{
System.out.println("here in interceptor");
Calendar cal=Calendar.getInstance();
int hour=cal.HOUR_OF_DAY;
if(openingTime<=hour && hour<closingTime)
{
return true;
}
httpResponse.sendRedirect("http://localhost:8080/SpringWebProject/outsideHours.html");
return false;
}
}
Application Context entry:
<context:component-scan base-package="com.neha.javabrains" />
<context:annotation-config/>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<mvc:resources mapping="/resources/**" location="/resources/" />
<tx:annotation-driven transaction-manager="txManager"/>
<aop:aspectj-autoproxy />
<mvc:interceptors>
<bean class="com.neha.javabrains.TimeBasedInterceptor">
</bean>
</mvc:interceptors>
Controller:
package com.neha.javabrains;
import java.util.Locale;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.MessageSource;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class LoginController {
public LoginService loginService;
#Autowired
#Qualifier("loginFormValidator")
public Validator validator;
#Autowired
public MessageSource messageSource;
#InitBinder
private void initBinder(WebDataBinder binder) {
binder.setValidator(validator);
}
#Autowired
private Environment environment;
#RequestMapping("/")
public String doLogin(ModelMap modelMap)
{
System.out.println("doLogin" +loginService);
String message=messageSource.getMessage("message", null, "default", Locale.UK);
System.out.println("Message is:" + message);
LoginForm loginForm=new LoginForm();
modelMap.put("loginForm",loginForm);
return "login";
}
public void printData()
{
System.out.println("just to test aspect programming");
}
#RequestMapping("/login")
public String verifyLogin(#Valid #ModelAttribute("loginForm") LoginForm loginForm,BindingResult bindingResult)
{
if(bindingResult.hasErrors())
{
System.out.println("here in error" + bindingResult.getAllErrors().get(0));
return "login";
}
loginService.verifyLogin(loginForm);
LoginForm loginFrm=new LoginForm();
loginFrm.setUsername(loginForm.getUsername());
loginFrm.setPassword(loginForm.getPassword());
ModelAndView mav=new ModelAndView();
mav.addObject("loginForm", loginFrm);
return "result";
}
#RequestMapping("/addUser")
public String addUser(#ModelAttribute("LoginForm") LoginForm loginForm,LoginForm loginFrm)
{
System.out.println("In add User");
loginService.addUser(loginForm);
loginFrm.setUsername(loginForm.getUsername());
loginFrm.setPassword(loginForm.getPassword());
ModelAndView mav=new ModelAndView();
mav.addObject("LoginForm", loginFrm);
return "result";
}
public LoginService getLoginService() {
return loginService;
}
#Autowired
#Required
public void setLoginService(LoginService loginService) {
this.loginService = loginService;
System.out.println("i was called" + loginService);
}
public Environment getEnvironment() {
return environment;
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public MessageSource getMessageSource() {
return messageSource;
}
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
}
Web.xml entry is:
<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">
<servlet>
<servlet-name>Neha</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>Neha</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
Can anyone please help.....
You seem to have missed the path where you want to apply the interceptor.
Try this
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" /> <!-- Specify here what all path you want to intercept -->
<bean class="com.neha.javabrains.TimeBasedInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
Hope this helps.
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.phoenix.config.ApplicationConfig</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.phoenix.config.MvcConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>authenticationFilter</filter-name>
<filter-class>
com.phoenix.authentication.AuthenticationFilter
</filter-class>
</filter>
<filter>
<filter-name>authorizationFilter</filter-name>
<filter-class>
com.phoenix.authentication.AuthorizationFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>authenticationFilter</filter-name>
<url-pattern>/login/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>authorizationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/ErrorHandler</location>
</error-page>
<servlet>
<servlet-name>PhoenixExceptionHandler</servlet-name>
<servlet-class>com.phoenix.authentication.PhoenixExceptionHandler</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PhoenixExceptionHandler</servlet-name>
<url-pattern>/ErrorHandler</url-pattern>
</servlet-mapping>
</web-app>
context configuration class:
package com.phoenix.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#ComponentScan({ "com.phoenix" })
#PropertySource(value = { "classpath:hibernate.properties" })
public class ApplicationConfig {
#Autowired
private Environment environment;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.phoenix.data.entity");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
#Bean
public HttpHeaders responseHeader(){
HttpHeaders responseTypeHeader = new HttpHeaders();
responseTypeHeader.add("Content-Type", "application/json; charset=utf-8");
return responseTypeHeader;
}
}
dispatcher configuration class:
package com.phoenix.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.phoenix")
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/WEB-INF/resources/");
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
}
filter class:
package com.phoenix.authentication;
import java.io.IOException;
import java.util.List;
import javax.persistence.Query;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.phoenix.data.entity.UserInfo;
public class AuthenticationFilter implements Filter {
#Autowired
SessionFactory sessionFactory;
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if(httpRequest.getParameter("username") != null
&& httpRequest.getParameter("password") != null)
{
String username = httpRequest.getParameter("username");
String password = httpRequest.getParameter("password");
boolean rememberMe = false;
if(httpRequest.getParameter("rememberMe")!= null)
rememberMe = httpRequest.getParameter("rememberMe").equals("on");
UserInfo user = getUserInfo(username, password);
System.out.print(user+"\n"+rememberMe);
}
chain.doFilter(request, response);
}
#Override
public void init(FilterConfig arg0) throws ServletException {
}
public UserInfo getUserInfo(String username, String password)
{
UserInfo user=null;
Session session=sessionFactory.getCurrentSession();
Query query = session.createQuery("FROM UserInfo WHERE"
+ " UserInfo.username = :xusername AND UserInfo.password = :xpassword");
query.setParameter("xusername",username);
query.setParameter("xpassword",password);
List list=query.getResultList();
if (list.size()>0)
user=(UserInfo)list.get(0);
return user;
}
}
exception :
Aug 13, 2016 5:02:39 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/phoenix] threw exception
java.lang.NullPointerException
at com.phoenix.authentication.AuthenticationFilter.getUserInfo(AuthenticationFilter.java:65)
at com.phoenix.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:50)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
I did a little search and The solution org.springframework.web.filter.DelegatingFilterProxy came. But this solution is a little vague to me. I am grateful if explain.
You can't use #Autowired in your AuthenticationFilter because it is not instantiated in Spring Container. It is instantiated in the Web Application Container so sessionFactory will always be null thus the NullPointerException.
But you can get the WebApplicationContext inside of a Filter by using WebApplicationContextUtils.getRequiredWebApplicationContext which is provided by Spring.
So with the modified AuthenticationFilter.init method as below, your filter should work.
public class AuthenticationFilter implements Filter {
SessionFactory sessionFactory;
#Override
public void destroy() {
this.sessionFactory.close();
this.sessionFactory = null;
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if(httpRequest.getParameter("username") != null
&& httpRequest.getParameter("password") != null)
{
String username = httpRequest.getParameter("username");
String password = httpRequest.getParameter("password");
boolean rememberMe = false;
if(httpRequest.getParameter("rememberMe")!= null)
rememberMe = httpRequest.getParameter("rememberMe").equals("on");
UserInfo user = getUserInfo(username, password);
System.out.print(user+"\n"+rememberMe);
}
chain.doFilter(request, response);
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext());
this.sessionFactory = ctx.getBean(SessionFactory.class);
}
public UserInfo getUserInfo(String username, String password)
{
UserInfo user=null;
Session session=sessionFactory.getCurrentSession();
Query query = session.createQuery("FROM UserInfo WHERE"
+ " UserInfo.username = :xusername AND UserInfo.password = :xpassword");
query.setParameter("xusername",username);
query.setParameter("xpassword",password);
List list=query.getResultList();
if (list.size()>0)
user=(UserInfo)list.get(0);
return user;
}
}
Hi I am new to Spring Security and Spring Oauth, i am configuring a Spring Oauth Server and Resource Server java based. but i need to configure some of the web mvc based on xml, like need to initialize servlet parameters.
below is my 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">
<display-name>Spring Web MVC Application</display-name>
<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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
and mvc-dispatcher-servlet.xml
<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">
<context:component-scan base-package="com.resource" />
<mvc:annotation-driven />
<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/userbase" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
</beans>
and Error log is below:
HTTP Status 500 - No WebApplicationContext found: no ContextLoaderListener registered?
type Exception report
message No WebApplicationContext found: no ContextLoaderListener registered?
description The server encountered an internal error that prevented it from fulfilling this request.
exception
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:252)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.68 logs.
Apache Tomcat/7.0.68
SecurityConfiguration.java
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
DataSource dataSource;
private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder)
.usersByUsernameQuery(
"select username,password, enabled from users where username=?")
.authoritiesByUsernameQuery(
"select username, authority from authorities where username=?");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
****OAuth2ServerConfig.java****
import java.security.Principal;
import java.util.UUID;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.web.bind.annotation.RequestMapping;
#Configuration
public class OAuth2ServerConfig {
#Configuration
#EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
#Autowired
private DataSource dataSource;
public static final String RESOURCE_ID = "resource_id";
#Bean
public JdbcTokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
#Bean
protected AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
#Override
public void configure(ResourceServerSecurityConfigurer resources)
throws Exception {
resources.tokenStore(tokenStore());
resources.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
}
#RequestMapping("/")
public String getInfo() {
return "id: " + UUID.randomUUID() + " content : Spring Oauth2 Welcome first Page";
}
#RequestMapping("/user")
public Principal getUser(Principal principal) {
return principal;
}
}
Please help me on above.
It looks like contextAttribute suffix of the springSecurityFilterChain must match the dispatcher servlet name. Here in your case i see the contextAttribute suffix is dispatcher but the dispatcher servlet name is mvc-dispatcher. Can you try matching them i.e change the contextAttibute suffix to mvc-dispatcher as below and see if the issue goes away.
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.mvc-dispatcher</param-value>
</init-param>
</filter>
I got this info from https://www.txedo.com/blog/spring-security-no-contextloaderlistener-registered/
I have a number of REST controllers built with Spring MVC, say for example:
#RequestMapping(value = "employee")
EmplyoeeController
#RequestMapping(value = "office")
OfficeController
#RequestMapping(value = "school")
SchoolController
#RequestMapping(value = "admin")
AdminController
#RequestMapping(value = "report")
ReportController
Only .../api/admin and .../api/report resources should be available for anyone.
I donot want to remove or comment request mappings in my other controllers. How could I achieve this in web.xml
The problem is we are releasing a lite version of our web-app, but bundled with a number of controllers. In our spring-security.xml we have:
<security:intercept-url
pattern="/api/**"
access="isAuthenticated()"
/>
If the user is authenticated then that will allow them to access all resources under /api/** - like /api/admin and also /api/office, /api/school /api/employee, and so on...
The functionality we want the authenticated users to access is only /api/admin and /api/report and nothing else even if they are authenticated.
We donot need any ROLEs to be assigned for the users yet.
You could use Spring Security for this. Tutorial here: http://spring.io/guides/gs/securing-web/.
In web.xml you would add this:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
some.package.LocalSecurityConfig
</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>
And you would define LocalSecurityConfig like this:
package some.package;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
public class LocalSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> configurer = new InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>();
configurer.withUser("user").password("password").authorities("ROLE_USER");
auth.apply(configurer);
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/employee", "/office", "/school").authenticated()
.anyRequest().permitAll().and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}