Spring Social Twitter HTTP Status 405 - Request method 'POST' not supported - spring

Friends I am using Spring Mvc 4.2.5, Spring Security 4.0.4 , Spring Social 1.1.2 to integrate with twitter api.everything is fine upto connectcontroller handling get /connect/twitter,/connect . but when i send post request from twitterConnect.jsp its giving 405 error
here is my SocialConfiguration code
#Configuration
#EnableSocial
#PropertySource(value = { "classpath:twitter.properties" })
public class SpringSocialConfig implements SocialConfigurer {
static final Logger logger = Logger.getLogger(SpringSocialConfig.class);
#Autowired
private DataSource dataSource;
//
// SocialConfigurer implementation methods
//
#Override
public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
logger.info("at addconnectionFactory adding consumerkey");
System.out.println("at add Connection FActory");
cfConfig.addConnectionFactory(new TwitterConnectionFactory(env.getProperty("twitter.consumerKey"), env.getProperty("twitter.consumerSecret")));
}
#Override
public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
logger.info("crateing jdbcuserconnection repository");
return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
}
// API Binding Beans
//
#Bean
#Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public Twitter twitter(ConnectionRepository repository) {
Connection<Twitter> connection = repository.findPrimaryConnection(Twitter.class);
logger.info("crateing connection Twitter");
return connection != null ? connection.getApi() : null;
}
//
// Web Controller and Filter Beans
//
#Bean
public ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) {
ConnectController connectController = new ConnectController(connectionFactoryLocator, connectionRepository);
logger.info("At connect Controller");
System.out.println("hi iam running");
return connectController;
}
#Bean
public ReconnectFilter apiExceptionHandler(UsersConnectionRepository usersConnectionRepository, UserIdSource userIdSource) {
return new ReconnectFilter(usersConnectionRepository, userIdSource);
}
#Override
public UserIdSource getUserIdSource() {
return new UserIdSource() {
#Override
public String getUserId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
}
return authentication.getName();
}
};
}
}
This is my SecurityConfiguration
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("customUserDetailsService")
UserDetailsService userDetailsService;
#Autowired
PersistentTokenRepository tokenRepository;
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/signup/**").anonymous()
.antMatchers("/dashboard/**","/add_t_accounts/**").access("hasRole('USER')")
.and().formLogin().loginPage("/login").loginProcessingUrl("/login").defaultSuccessUrl("/dashboard")
.usernameParameter("userName").passwordParameter("password").and()
.rememberMe().rememberMeParameter("remember-me").tokenRepository(tokenRepository)
.tokenValiditySeconds(86400).and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public TextEncryptor textEncryptor() {
return Encryptors.noOpText();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
#Bean
public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
PersistentTokenBasedRememberMeServices tokenBasedservice = new PersistentTokenBasedRememberMeServices(
"remember-me", userDetailsService, tokenRepository);
return tokenBasedservice;
}
#Bean
public AuthenticationTrustResolver getAuthenticationTrustResolver() {
return new AuthenticationTrustResolverImpl();
}
#Bean(name="authenticationManager")
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Im getting this on console
enter code hereo
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Thu Nov 24 05:04:03 IST 2016]; root of context hierarchy
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Registering annotated classes: [class org.springframework.social.showcase.config.MainConfig,class org.springframework.social.showcase.config.WebMvcConfig,class org.springframework.social.showcase.config.SecurityConfig,class org.springframework.social.showcase.config.SocialConfig]
WARN : org.springframework.context.annotation.ConfigurationClassEnhancer - #Bean method MainConfig.propertyPlaceHolderConfigurer is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as #Autowired, #Resource and #PostConstruct within the method's declaring #Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see #Bean javadoc for complete details
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Detected #ExceptionHandler methods in exceptionHandlingControllerAdvice
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for #ControllerAdvice: Root WebApplicationContext: startup date [Thu Nov 24 05:04:03 IST 2016]; root of context hierarchy
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.HomeController.home(java.security.Principal,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/signin],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public void org.springframework.social.showcase.signin.SigninController.signin()
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/signup],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.social.showcase.signup.SignupForm org.springframework.social.showcase.signup.SignupController.signupForm(org.springframework.web.context.request.WebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/signup],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.signup.SignupController.signup(org.springframework.social.showcase.signup.SignupForm,org.springframework.validation.BindingResult,org.springframework.web.context.request.WebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/friends],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterFriendsController.friends(org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/followers],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterFriendsController.followers(org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/messages],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterMessageController.sent(org.springframework.social.showcase.twitter.MessageForm)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/messages/sent],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterMessageController.sent(org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/messages],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterMessageController.inbox(org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterProfileController.home(java.security.Principal,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/revoked],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public void org.springframework.social.showcase.twitter.TwitterRevokedToken.simulateExpiredToken()
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/search],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterSearchController.showTrends(java.lang.String,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/timeline/{timelineType}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterTimelineController.showTimeline(java.lang.String,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/timeline],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterTimelineController.showTimeline(org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/tweet],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterTimelineController.postTweet(java.lang.String)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/twitter/trends],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.showcase.twitter.TwitterTrendsController.showTrends(org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/signin/{providerId}],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ProviderSignInController.signIn(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/signin/{providerId}],methods=[GET],params=[oauth_token],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ProviderSignInController.oauth1Callback(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/signin/{providerId}],methods=[GET],params=[error],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ProviderSignInController.oauth2ErrorCallback(java.lang.String,java.lang.String,java.lang.String,java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/signin/{providerId}],methods=[GET],params=[code],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ProviderSignInController.oauth2Callback(java.lang.String,java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/signin/{providerId}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ProviderSignInController.canceledAuthorizationCallback()
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.connect(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[GET],params=[oauth_token],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.oauth1Callback(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[GET],params=[error],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.oauth2ErrorCallback(java.lang.String,java.lang.String,java.lang.String,java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.connect.web.ConnectController.connectionStatus(org.springframework.web.context.request.NativeWebRequest,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String org.springframework.social.connect.web.ConnectController.connectionStatus(java.lang.String,org.springframework.web.context.request.NativeWebRequest,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[GET],params=[code],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.oauth2Callback(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}/{providerUserId}],methods=[DELETE],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.removeConnection(java.lang.String,java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/connect/{providerId}],methods=[DELETE],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.view.RedirectView org.springframework.social.connect.web.ConnectController.removeConnections(java.lang.String,org.springframework.web.context.request.NativeWebRequest)
INFO : org.springframework.security.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/resources/**'], []
INFO : org.springframework.security.web.DefaultSecurityFilterChain - Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher#1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#70012279, org.springframework.security.web.context.SecurityContextPersistenceFilter#69061fc0, org.springframework.security.web.header.HeaderWriterFilter#12139505, org.springframework.security.web.csrf.CsrfFilter#5a005b47, org.springframework.security.web.authentication.logout.LogoutFilter#3170938b, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#4946d531, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#5a45ee51, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#27698887, org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter#61a3002, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#5a7e6f61, org.springframework.security.web.session.SessionManagementFilter#58c11f65, org.springframework.security.web.access.ExceptionTranslationFilter#18b43f5, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#4986e68]
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 4999 ms
Nov 24, 2016 5:04:08 AM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'dispatcher'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcher': initialization started
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Thu Nov 24 05:04:08 IST 2016]; parent: Root WebApplicationContext
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcher': initialization completed in 212 ms
Nov 24, 2016 5:04:08 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8090"]
Nov 24, 2016 5:04:08 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8099"]
Nov 24, 2016 5:04:08 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 23694 ms

I had the same problem like you have. Now, I found the cause. You are including csrf token control in spring security configuration. That's why, you need to add csrf token as input in your connectTwitter view file.

Related

What happens when i using #Bean and #Component annotations together?

I'm trying to configure my spring security application.
I want to create my own UserDetailsService.
For that i do something like this:
public class ApplicationUserService implements UserDetailsService {
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return this.someUser();
}
}
I got 2 ways to add this UserService to Spring Security
Add it to configuration class. Something like this:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
protected UserDetailsService userDetailsService() {
return applicationUserService;
}
}
Or add annotaion #Component, or #Service on my class.
Everything is working fine when i chose only 1 way, but i got an question: why when i trying to use both variants (add #Service and add #Bean to config) nothing is working?
I got no exceptions, error or something like this in console:
2021-09-11 17:26:16.755 INFO 15819 --- [ main] com.example.test.TestApplication : Starting TestApplication using Java 16.0.2 on aleksander-MS-7A71 with PID 15819 (/home/aleksander/programming/java/4fun/test/target/classes started by aleksander in /home/aleksander/programming/java/4fun/test)
2021-09-11 17:26:16.756 INFO 15819 --- [ main] com.example.test.TestApplication : No active profile set, falling back to default profiles: default
2021-09-11 17:26:17.402 INFO 15819 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-09-11 17:26:17.409 INFO 15819 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-09-11 17:26:17.409 INFO 15819 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.52]
2021-09-11 17:26:17.442 INFO 15819 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-09-11 17:26:17.442 INFO 15819 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 630 ms
2021-09-11 17:26:17.555 INFO 15819 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#6981f8f3, org.springframework.security.web.context.SecurityContextPersistenceFilter#38bb9d7a, org.springframework.security.web.header.HeaderWriterFilter#62db3891, org.springframework.security.web.authentication.logout.LogoutFilter#48528634, org.springframework.security.web.authentication.www.BasicAuthenticationFilter#80bfdc6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#78d6447a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#5e65afb6, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#623dcf2a, org.springframework.security.web.session.SessionManagementFilter#2819c460, org.springframework.security.web.access.ExceptionTranslationFilter#6f49d153, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#60bbacfc]
2021-09-11 17:26:17.676 INFO 15819 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-09-11 17:26:17.682 INFO 15819 --- [ main] com.example.test.TestApplication : Started TestApplication in 1.215 seconds (JVM running for 1.794)
The way you've described the question, the application will definitely throw an exception unless you've defined the bean preference.
First case:
Basically, UserDetailsService is an interface and you've provided the implementation of it by declaring the bean as
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
protected UserDetailsService userDetailsService() {
return new ApplicationUserService();
}
}
Second case: You want to check the behaviour by declaring another bean using #Service or #Component annotation as following
#Service
public class ApplicationUserService implements UserDetailsService {
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return new UserDetails();
}
}
If you try to use the above cases together, it won't work. The case is very simple you are providing two beans of type UserDetailsService to the spring container and hence it won't be able to identify which one it should use.
If you want to check the behaviour with both the cases you've to set the priority for beans, so in that case you can mark one of the bean with #Primary annotation.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Primary
#Bean
#Override
protected UserDetailsService userDetailsService() {
return new ApplicationUserService();
}
}

Multiple DispatcherServlet - Spring-Boot-2.4

I'm trying to create multiple dispatcherservlet ("/rest/", "/jsp/", "mq/*"). Springboot initialises only one dispatcherservlet.
i have two bean creation methods for DispatcherServletRegistrationBean in order to create two dispatcher servlet. I has set the order and precedence level for both beans. When i start the application, only one of the dispatcherservlet is getting Initialised. In this case, it is "restDisparcher" (please look for console output). what should i do in order to setup multiple dispatcher servlet.
#SpringBootConfiguration
public class AppConfiguration {
#Bean
#Primary
public DispatcherServletRegistrationBean dispatcherServletRegistrationBeanRest() {
DispatcherServlet dispatcherServlet = new DispatcherServlet(new AnnotationConfigServletWebApplicationContext("com.michael.springsecurityentitlement.rest"));
DispatcherServletRegistrationBean dispatcher = new DispatcherServletRegistrationBean(dispatcherServlet , "/rest/*");
dispatcher.setName("restDispatcher");
dispatcher.setLoadOnStartup(1);
dispatcher.setOrder(Ordered.HIGHEST_PRECEDENCE);
return dispatcher;
}
#Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBeanJsp() {
DispatcherServlet dispatcherServlet = new DispatcherServlet(new AnnotationConfigServletWebApplicationContext("com.michael.springsecurityentitlement.jsp"));
DispatcherServletRegistrationBean dispatcher = new DispatcherServletRegistrationBean(dispatcherServlet , "/jsp/*");
dispatcher.setName("restDispatcher");
dispatcher.setLoadOnStartup(1);
dispatcher.setOrder(Ordered.HIGHEST_PRECEDENCE);
return dispatcher;
}
#Bean
public TomcatServletWebServerFactory servletWebServerFactory() {
TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory("/custom",8081);
return tomcatServletWebServerFactory;
}
public static void main(String[] args) {
SpringApplication app = new SpringApplication(AppConfiguration.class);
app.run(args);
}
}
Console:
2021-03-04 12:09:39.015 INFO 1108 --- [ main] c.m.s.AppConfiguration : Starting AppConfiguration using Java 15.0.2 on ASINTHs-MacBook-Pro.local with PID 1108 (/Users/asinth/git/spring-security-entitlement/target/classes started by asinth in /Users/asinth/git/spring-security-entitlement)
2021-03-04 12:09:39.030 INFO 1108 --- [ main] c.m.s.AppConfiguration : No active profile set, falling back to default profiles: default
2021-03-04 12:09:39.539 INFO 1108 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2021-03-04 12:09:39.551 INFO 1108 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-03-04 12:09:39.551 INFO 1108 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.43]
2021-03-04 12:09:39.704 INFO 1108 --- [ main] o.a.c.c.C.[.[localhost].[/custom] : Initializing Spring embedded WebApplicationContext
2021-03-04 12:09:39.704 INFO 1108 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 635 ms
2021-03-04 12:09:39.806 INFO 1108 --- [ main] o.s.boot.web.servlet.RegistrationBean : Servlet restDispatcher was not registered (possibly already registered?)
2021-03-04 12:09:39.880 INFO 1108 --- [ main] o.a.c.c.C.[.[localhost].[/custom] : Initializing Spring DispatcherServlet 'restDispatcher'
2021-03-04 12:09:39.881 INFO 1108 --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'restDispatcher'
2021-03-04 12:09:40.131 INFO 1108 --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 250 ms
2021-03-04 12:09:40.136 INFO 1108 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path '/custom'
2021-03-04 12:09:40.155 INFO 1108 --- [ main] c.m.s.AppConfiguration : Started AppConfiguration in 2.093 seconds (JVM running for 3.252)
I think the problem is your dispatcher name. Set different names for different Dispatcher and it should works. Maybe like this :
#SpringBootApplication
public class AppConfiguration {
#Bean
#Primary
public DispatcherServletRegistrationBean dispatcherServletRegistrationBeanRest() {
DispatcherServlet dispatcherServlet = new DispatcherServlet(new AnnotationConfigServletWebApplicationContext("com.michael.springsecurityentitlement.rest"));
DispatcherServletRegistrationBean dispatcher = new DispatcherServletRegistrationBean(dispatcherServlet , "/rest/*");
dispatcher.setName("restDispatcher");
dispatcher.setLoadOnStartup(1);
dispatcher.setOrder(Ordered.HIGHEST_PRECEDENCE);
return dispatcher;
}
#Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBeanJsp() {
DispatcherServlet dispatcherServlet = new DispatcherServlet(new AnnotationConfigServletWebApplicationContext("com.michael.springsecurityentitlement.jsp"));
DispatcherServletRegistrationBean dispatcher = new DispatcherServletRegistrationBean(dispatcherServlet , "/jsp/*");
dispatcher.setName("jspDispatcher");
dispatcher.setLoadOnStartup(1);
dispatcher.setOrder(Ordered.HIGHEST_PRECEDENCE);
return dispatcher;
}
#Bean
public TomcatServletWebServerFactory servletWebServerFactory() {
TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory("/custom",8081);
return tomcatServletWebServerFactory;
}
public static void main(String[] args) {
SpringApplication.run(AppConfiguration.class, args);
}
}

Spring Security ignoring roles

I have this controller:
#RestController
public class NumbersController {
#PreAuthorize("hasRole('ROLE_ONE')")
#GetMapping("/one")
private String one(){
return "This is one.";
}
#PreAuthorize("hasRole('ROLE_TWO')")
#GetMapping("/two")
private String two(){
return "This is two.";
}
}
And this security configuration:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends GlobalMethodSecurityConfiguration {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth
.inMemoryAuthentication()
.withUser("user").password(encoder.encode("password")).roles("ONE");
auth
.inMemoryAuthentication()
.withUser("user2").password(encoder.encode("password2")).roles("TWO");
}
}
And while running both of my users can access both of the resources. What I want is only for user to be able to access /one and only for user2 to access /two.
I also tried using #Secured("ONE") with the same result.
Console output:
2021-01-14 16:10:20.026 INFO 4376 --- [ main] security.security.SecurityApplication : Starting SecurityApplication on Ivan-PC with PID 4376 (D:\Z\security\target\classes started by Ivan in D:\Z\security)
2021-01-14 16:10:20.041 INFO 4376 --- [ main] security.security.SecurityApplication : No active profile set, falling back to default profiles: default
2021-01-14 16:10:24.363 INFO 4376 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-01-14 16:10:24.378 INFO 4376 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-01-14 16:10:24.378 INFO 4376 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-01-14 16:10:24.565 INFO 4376 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-01-14 16:10:24.565 INFO 4376 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4321 ms
2021-01-14 16:10:25.221 INFO 4376 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-01-14 16:10:25.860 INFO 4376 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#57a48985, org.springframework.security.web.context.SecurityContextPersistenceFilter#17740dae, org.springframework.security.web.header.HeaderWriterFilter#14bf57b2, org.springframework.security.web.csrf.CsrfFilter#48535004, org.springframework.security.web.authentication.logout.LogoutFilter#3cee53dc, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#67440de6, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter#35835e65, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter#1ab6718, org.springframework.security.web.authentication.www.BasicAuthenticationFilter#7ce7e83c, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#345cf395, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#7144655b, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#3910fe11, org.springframework.security.web.session.SessionManagementFilter#14379273, org.springframework.security.web.access.ExceptionTranslationFilter#cfbc8e8, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#49293b43]
2021-01-14 16:10:25.969 INFO 4376 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-01-14 16:10:25.985 INFO 4376 --- [ main] security.security.SecurityApplication : Started SecurityApplication in 6.771 seconds (JVM running for 8.031)
2021-01-14 16:10:29.847 INFO 4376 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-01-14 16:10:29.848 INFO 4376 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2021-01-14 16:10:29.870 INFO 4376 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 22 ms
The requests are made with Postman to http://localhost:8080/two and using the authorization fields.
Check this if it helps,
We can configure multiple HttpSecurity instances just as we can have multiple blocks. The key is to extend the WebSecurityConfigurerAdapter multiple times. For example, the following is an example of having a different configuration for URL’s that start with /api/.
#EnableWebSecurity
public class MultiHttpSecurityConfig {
#Bean
public UserDetailsService userDetailsService() throws Exception {
// ensure the passwords are encoded properly
UserBuilder users = User.withDefaultPasswordEncoder();
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(users.username("user").password("password").roles("USER").build());
manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build());
return manager;
}
#Configuration
#Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests(authorize -> authorize
.anyRequest().hasRole("ADMIN")
)
.httpBasic(withDefaults());
}
}
#Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults());
}
}
}
Configure Authentication as normal
Create an instance of WebSecurityConfigurerAdapter that contains #Order to specify which WebSecurityConfigurerAdapter should be considered first.
The http.antMatcher states that this HttpSecurity will only be applicable to URLs that start with /api/
Create another instance of WebSecurityConfigurerAdapter.
If the URL does not start with /api/ this configuration will be used.
This configuration is considered after ApiWebSecurityConfigurationAdapter since it has an #Order value after 1 (no #Order defaults to last).
Try out this in your SecurityConfig class
#EnableGlobalMethodSecurity(
prePostEnabled = true,
jsr250Enabled = true)
The prePostEnabled property enables Spring Security pre/post annotations
The jsr250Enabled property allows us to use the #RoleAllowed annotation

Spring MVC Rest API not working when implementing InitializingBean

I have a basic API setup with Spring MVC Rest as following.
public abstract class AbstractApi implements InitializingBean {
#Autowired
protected ValidatorFactory validatorFactory;
/* ... */
#Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(validatorFactory);
}
}
#Controller
#RequestMapping("books")
public class BookApi extends AbstractApi {
private final BookRepository bookRepository;
#Autowired
public BookApi(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Book> getBooks() {
return new ResponseEntity<>(bookRepository.findAll(), HttpStatus.OK);
}
}
The server returns 404 - Not Found if I send GET /books request with above configuration.
But, if I make AbstractApi un-implement InitializingBean, it works fine. Also, annotating #PostConstruct to afterPropertiesSet() instead of implementing InitializingBean works.
Why is Spring #Controller API not working when implementing InitializingBean?
Your code looks correct. I tested in on my own and everything works as expected. What I'm suggesting is to remove #Autowired ValidatorFactory in AbstractApi class just for testing purpose. Implementing InitializingBean is not related to the request mapping handler mapping. My working code is:
public abstract class AbstractApi implements InitializingBean {
#Override
public void afterPropertiesSet() throws Exception {
System.out.println("after properties set");
}
}
and my controller
#Controller
#RequestMapping("books")
public class BooksController extends AbstractApi {
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<String> getBooks() {
return new ResponseEntity<>("", HttpStatus.OK);
}
}
and starting log from tomcat:
2016-01-28 16:48:03.141 INFO 2238 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-01-28 16:48:03.317 INFO 2238 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2016-01-28 16:48:03.329 INFO 2238 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.23
2016-01-28 16:48:03.405 INFO 2238 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2016-01-28 16:48:03.405 INFO 2238 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1815 ms
2016-01-28 16:48:03.512 INFO 2238 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-01-28 16:48:03.515 INFO 2238 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
after properties set
Your current #RequestMapping("books") path is incorrectly specified. When running locally on port 8080 looks like http://localhost:8080books
and should be #RequestMapping("/books") - http://localhost:8080/books
give that a try.

Home page not displayed in Spring Boot

I am getting below error when developing first web app in STS in Spring Boot (v1.2.3.RELEASE) while opening this url (http://localhost:8080/riyan/):
Error:
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Jun 05 23:08:55 PKT 2015
There was an unexpected error (type=Not Found, status=404).
No message available
Application.properties
logging.config = ${app.root.dir}/config/logback.xml
spring.view.prefix = /WEB-INF/views/
spring.view.suffix = .jsp
spring.datasource.url=jdbc:hsqldb:file:${app.root.dir}/data/accounts;crypt_key=901a6105813eb65326bf35790a965432;crypt_type=blowfish;hsqldb.write_delay=false;create=false;sql.syntax_ora=true
spring.datasource.username=accounts
spring.datasource.password=accounts
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=none
spring.datasource-internal.jpa.database-platform=org.hibernate.dialect.HSQLDialect
HomeController.java
package com.riyan.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HomeController {
#RequestMapping("/")
public String getHomePage() {
return "login";
}
}
JSP:
login.jsp is present at WEB-INF->views->login.jsp
Followings are contents from pivotal server console:
Console Output:
23:08:47.239 [localhost-startStop-1] INFO org.apache.tiles.access.TilesAccess - Publishing TilesContext for context: org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext
23:08:47.989 [localhost-startStop-1] INFO o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Looking for #ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#5596ab: startup date [Fri Jun 05 23:08:32 PKT 2015]; root of context hierarchy
23:08:48.333 [localhost-startStop-1] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
23:08:48.333 [localhost-startStop-1] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
23:08:48.427 [localhost-startStop-1] INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
23:08:48.427 [localhost-startStop-1] INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
23:08:48.614 [localhost-startStop-1] INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
Please let me know if anything further is required.
I don't see anything in your config that is setting the server context to "/riyan". You should add this to your application.properties
server.contextPath=/riyan
Otherwise you will probably find your actual login.jps is at
http://localhost:8080/

Resources