One controller can be reached but others cannot - java

Main Application Class: (It was going to be using JSP but realized the trouble with Spring Boot):
package com.MBS.Consulting.jsp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Configuration;
#Configuration
#SpringBootApplication(scanBasePackages="com.MBS.Consulting.jsp")
public class SampleWebJspApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SampleWebJspApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleWebJspApplication.class, args);
}
}
WelcomeController - In sub folder of main class (this controller is accessible):
package com.MBS.Consulting.jsp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class WelcomeController {
#GetMapping("/")
public String index() {
return "static/index";
}
#GetMapping("/Home")
public String welcome() {
return "Welcome/welcome";
}
#GetMapping("/ContactUs")
public String contactUs() {
return"Welcome/contact_Us";
}
#GetMapping("/AboutUs")
public String aboutUs() {
return "Welcome/about_us";
}
}
CustomerController - Does not even show that it is called with AOP. The package name is the same as the last controller. I do need to login using Spring Security to reach this page. It allows me to login and then gives me 404.
package com.MBS.Consulting.jsp.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.MBS.Consulting.jsp.entity.Customers;
import com.MBS.Consulting.jsp.entity.Users;
import com.MBS.Consulting.jsp.services.CustomersService;
#Controller
#RequestMapping("/Customer")
public class CustomerController {
#Autowired
private CustomersService customerService;
#GetMapping("/Home")
public String customerHome() {
return "Customer/Customer_Home";
}
}
Security config:
Not sure if I really need this or not but added it just to make sure that it couldn't be causing the problem.
package com.MBS.Consulting.jsp.config;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class DemoSecurityConfig {
// add a reference to our security data source
#Autowired
#Qualifier("securityDataSource")
private DataSource securityDataSource;
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((auth) -> {
try {
auth
.antMatchers("/Admin/**").hasRole("ADMIN")
.antMatchers("/Billing/**").hasAnyRole("ADMIN", "CUSTOMER", "EMPLOYEE")
.antMatchers("/Contacts/**").hasAnyRole("ADMIN", "EMPLOYEE")
.antMatchers("/Customer/**").hasAnyRole("ADMIN", "CUSTOMER")
.antMatchers("/Order/**").hasAnyRole("ADMIN", "CUSTOMER", "EMPLOYEE")
.antMatchers("/Plan/**").hasAnyRole("ADMIN", "CUSTOMER", "EMPLOYEE")
.antMatchers("/Services/**").hasAnyRole("ADMIN", "CUSTOMER", "EMPLOYEE")
.antMatchers("/Welcome", "/Login").permitAll()
.and()
.formLogin()
.and()
.logout()
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
)
.httpBasic();
return http.build();
}
}
Project structure:
I hope the image shows up due just to show the project structure and that I believe the controllers are in the correct location to not be a problem for Spring Boot.
In the logs for console I get no information at all when visit CustomerController, but I do get a 404 Error. The web address I visit is http://localhost:8080/Customer/Home to try to call CustomerController. I am unsure what will cause this and if someone could explain what I did wrong.
I did search on it and I was going to try and configure the dispatcher servlet but it should of been auto configured. I believe if it reaching one it should be able to reach the other if it is the same folder. Also I understand the it needs to be in the sub folder of the main class. Finally I checked to see if it was the mapped right since I used folders in the template folder.

While mappings were correct and the project structure is correct it was unable to reach controllers due to spring security. The security FilterChain in the screen shot is missing two asterisks on the permit all controllers.
this:
.antMatchers("/","/Welcome", "/Login").permitAll()
should be:
.antMatchers("/**","/Welcome/**", "/Login/**").permitAll()

Related

type org.springframework.security.authentication.encoding.PasswordEncoder cannot be resolved. It is indirectly referenced from required .class files

Hi there so I'm trying to create a Spring Security Login page which roots back to my DB(sql server) where my credentials are stored.
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
//Some imports like JDBC template and beanrowmapper are present but dont mind them.. as i was trying somethings out..
#Configuration
#EnableWebSecurity
public class SecurityConfigWithDB extends WebSecurityConfigurerAdapter{
#Autowired
private DataSource dataSource;
#Bean
public PasswordEncoder passwordEncoder1() {
return new BCryptPasswordEncoder();
}
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.passwordEncoder(new BCryptPasswordEncoder()) // this is where i get the error//
.dataSource(dataSource)
.usersByUsernameQuery("Select UserName, Password, Enable FROM LoginDetails WHERE Username=?")
.authoritiesByUsernameQuery("Select UserName, Role FROM LoginDetails WHERE Username=?");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and()
.logout().permitAll();
}
}
And the error goes like :
The type org.springframework.security.authentication.encoding.PasswordEncoder cannot be resolved. It is indirectly referenced from required .class files

