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();
}
}
Related
I am new in spring boot, and I am trying to work with JWT.
I follwed many examples and all looks the same.
Before,15 days I make classic auth application with JWT and all works fine, but now I am facing some errors there.
https://github.com/nedim-bajric/basicJWTspring this is a repo of project that I was created before 15 days and it works fine.
Error I gets comming from SecurityConfiguration and it says that is not possible to find WebSecurityConfigurerAdapter, and it is not possilbe to #Overide configure method.
Also, there is problem with .antMatchers, it says Cannot resolve method 'antMatchers' in 'ExpressionInterceptUrlRegistry'.
There is my config file
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.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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.unze.sis.security.jwt.AuthEntryPointJwt;
import com.unze.sis.security.jwt.AuthTokenFilter;
import com.unze.sis.security.services.UserDetailsServiceImpl;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsServiceImpl userDetailsService;
#Autowired
private AuthEntryPointJwt unauthorizedHandler;
#Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
#Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
I tried few solutions that I found on stackowerflow, but it doesn't work.
This question already has answers here:
Why is my method undefined for the type object?
(4 answers)
Closed 2 years ago.
I'm building a spring application with spring security. I have added basic authentication of a username and password in the code. I want to access APIs via a reactjs web app with this basic authentication. For this, I'm trying to add the cors policy.
In the security configuration of spring security, I'm getting the error:
The method withDefaults() is undefined for the type SecurityConfiguration
I have got all the necessary dependencies installed.
What can be the possible solution?
Attaching my code below.
package com.example.demo;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
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.config.annotation.web.configurers.CorsConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors(withDefaults()) //getting the error here
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/login").authenticated()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers(HttpMethod.GET).authenticated()
.anyRequest().authenticated()
.and()
.httpBasic();
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowedMethods(Arrays.asList("GET","POST", "OPTIONS"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Bean
public PasswordEncoder getPasswordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
Your SecurityConfiguration, nor the WebSecurityConfigurerAdapter have a method withDefaults(). You need to add a static import:
import static org.springframework.security.config.Customizer.withDefaults;
I know this has been asked before, but none of the proposed answers work for me.
When starting up Jetty with Spring Security I get this error:
No bean named 'org.springframework.web.filter.DelegatingFilterProxy-1b68ddbd' available
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:tx="http://www.springframework.org/schema/tx"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<context:component-scan base-package="de.pack.webservice" />
<context:annotation-config />
[...]
<jpa:repositories base-package="de.pack.webservice.security"
entity-manager-factory-ref="customEntityManagerFactory" />
</beans>
SecurityConfig.java
package de.pack.webservice.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.authentication.dao.ReflectionSaltSource;
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.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import de.pack.webservice.security.StandardPasswordEncoder;
#EnableWebSecurity
#Configuration
#Import(PrePostEnabledConfig.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userService;
#Autowired
private StandardPasswordEncoder encoder;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userService);
authProvider.setPasswordEncoder(encoder);
ReflectionSaltSource saltSource = new ReflectionSaltSource();
saltSource.setUserPropertyToUse("salt");
authProvider.setSaltSource(saltSource);
auth.authenticationProvider(authProvider);
System.out.println("in gobal");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("in configure");
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable().authorizeRequests().anyRequest().authenticated()
.and().httpBasic();
}
}
And for Dev we don't use Web.xml but set the parameters at server startup. Here's the relevant part with the filter definition:
ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
contextHandler.setContextPath("/");
contextHandler.setInitParameter("contextConfigLocation", "classpath*:**applicationContext.xml");
contextHandler.addEventListener(new ResteasyBootstrap());
contextHandler.addEventListener(new SpringContextLoaderListener());
ServletHolder holder = new ServletHolder(new HttpServletDispatcher());
holder.setInitParameter("javax.ws.rs.Application", WebApplication.class.getName());
contextHandler.addServlet(holder, "/*");
EnumSet<DispatcherType> x = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE);
contextHandler.addFilter(DelegatingFilterProxy.class, "/*", x);
server.setHandler(contextHandler);
Configure the DelegatingFilterProxy as below:
context.addFilter(new FilterHolder(new DelegatingFilterProxy("springSecurityFilterChain")), "/*", x);
Actually Spring Security looks for a bean named springSecurityFilterChain (by default), which points to org.springframework.web.filter.DelegatingFilterProxy
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.
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).