#spring-security
Вопрос:
Я работаю над несколькими учебниками, чтобы реализовать свою собственную безопасность в рамках своего проекта.
Проблема в том, что, как было настроено system.out.println
, вызовы внутри класса, расширения WebSecurityConfigurerAdapter
не выполняются. Это означает, что класс безопасности вообще не вызывается. Сообщений об ошибках нет, и я также могу перейти на любую страницу сайта без перенаправления авторизации на страницу входа. Кроме того, страница входа в систему просто публикует сообщение и выводит меня на домашнюю страницу сайта.
Вот пользовательский адаптер конфигуратора веб-безопасности:
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.authentication.dao.DaoAuthenticationProvider;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
ShopmeUserDetailsService shopmeUserDetailsService;
@Bean
public UserDetailsService userDetailsService() {
return new ShopmeUserDetailsService();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
public DaoAuthenticationProvider authenicationProvider() {
System.out.println("In Dao auth security");
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
System.out.println("In configure security");
//auth.authenticationProvider(authenicationProvider());
//auth.userDetailsService(shopmeUserDetailsService);
auth
.inMemoryAuthentication()
.withUser("user1")
.password(passwordEncoder().encode("user1Pass"))
.roles("USER")
.and()
.withUser("user2")
.password(passwordEncoder().encode("user2Pass"))
.roles("USER")
.and()
.withUser("admin")
.password(passwordEncoder().encode("adminPass"))
.roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("In configure security auth");
http
.authorizeRequests()
.anyRequest().authenticated() //all URLs are allowed by any authenticated user, no role restrictions.
.and()
.formLogin() //enable form based authentication
.loginPage("/login") //use a custom login URI
.usernameParameter("email")
.permitAll(true) //login URI can be accessed by anyone
.and()
.logout() //default logout handling
.permitAll(); //allow all as it will be accessed when user is not logged in anymore
}
@Override
public void configure(WebSecurity web) throws Exception{
System.out.println("In configure ignorings");
web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**" );
}
}
Вот основной класс приложения:
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
@EntityScan({"com.shopme.common.entity", "com.shopme.admin.user"})
public class ShopmeBackendApplication {
public static void main(String[] args) {
SpringApplication.run(ShopmeBackendApplication.class, args);
}
}
Мой главный контроллер:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class MainController {
@GetMapping("")
public String viewHomePage() {
return "index";
}
@GetMapping("/login")
public String viewLoginPage() {
System.out.println("In viewLoginPage method - MainController");
return "login";
}
@PostMapping("/login")
public String login() {
System.out.println("login attempt");
return "index";
}
}
И, наконец, мой другой контроллер для страниц администратора:
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.shopme.admin.FileUploadUtil;
import com.shopme.common.entity.Role;
import com.shopme.common.entity.User;
@Controller
public class UserController {
@Autowired
private UserService userService;
//private final java.nio.file.Path root = Paths.get("user_photos");
//Updated method to list the first page of users
@GetMapping("/users")
public String listFirstPage(Model model) {
return listUsersByPage(1, model, null);
}
@GetMapping("/users/new")
public String newUser(Model model) throws IOException {
System.out.println("new User method");
List<Role> roles = userService.listRoles();
//System.out.println(multiPartFile.getOriginalFilename());
//String fileName =
StringUtils.cleanPath(multiPartFile.getOriginalFilename());
//String uploadDir = "user_photos";
//FileUploadUtil.saveFile(uploadDir, fileName, multiPartFile);
//Files.copy(multiPartFile.getInputStream(), ((java.nio.file.Path)
this.root).resolve(multiPartFile.getOriginalFilename()));
User user = new User();
user.setEnabled(true);
model.addAttribute("user", user);
model.addAttribute("roles", roles);
model.addAttribute("pageTitle", "Create New User");
return "user_form";
}
@PostMapping("/users/save")
public String saveUser(User user, RedirectAttributes redirect, @RequestParam("image") MultipartFile multiPartFile) throws IOException {
System.out.println(user);
System.out.println(multiPartFile.getOriginalFilename());
String fileName = StringUtils.cleanPath(multiPartFile.getOriginalFilename());
String uploadDir = "user_photos";
FileUploadUtil.saveFile(uploadDir, fileName, multiPartFile);
//Files.copy(multiPartFile.getInputStream(), ((java.nio.file.Path) this.root).resolve(multiPartFile.getOriginalFilename()));
userService.save(user);
redirect.addFlashAttribute("message", "User has been saved successfully!");
return "redirect:/users/page/1?keyword=" user.getId();
}
@GetMapping("/users/edit/{id}")
public String editUser(@PathVariable(name = "id") Integer id, Model model, RedirectAttributes redirect){
try {
Optional<User> user = userService.getUserById(id);
List<Role> roles = userService.listRoles();
model.addAttribute("user", user);
model.addAttribute("roles", roles);
model.addAttribute("pageTitle", "Edit User (ID: " id ")");
return "user_form";
} catch (UserNotFoundException ex) {
redirect.addFlashAttribute("message", ex.getMessage());
return "redirect:/users";
}
}
@GetMapping("users/delete/{id}")
public String deleteUser(@PathVariable(name="id") Integer id, Model model, RedirectAttributes redirect) {
userService.deleteUserById(id);
redirect.addFlashAttribute("message", "User has been deleted successfully!");
return "redirect:/users";
}
@GetMapping("/users/{id}/enabled/{status}")
public String updateUserEnabledStatus(@PathVariable("id") Integer id, @PathVariable("status") boolean enabled, RedirectAttributes redirect) {
userService.updateUserEdabledStatus(id, enabled);
String status = enabled ? "enabled" : "disabled";
String message = "THe user Id " id " has been " status;
redirect.addFlashAttribute("message", message);
return "redirect:/users";
}
@GetMapping("/users/page/{pageNumber}")
public String listUsersByPage(@PathVariable(name = "pageNumber") int pageNumber, Model model, @Param("keyword") String keyword) {
Page<User> page = userService.listByPage(pageNumber, keyword);
List<User> userPagedList = page.getContent();
System.out.println("Pagenumber: " pageNumber);
System.out.println("Total Elements: " page.getTotalElements());
System.out.println("Totals Pages: " page.getTotalPages());
long startCount = (pageNumber - 1) * UserService.USERS_PER_PAGE 1;
long endCount = startCount UserService.USERS_PER_PAGE -1;
if(endCount > page.getTotalElements()){
endCount = page.getTotalElements();
}
model.addAttribute("totalPages", page.getTotalPages());
model.addAttribute("currentPage", pageNumber);
model.addAttribute("startCount", startCount);
model.addAttribute("endCount", endCount);
model.addAttribute("totalItems", page.getTotalElements());
model.addAttribute("users", userPagedList);
model.addAttribute("keyword", keyword);
return "users";
} //end listUserByPage
@GetMapping("/users/export/csv")
public void exportToCSV(HttpServletResponse response) throws IOException {
List<User> userList = userService.listAll();
UserCsvExporter exporter = new UserCsvExporter();
exporter.export(userList, response);
} //end exportToCsv
@GetMapping("/users/export/excel")
public void exportToExcel(HttpServletResponse response) throws IOException {
List<User> userList = userService.listAll();
UserExcelExporter exporter = new UserExcelExporter();
exporter.export(userList, response);
} //end exportToExcel
@GetMapping("/users/export/pdf")
public void exportToPdf(HttpServletResponse response) throws IOException {
List<User> userList = userService.listAll();
UserPdfExporter exporter = new UserPdfExporter();
exporter.export(userList, response);
} //end exportToPdf
} //end of class
Я потратил два дня на расследование этого дела, но безрезультатно… любая помощь была бы очень признательна.
Комментарии:
1. Почему вы исключаете автоматическую настройку Spring Security? Без него весенняя охрана не работает.
2. С тех пор я удалил это, оно было там в целях тестирования, чтобы исключить функциональность входа в систему.
Ответ №1:
Я понял, почему это не работает, ну, по крайней мере, у меня это работает с этим решением.
Я включил в WebSecurityConfig.class в стартовом классе проекта, как показано ниже:
@SpringBootApplication
@EntityScan({"com.shopme.common.entity", "com.shopme.admin.user"})
public class ShopmeBackendApplication {
public static void main(String[] args) {
SpringApplication.run(new Class[]
{ShopmeBackendApplication.class,
WebSecurityConfig.class}, args);
}
}
Комментарии:
1. это не то, как вы должны это решать, у вас, скорее всего, что-то не так в вашем приложении, и я предлагаю вам загрузить его на github и показать нам, потому что у вас, вероятно, возникнет больше проблем с этим решением. Проголосуйте против, так как это неверное решение проблемы.
2. Я согласен с вами в этом, я буду работать над загрузкой проекта на github, и, как вы упомянули, что-то еще пошло не так, не сканирование компонентов не обнаружит новый контроллер, который я добавил в проект. Существующие контроллеры работают, но не новые. Сообщу вам, когда проект появится на github…спасибо за помощь.
3. Все проблемы, с которыми вы сталкиваетесь, указывают мне на то, что у вас необычная структура проекта. Spring (по умолчанию) будет сканировать один и тот же и все подкаталоги из основного класса на предмет возможных аннотированных классов. Но я не могу видеть структуру вашего проекта
4. Toektmmlare — Вы были на правильном пути, я следовал учебнику, и где-то на этом пути файл проекта был поврежден, поэтому я удалил файл проекта, а затем воссоздал его, все ошибки и случайные ошибки исчезли.