Swagger is not showing any controllers or endpoints

Swagger Api Docs Image
I am working on adding / integrating swagger in my springboot project. I have tried different things but its not got fixed. All that is showing now is white page without any endpoints or controllers and just an empty page with swagger logo.
Swagger URL is : http://localhost:8080/swagger-ui.html
My swagger configurations are given below:
package com.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#SpringBootApplication(scanBasePackages = {"com.app.controller"})
public class StoreApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
try {
SpringApplication.run(StoreApplication.class, args);
}catch (Throwable throwable){
System.out.println(throwable.toString());
throwable.printStackTrace();
}
}
}
Here is my controller code.
My Controller
package com.app.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#CrossOrigin
#RestController
public class CustomersController {
#RequestMapping(value = "/customers", method = RequestMethod.GET)
ResponseEntity<?> getAllCustomers(){
return ResponseEntity.status(HttpStatus.OK).body(null);
}
#RequestMapping(value = "/customer", method = RequestMethod.POST)
ResponseEntity<?> createCustomer(){
return ResponseEntity.status(HttpStatus.OK).body(null);
}
}
Here is the main class
Main Class
package com.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#SpringBootApplication(scanBasePackages = {"com.app.controller"})
public class StoreApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
try {
SpringApplication.run(StoreApplication.class, args);
}catch (Throwable throwable){
System.out.println(throwable.toString());
throwable.printStackTrace();
}
}
}
This is my app config file
AppConfig
package com.app.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class AppConfig implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry){
// registry.addRedirectViewController("/docApi/v2/api-docs","/v2/api-docs");
registry.addViewController("/welcome").setViewName("Welcome");
}
}
First, try to add swagger config like this:
#EnableSwagger2
#Configuration
public class SwaggerConfig {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.app"))
.paths(PathSelectors.any())
.build();
}
}
then add some annotation in your controller like this:
package com.app.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#CrossOrigin
#RestController
#Api
public class CustomersController {
#RequestMapping(value = "/customers", method = RequestMethod.GET)
#ApiOperation(value = "get all", tags = "customer")
ResponseEntity<?> getAllCustomers(){
return ResponseEntity.status(HttpStatus.OK).body(null);
}
#RequestMapping(value = "/customer", method = RequestMethod.POST)
#ApiOperation(value = "create", tags = "customer")
ResponseEntity<?> createCustomer(){
return ResponseEntity.status(HttpStatus.OK).body(null);
}
}
hope this would fix your problem. Then try to access the url: http://127.0.0.1:8080/swagger-ui/index.html, pay attention not the url http://localhost:8080/swagger-ui.html.

The method withDefaults() is undefined for the type SecurityConfiguration [duplicate]

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;

Spring Boot application endpoint returns 403

