표준 스프링 보안 API를 사용하여 보안 웹 페이지를 테스트하려고합니다. UserDetailService를 구현하여 자체 사용자 인증 서비스를 구현했습니다. 그러나 내 응용 프로그램에 로그인 할 때마다/login api는 302 리디렉션을 계속 반환합니다. 좋은 자격 증명과 나쁜 자격 증명을 수동으로 테스트하여 로그인 페이지가 올바르게 작동하는지 확인하고 자격 증명이 좋은지 여부에 따라 제대로 홈페이지에 올바르게 인증되었지만 여전히/login에 302가 반환되었습니다. 임/로그인 요청을 수행 할 때 Spring/Thymeleaf가 302 리디렉션을 반환하는 이유가 궁금합니다. 이것은 봄 보안으로 잠겨있을 때 나의 지키는 끝점을 테스트 할 수있는 능력을 방해합니다.스프링 부트 보안 인증 - 302 리디렉션
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JwtTokenFilter jwtTokenFilter() {
return new JwtTokenFilter();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.cors()
.and()
.authorizeRequests().antMatchers("/profiles/**","/img/**","/resources","/v2/**","/users", "/login", "/error/**", "/keepalive", "/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout();
http.addFilterBefore(jwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(asList("*"));
configuration.setAllowedMethods(asList("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH"));
// setAllowCredentials(true) is important, otherwise:
// The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
configuration.setAllowCredentials(true);
// setAllowedHeaders is important! Without it, OPTIONS preflight request
// will fail with 403 Invalid CORS request
configuration.setAllowedHeaders(asList("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
Login.html 페이지
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
>
<head>
<title>Login</title>
<div th:replace="fragments/header :: header-css"/>
</head>
<body class="white-bg">
<div th:replace="fragments/header :: header"/>
<div class="middle-box text-center loginscreen">
<div>
<div>
<h1 class="logo-name"></h1>
</div>
<h3>Welcome to </h3>
<p>Login in. To see it in action.</p>
<form th:action="@{/login}" method="post">
<fieldset>
<div th:if="${param.error}">
<div class="alert alert-danger">
Invalid username and password.
</div>
</div>
<div th:if="${param.logout}">
<div class="alert alert-info">
You have been logged out.
</div>
</div>
<div class="form-group">
<input type="text" name="username" id="username" class="form-control"
placeholder="UserName" required="true" autofocus="true"/>
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control"
placeholder="Password" required="true"/>
</div>
<input type="submit" class="btn btn-lg btn-primary btn-block" value="Sign In"/>
<a href="#"><small>Forgot password?</small></a>
<p class="text-muted text-center"><small>Do not have an account?</small></p>
<a class="btn btn-sm btn-white btn-block" href="register.html">Create an account</a>
</fieldset>
</form>
<p class="m-t"> <small>DigiProof Company © 2017</small> </p>
</div>
</div>
BaseController.java 라우팅
@Controller
public class BaseController {
@Autowired
private UserService userService;
@GetMapping("/")
public String homeMain() {
return "home";
}
@GetMapping("/home")
public String home() {
return "home";
}
@GetMapping("/login")
public String login(Principal principal) {
if (principal!=null && ((Authentication)principal).isAuthenticated())
return "redirect:/home";
else
return "login";
}
@RequestMapping(value="/registration", method = RequestMethod.GET)
public ModelAndView registration(){
ModelAndView modelAndView = new ModelAndView();
User user = new User();
modelAndView.addObject("user", user);
modelAndView.setViewName("register");
return modelAndView;
}
@RequestMapping(value = "/registration", method = RequestMethod.POST)
public ModelAndView createNewUser(@Valid User user, BindingResult bindingResult) {
ModelAndView modelAndView = new ModelAndView();
User userByEmailExists = userService.findUserByEmail(user.getEmail());
if (userByEmailExists != null) {
bindingResult
.rejectValue("email", "error.user",
"There is already a user registered with the email provided");
}
if (bindingResult.hasErrors()) {
modelAndView.setViewName("register");
} else {
userService.save(user);
modelAndView.addObject("successMessage", "User has been registered successfully");
modelAndView.addObject("user", new User());
modelAndView.setViewName("register");
}
return modelAndView;
}
@GetMapping("/profile")
public String profile() {
return "profile";
}
@GetMapping("/activity")
public String activity() {
return "activity";
}
@GetMapping("/teams")
public String teams() {
return "teams";
}
@GetMapping("/404")
public String error404() {
return "/error/403";
}
@GetMapping("/403")
public String error403() {
return "/error/403";
}
@GetMapping("/500")
public String error500() {
return "/error/500";
}
@GetMapping("/error")
public String error() {
return "/error/500";
}
}