use*_*493 5 spring spring-mvc spring-security spring-boot
我正在尝试测试使用标准 Spring Security API 保护的 web api。我已经通过实现 UserDetailService 实现了我自己的用户身份验证服务。但是,每当我登录到我的应用程序时,/login api 都会不断返回 302 重定向。我通过手动测试良好的凭据和错误的凭据来验证我的登录页面是否正常工作,并且根据凭据是否正确,它确实正确地对主页进行了正确的身份验证,但是它仍然为 /login 返回了 302。我想知道为什么 Spring/Thymeleaf 在执行 /login 请求时会返回 302 重定向。这阻止了我在使用 Spring Security 锁定时测试任何受保护端点的能力。
@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());
}
Run Code Online (Sandbox Code Playgroud)
登录.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>
Run Code Online (Sandbox Code Playgroud)
用于路由的 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";
}
}
Run Code Online (Sandbox Code Playgroud)
spring security formLogin默认拦截“/login”请求,我发现您的登录页面url是“/login”,这与此过滤器冲突。您可以像这样定义您的登录页面网址:
.formLogin()
.loginPage("/page/login.html").permitAll()
Run Code Online (Sandbox Code Playgroud)
然后从登录 --> /page/login 更改控制器映射
| 归档时间: |
|
| 查看次数: |
14682 次 |
| 最近记录: |