I'm new to Spring Boot and currently stuck. I followed this (https://github.com/AppDirect/service-integration-sdk/wiki) Tutorial, as I want to implement an application that integrates itself into AppDirect. In the log I can see that the endpoints get created and mapped:
2018-10-29 16:32:48.898 INFO 8644 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/v1/integration/processEvent],methods=[GET],produces=[application/json]}" onto public org.springframework.http.ResponseEntity<com.appdirect.sdk.appmarket.events.APIResult> com.appdirect.sdk.appmarket.events.AppmarketEventController.processEvent(javax.servlet.http.HttpServletRequest,java.lang.String)
But when I try to access the endpoint (http://localhost:8080/api/v1/integration/processEvent) with Browser or Http-Requester I get the following response:
{timestamp":"2018-10-29T08:50:13.252+0000","status":403,"error":"Forbidden","message":"Access Denied","path":"/api/v1/integration/processEvent"}
My application.yml looks like this:
connector.allowed.credentials: very-secure:password
server:
use-forward-headers: true
tomcat:
remote_ip_header: x-forwarded-for
endpoints:
enabled: true
info:
enabled: true
sensitive: false
health:
enabled: true
sensitive: false
time-to-live: 5000
info:
build:
name: #project.name#
description: #project.description#
version: #project.version#
This is my Application.java:
package de.....;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.http.MediaType;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
public class Application extends WebMvcConfigurerAdapter {
public static void main(String... args) {
SpringApplication.run(RootConfiguration.class, args);
}
/**
* Hack to make Spring Boot #Controller annotated classed to recognize the 'x-www-form-urlencoded' media type
*
* #param converters
*/
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FormHttpMessageConverter converter = new FormHttpMessageConverter();
MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", Charset.forName("UTF-8"));
converter.setSupportedMediaTypes(Collections.singletonList(mediaType));
converters.add(converter);
super.configureMessageConverters(converters);
}
}
And this is the RootConfiguration.java:
package de.....;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import com.appdirect.sdk.ConnectorSdkConfiguration;
import com.appdirect.sdk.appmarket.DeveloperSpecificAppmarketCredentialsSupplier;
import com.appdirect.sdk.credentials.StringBackedCredentialsSupplier;
import de.....;
#Configuration
#Import({
ConnectorSdkConfiguration.class,
EventHandlersConfiguration.class
})
#EnableAutoConfiguration
public class RootConfiguration {
#Bean
public DeveloperSpecificAppmarketCredentialsSupplier environmentCredentialsSupplier(#Value("${connector.allowed.credentials}") String allowedCredentials) {
return new StringBackedCredentialsSupplier(allowedCredentials);
}
}
Any help is appreciated as intensive googleing didn't help.
Thanks in advance.
Adding the following class and registering it in Application.java solved my problem:
package de.......;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
#Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers("/").permitAll();
}
}

Testing spring-boot security, Thymeleaf error

I'm using Thymeleaf with Spring-boot and I get a problem testing the security #withmockuser.
This is the code for testing the controller
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#SuppressWarnings("SpringJavaAutowiringInspection")
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = SecurityConfiguration.class)
#WebMvcTest(IndexController.class)
public class IndexControllerTest {
#Autowired
private MockMvc mvc;
#MockBean
private IndexController IndexController;
#Test
#WithMockUser
public void testAuthenticated() throws Exception {
this.mvc.perform(get("/"))
.andExpect(status().is(200));
}
}
And this is the controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class IndexController {
private DemoshopService demoshopService;
#Autowired
public void setDemoshopService(DemoshopService demoshopService) {
this.demoshopService = demoshopService;
}
#RequestMapping(value = "/", method = RequestMethod.GET)
public String list(Model model) {
model.addAttribute("demoshops", demoshopService.listAllDemoshops());
return "index";
}
}
It will give me the following error
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception processing template ()
Does this mean Thymeleaf reads "/" as an template?
Without #withMockUser it does what I'm expecting.
Thank you for the help.
EDIT:
as requested the security configuration:
import org.springframework.beans.factory.annotation.Autowired;
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;
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**").permitAll()
.antMatchers("/images/**").permitAll()
.antMatchers("/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("test1").password("password").roles("USER")
.and()
.withUser("test2").password("password").roles("USER")
.and()
.withUser("test3").password("password").roles("USER")
.and()
.withUser("test4").password("password").roles("USER")
.and()
.withUser("test5").password("password").roles("USER")
.and()
.withUser("test6").password("password").roles("USER");
}
}
The usernames are normally e-mail address but I changed them for now.
Without parameters #WithMockUser will run test with the username "user", the password "password", and the roles "ROLE_USER".
Use #WithMockUser(username="test1",roles={"USER"}) to run test for test1 user for example.

Categories