2017-12-05 1 views
0

표준 스프링 보안 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 &copy; 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"; 
    } 


} 

답변

0

봄 보안 formLogin 기본 INTE에 대한 "/ login"요청에 동의하지 않으면 로그인 페이지 URL이이 필터와 충돌하는 "/ login"임을 알게됩니다. 이 같은 로그인 페이지 URL을 정의 할 수 있습니다

.formLogin() 
     .loginPage("/page/login.html").permitAll() 

및 로그인에서 다음 컨트롤러 매핑을 변경 ->/페이지/로그인