当前位置: 首页 > 知识库问答 >
问题:

Spring Boot Security身份验证-302重定向

陈高寒
2023-03-14

我正在尝试测试我的web api,它使用标准的Spring Securityapi进行保护。我通过实现UserDetailService实现了自己的用户身份验证服务。然而,每当我登录到我的应用程序时,/login api总是返回302重定向。我通过手动测试好的凭据和坏的凭据来验证我的登录页面是否正常工作,并且根据凭据是否良好,它确实正确地对主页进行了身份验证,但是它仍然返回了302 for/login。我想知道为什么Spring/Thymeleaf在执行/login请求时返回302重定向。这妨碍了我在使用spring security锁定时测试任何受保护endpoint的能力。

@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());
}

登录。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";
    }


}

共有2个答案

夔宏深
2023-03-14

尝试禁用csrf

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
}

戈睿识
2023-03-14

弹性安全格式登录默认拦截"/登录"请求,我发现你的登录页面网址是"/登录",这是与此过滤器冲突。你可以这样定义你的登录页面网址:

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

然后从登录更改控制器映射--

 类似资料:
  • 我正在laravel中创建一个多身份验证系统,其中有两种类型的用户:管理员(由我创建)和用户(使用本地laravel身份验证系统)。 如果我以用户身份登录,当我尝试访问登录页面时,当我已经登录,它会将我重定向回仪表板,但如果我以管理员身份登录,当我再次访问管理员登录页面时,它会让我再次登录,尽管已经作为管理员登录。 以下是我的重定向身份验证类代码: 有人能解释一下发生了什么事吗?

  • 我的管理员控制器扩展了控制器类,在那里我使用方法加载视图页面并传递保护。config/auth.php也通过添加管理员保护和提供程序进行了修改。在app/Actions/Fortify文件夹中,我添加了AttemptToAuthenticate和ReDirectIfTwoFactorAuthenticate类,并更改了命名空间。我的管理员控制器还扩展了Guard。用户的重定向中间件和管理员的重定向

  • 遵循这个指南:https://www.youtube.com/watch?v=bqkt6eSsRZs 添加了从laravel docs的auth路由 创建登录/注册视图 创建 /home路线 自定义AuthController: 尝试访问身份验证/登录时,我遇到以下错误: 请求中出现错误异常。php第775行:。。未根据请求设置会话存储。 已将身份验证路由移动到中间件组。 成功注册,在数据库和会话

  • 我正在使用fire base制作一个反应原生应用程序,用于使用电子邮件登录im并通过身份验证。但是,有没有办法使用用户名和密码登录?

  • 我正在创建一个laravel应用程序与自定义多重身份验证。我正在跟随这篇文章进行多重身份验证。https://pusher.com/tutorials/multiple-authentication-guards-laravel 我已经创建了登录和注册控制器定义的警卫和提供者,一切正常,我能够注册用户并登录他们。我写了一页(http://127.0.0.1:8000/admin)只有当管理员登录时

  • 我目前正在使用FirebaseAuth和web小部件库firebaseui web开发基于VueJS的登录流原型。 成功认证后(无论是< code>password还是< code>google provider ),小部件加载栏会不断重复,firebaseui-web不会触发其< code > signinseccesswithauthresult 回调。但是对< code > identity