I'm not 100% sure I'm performing the correct request but I can't seem to get a token for a client. I've based my solution off of this tutorial 5 minutes with spring oauth 2.0.
I'm performing this request from postman:
/oauth/token?grant_type=client_credentials&client_id=mysupplycompany&client_secret=mycompanyk
That request responds with an exception:
org.springframework.security.authentication.InsufficientAuthenticationException:
There is no client authentication. Try adding an appropriate
authentication filter.
org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(TokenEndpoint.java:91)
Below are some files/classes you may need to help me figure out any issues.
WebInitializer
package com.squirrels.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;
public class WebInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
servletContext.addListener(new RequestContextListener());
Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
DelegatingFilterProxy filter = new DelegatingFilterProxy("springSecurityFilterChain");
filter.setContextAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher");
servletContext.addFilter("springSecurityFilterChain", filter).addMappingForUrlPatterns(null, false, "/*");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.squirrels.config");
return context;
}
}
PersistenceJPAConfig
package com.squirrels.config;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import liquibase.integration.spring.SpringLiquibase;
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.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#ComponentScan({ "com.squirrels.controller", "com.squirrels.services", "com.squirrels.persistence.dao", "com.squirrels.auth" })
#PropertySource(value = { "classpath:squirrel.properties" })
#ImportResource("classpath:spring-security.xml")
public class PersistenceJPAConfig {
#Autowired
private Environment environment;
#Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource());
liquibase.setDefaultSchema(environment.getRequiredProperty("db_schema"));
liquibase.setChangeLog("classpath:/db/changelog/db.changelog-master.xml");
return liquibase;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPersistenceUnitName("SquirrelAuth");
em.setPackagesToScan(new String[] { "com.squirrels.persistence.model" });
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("db_driverClass"));
dataSource.setUrl(environment.getRequiredProperty("db_jdbcUrl"));
dataSource.setUsername(environment.getRequiredProperty("db_user"));
dataSource.setPassword(environment.getRequiredProperty("db_password"));
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", environment.getRequiredProperty("db_hibernateDialect"));
return properties;
}
}
security-spring.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:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<sec:http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="authenticationManager">
<sec:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<sec:anonymous enabled="false" />
<sec:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<sec:custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<sec:http pattern="/api/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint">
<sec:anonymous enabled="false" />
<sec:intercept-url pattern="/api/**" method="GET"
access="IS_AUTHENTICATED_FULLY" />
<sec:custom-filter ref="resourceServerFilter"
before="PRE_AUTH_FILTER" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="springsec/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
</bean>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider
user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<bean id="clientDetails" class="com.squirrels.auth.OAuthClientDetailsImpl">
<property name="id" value="mysupplycompany" />
<property name="secretKey" value="mycompanykey" />
</bean>
<sec:authentication-manager id="userAuthenticationManager">
<sec:authentication-provider ref="customUserAuthenticationProvider" />
</sec:authentication-manager>
<bean id="customUserAuthenticationProvider" class="com.squirrels.auth.OAuthAuthenticationProvider">
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password authentication-manager-ref="userAuthenticationManager" />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="springsec" token-services-ref="tokenServices" />
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="120"></property>
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<mvc:annotation-driven />
</beans>
OAuthAuthenticationProvider
package com.squirrels.auth;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
public class OAuthAuthenticationProvider implements AuthenticationProvider {
#Autowired
private OAuthProxy proxy;
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
boolean result = proxy.isValidUser("1", authentication.getPrincipal().toString(), authentication.getCredentials().toString());
if (result) {
List<GrantedAuthority> grantedAuthorities =
new ArrayList<GrantedAuthority>();
OAuthAuthenticationToken auth = new OAuthAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), grantedAuthorities);
return auth;
} else {
throw new BadCredentialsException("Bad User Credentials.");
}
}
#Override
public boolean supports(Class<?> arg0) {
return true;
}
}
WebMvcConfig
package com.squirrels.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
#Configuration
#EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
};
/*
* Configure ContentNegotiatingViewResolver
*/
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<ViewResolver>();
resolvers.add(jsonViewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
/*
* Configure View resolver to provide JSON output using JACKSON library to
* convert object in JSON format.
*/
#Bean
public ViewResolver jsonViewResolver() {
return new JsonViewResolver();
}
}
OAuthenticationToken
package com.squirrels.auth;
import java.util.Collection;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
public class OAuthAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = -1092219614309982278L;
private final Object principal;
private Object credentials;
public OAuthAuthenticationToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
}
#Override
public Object getCredentials() {
return credentials;
}
#Override
public Object getPrincipal() {
return principal;
}
}
OAuthClientDetailsImpl
package com.squirrels.auth;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
public class OAuthClientDetailsImpl implements ClientDetailsService {
private String id;
private String secretKey;
#Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
if (clientId.equals(id))
{
List<String> authorizedGrantTypes = new ArrayList<String>();
authorizedGrantTypes.add("password");
authorizedGrantTypes.add("refresh_token");
authorizedGrantTypes.add("client_credentials");
BaseClientDetails clientDetails = new BaseClientDetails();
clientDetails.setClientId(id);
clientDetails.setClientSecret(secretKey);
clientDetails.setAuthorizedGrantTypes(authorizedGrantTypes);
return clientDetails;
}
else {
throw new NoSuchClientException("No client recognized with id: " + clientId);
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}
OAuthProxy
package com.squirrels.auth;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.squirrels.dto.UserDTO;
import com.squirrels.persistence.dao.UserDao;
import com.squirrels.persistence.model.UserModel;
import com.squirrels.services.UserUtil;
#Service
public class OAuthProxy {
protected static final Logger logger = LogManager.getLogger(OAuthProxy.class);
#Autowired
private UserDao userDaoImpl;
#Autowired
private UserUtil userUtil;
#Transactional
public boolean isValidUser(String organizationId, String username, String password) {
try{
UserModel user = userDaoImpl.findByOrganizationAndUserName(organizationId, username);
UserDTO userDto = userUtil.getDTO(user);
//TODO validate password (or other means of auth)
return true;
}catch(Exception e){
logger.error("No user: " + username + " found in organization: " + organizationId, e);
}
return false;
}
}
I had the same problem.
In my case is was because I mapped my DispatcherServlet like this :
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/dispatcher/*</url-pattern>
</servlet-mapping>
This was causing problem because security was configured on "/oauth/token", instead of "/dispatcher/oauth/token" :
<security:http pattern="/oauth/token" ...
So I just had to do :
<security:http pattern="/dispatcher/oauth/token"
And the problem was gone.
If that is not the case for you, it may be because you have no DelegatingFilterProxy configured.
Try configuring it in web.xml :
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
And if you use java config instead of web.xml, extending the class org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer
will configure it.
Related
My applicationContext is failing while executing stored procedure with below exception :
org.springframework.dao.InvalidDataAccessApiUsageException: Property 'sql' is required
My configurations are mentioned below.
package com.comp.bu.app.service.impl;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.StoredProcedure;
import org.springframework.stereotype.Service;
import com.apple.gbi.eds.db.dao.storeproc.SqlRefOutParam;
import com.comp.bu.app.model.ErrorDetails;
import com.comp.bu.app.service.IErrorDetailsService;
#Service(value="errorDetailsServiceImpl")
public class ErrorDetailsServiceImpl extends StoredProcedure implements IErrorDetailsService {
/**
* LOG for logging for the message
*/
private static final Logger LOG = Logger.getLogger(ErrorDetailsServiceImpl.class);
JdbcTemplate jdbcTemplate;
#Autowired
public ErrorDetailsServiceImpl(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
}
#Override
public List<ErrorDetails> getErrorDetails(final String startDate, final String endDate) {
String procName="sp_uptime_error_section";
List<ErrorDetails> errorDetailsList = null;
Map<String,Object> inParameters = new HashMap<String,Object>();
try{
ErrorSectionProcedure errorProcedure = new ErrorSectionProcedure(jdbcTemplate, procName);
inParameters.put("startDate", startDate);
inParameters.put("endDate", endDate);
errorDetailsList= errorProcedure.executeProc(inParameters);
System.out.println(" errorDetailsList >>> "+errorDetailsList);
LOG.info("errorDetailsList >> "+errorDetailsList);
}catch(Exception ex){
ex.printStackTrace();
}
return errorDetailsList;
}
public static class ErrorSectionProcedure extends StoredProcedure{
public ErrorSectionProcedure(JdbcTemplate jdbcTemplate, String procName){
super(jdbcTemplate,procName);
setSql(procName);
declareParameter(new SqlParameter("startDate", Types.VARCHAR));
declareParameter(new SqlParameter("endDate", Types.VARCHAR));
declareParameter(new SqlOutParameter("res", oracle.jdbc.OracleTypes.CURSOR, new RowMapper<ErrorDetails>() {
public ErrorDetails mapRow(ResultSet argResults, int argRowNum) throws SQLException {
ErrorDetails reportDetails = new ErrorDetails();
reportDetails.setAppName(argResults.getString(1));
reportDetails.setTransactionId(argResults.getString(2));
reportDetails.setCurlId(argResults.getString(3));
reportDetails.setFailureLog(argResults.getString(4));
reportDetails.setTimeStamp(argResults.getString(4));
return reportDetails;
}
}));
super.compile();
}
public List<ErrorDetails> executeProc(Map<String,Object> inParameters){
Map<String,Object> output = execute(inParameters);
#SuppressWarnings("unchecked")
List<ErrorDetails> outputlist = (List<ErrorDetails>)output.get("res");
return outputlist;
}
}
}
Configuration is mentioned as :
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#url:1526:sid" />
<property name="username" value="uname" />
<property name="password" value="***" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
Please refer the real issue why my #PreAuthorize("hasPermission(#user,'write')") is not working
Basically I'am trying to check a normal user
My controllerClass
package com.***.appconfig.controller;
import com.***.appconfig.dao.UserDaoImplementation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.***.appconfig.model.User;
import com.***.appconfig.security.CustomPermissionEvaluator;
#Controller
public class CheckPermissionController {
public static User user = new User();
UserDaoImplementation userDao = new UserDaoImplementation();
Boolean directPermission = false;
CustomPermissionEvaluator customPermissionEvaluator = new CustomPermissionEvaluator();
#RequestMapping("/checkPermission")
protected ModelAndView direct() throws Exception {
System.out.println("in direct");
user.setUserName("andrew");
userDao.addListValues(user);
System.out.println("before assign");
directPermission = userDao.assignUser(user);
System.out.print("after assign");
if (directPermission) {
return new ModelAndView("checkPermission");
} else {
return new ModelAndView("login");
}
}
}
Here is my Dao
import com.***.appconfig.model.User;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import java.util.HashMap;
#Component
public class UserDaoImplementation implements UserDao {
#Override
public User addListValues(User user) {
HashMap < String, String > permissionList = new HashMap < String, String > ();
permissionList.put("server", "write");
user.setPermissionList(permissionList);
return null;
}
#PreAuthorize("hasPermission(#user,'write')")
public Boolean assignUser(User user) {
System.out.println("in assign");
return true;
}
}
Here is my CustomPermissionEvaluator
package com.***.appconfig.security;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import com.***.appconfig.controller.CheckPermissionController;
import com.***.appconfig.model.User;
import com.***.appconfig.dao.UserDaoImplementation;
import java.io.Serializable;
import java.util.HashMap;
public class CustomPermissionEvaluator implements PermissionEvaluator {
public static User user;
public UserDaoImplementation userDao;
#Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
setPermissions();
String targetType = targetDomainObject.getClass().getSimpleName().toUpperCase();
HashMap < String, String > permissionList = user.getPermissionList();
System.out.print("before check");
if (permissionList.containsValue("write")) {
System.out.print("success check");
hasPermission = true;
}
return hasPermission;
}
#Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
Boolean hasPermission = false;
return hasPermission;
}
public void setPermissions() {
user.setUserName("andrew");
userDao.addListValues(user);
}
}
I created a duplicate user object inorder to dynmically populate in PermissionEvaluator.The hasPermission() overrride is not getting called.
Here is my spring-security.xml
<http auto-config="true">
<access-denied-handler error-page="/403page" />
<intercept-url pattern="/user" access="ROLE_USER" />
<intercept-url pattern="/admin" access="ROLE_ADMIN" />
<form-login login-page='/login' username-parameter="username" password-parameter="password" default-target-url="/user" authentication-failure-url="/login?authfailed" />
<logout logout-success-url="/login?logout" />
</http>
<global-method-security pre-post-annotations="enabled" secured-annotations="enabled">
<expression-handler ref="expressionHandler" />
</global-method-security>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password, enabled from users where username=?" authorities-by-username-query="select username, role from user_roles where username =? " />
</authentication-provider>
</authentication-manager>
<beans:bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<beans:property name="permissionEvaluator" ref="permissionEvaluator" />
</beans:bean>
<beans:bean name="permissionEvaluator" class="com.coolminds.appconfig.security.CustomPermissionEvaluator" />undefined</beans:beans>
Your Controller class should inject all dependencies to make sure Spring can create appropriate proxy objects:
package com.***.appconfig.controller;
import com.***.appconfig.dao.UserDaoImplementation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.***.appconfig.model.User;
#Inject
UserDao userDao;
#Controller
public class CheckPermissionController {
#RequestMapping("/checkPermission")
protected ModelAndView direct() throws Exception {
User user = new User();
boolean directPermission = false;
System.out.println("in direct");
user.setUserName("andrew");
userDao.addListValues(user);
System.out.println("before assign");
directPermission = userDao.assignUser(user);
System.out.print("after assign");
if (directPermission) {
return new ModelAndView("checkPermission");
} else {
return new ModelAndView("login");
}
}
}
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.
I am migrating the Spring Security from xml to java and I am facing the issue:
j_spring_security_check : The requested resource is not available.
The security is working fine with xml but switching to java is giving the error.
This is working fine
Spring security xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<security:http auto-config="true" use-expressions="true">
<security:logout logout-success-url="/logout" />
<security:intercept-url pattern="/userOnly**" access="hasRole('USER')"/>
</security:http>
<!-- authentication manager -->
<security:authentication-manager erase-credentials="true">
<security:authentication-provider user-service-ref="userService">
<security:password-encoder ref="encoder" />
</security:authentication-provider>
</security:authentication-manager>
<!-- password encoder -->
<beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" />
</beans>
Security Config
package com.src.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
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.password.StandardPasswordEncoder;
import com.src.service.UserService;
#Configuration
#EnableWebSecurity
#ImportResource(value = "classpath:spring-security-context.xml")
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Bean
public UserService userService(){
return new UserService();
}
}
This is not working
Security Config
package com.src.config;
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.password.StandardPasswordEncoder;
import com.src.service.UserService;
#Configuration
#EnableWebSecurity
//#ImportResource(value = "classpath:spring-security-context.xml")
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Bean(name="userService")
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public UserService userService(){
return new UserService();
}
#Autowired
private UserService userService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userService)
.passwordEncoder(new StandardPasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user/**").access("hasRole('USER')")
.and()
.formLogin().loginPage("/signin").failureUrl("/signin?error=1")
.and()
.logout().logoutSuccessUrl("/logout")
.and()
.csrf();
}
}
I I am trying to use spring security to control authentication in my RMI client app.
I am using maven to load 3.1.3.RELEASE spring
Then in my client xml, I am seeing "authentication-provider is not allowed here" message.
This is the spring xml file:
<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
">
<bean id="employeeService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://localhost:1234/employee-service"/>
<property name="serviceInterface" value="rmi.common.EmployeeService"/>
<property name="refreshStubOnConnectFailure"><value>true</value></property>
<property name="remoteInvocationFactory"><ref bean="remoteInvocationFactory"/></property>
</bean>
<bean id="remoteInvocationFactory" class="org.springframework.security.remoting.rmi.ContextPropagatingRemoteInvocationFactory"/>
<security:authentication-manager alias="authManager">
<security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>
<bean id="customAuthenticationProvider" class="rmi.authentication.CustomAuthenticationProvider"/>
</beans>
This is my client side code:
package rmi.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import rmi.common.Employee;
import rmi.common.EmployeeService;
import javax.annotation.Resource;
import java.util.Iterator;
import java.util.List;
public class EmployeeClient {
#Resource(name = "authManager")
private org.springframework.security.authentication.AuthenticationManager authenticationManager; // specific for Spring Security
private static ApplicationContext ctx;
public static void main(String[] args) {
ctx = new ClassPathXmlApplicationContext("rmi-client-context.xml");
new EmployeeClient().exec();
}
public void exec() {
EmployeeService employee = (EmployeeService) ctx.getBean("employeeService");
Authentication authenticate = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken("myuser", "mypwd"));
if (authenticate.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(authenticate);
}
employee.addEmployee(new Employee("Jack Su", "address1"));
employee.addEmployee(new Employee("Alice Liu", "address2"));
List<Employee> employees = employee.getEmployees();
System.out.println("Total number of employees: " + employees.size());
Iterator<Employee> it = employees.iterator();
while (it.hasNext()) {
Employee emp = (Employee) it.next();
System.out.println(" " + emp);
}
}
}
This is my testing authentication provider:
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.ArrayList;
import java.util.List;
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Override
public Authentication authenticate(Authentication argAuth) throws AuthenticationException {
List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
Authentication auth = new UsernamePasswordAuthenticationToken(argAuth.getPrincipal(),
argAuth.getCredentials(), grantedAuths);
auth.setAuthenticated(true);
return auth;
}
#Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Not sure about your exact error, but something in your configuration might be wrong.
Your EmployeeClient is not a Spring-Managed-Bean, because you created it with new-operator, so your #Resource(name = "authManager") should not work. If you posted all your configuration authenticationManager.authenticate(..) should produce NullPointerException.
Instead of new you could do this in your Main.
EmployeeClient client = (EmployeeClient) ctx.getBean("employeeClient");
client.exec();
(and add #Service to your EmployeeClient).