在 Spring Boot 应用程序中的 Google 身份验证期间接收 302 状态代码

Receiving 302 Status Code during Google Authentication in Spring Boot Application

提问人:Kavindu Wijethunga 提问时间:8/15/2023 最后编辑:Linda Lawton - DaImToKavindu Wijethunga 更新时间:8/15/2023 访问量:159

问:

我正在开发一个集成了 Google 身份验证的 Spring Boot 应用程序。我设置了身份验证流程,将用户重定向到 Google 登录页面。但是,选择我的 Google 帐户后,我被重定向回 URL,并且我遇到了 .我看到的错误消息是“”。http://localhost:8080/david-core/oauth2/authorization/googlehttp://localhost:8080/david-core/oauth2/code/google302 status codetoo many requests

我已经检查了后端日志,但我没有看到任何明确的错误消息。同样,在网络选项卡中,我只看到 302 状态代码,没有其他信息。以下是请求和响应标头的详细信息:

请求 URL:

https://accounts.google.com/signin/oauth/consent?authuser=0&part=AJi8hAOEdMF1IEbyffElZiFCvtY0Kt7OvFyp0NsplSGhhNwKhj5q2BTwVoY6smr6UvyNJJM2guCHubu5hwhGWZnc1I6pHiSgeoGmhCZTa8BTRR40nW6-P5HDfIuyf_Wc0UhVV6jrvCqUxfngJfjEFHAR3DTMrlZfjEVzpMIstziuawocqs6kxAo3haS7ct5BeJYoDptPYqyWk12fFmSIxNJWmhCESUt2Ah2K6sSjvEv8NADUCsGEeBnr3NVDmJnpKAOuPhetCX_XaQ3Z44PnKrGeHe3_zC9ySrbtN9qpVLZqump-lkNsMoeJKCLEYy6eVlbDV8q4UezUj_SsG1-zUSdKjVV6RrDRQLmVv42gQj18hgGQX5ZBs279ubVHWBW2dgGzCsv6ok6_UHjrsQYtaeYtmRrEGkkVkEZ1u-mR-ZONTZyKfgkRgGlQ5jJ7hfcRo4ETXMKSLVeOIQa6nbwY6EyAdBurFfWIyQ&as=S1543709863%3A1692062127598219&client_id=33573278563-e6pfelv8h4e18lfmtgmnj5g5lmi0a655.apps.googleusercontent.com&pli=1&rapt=AEjHL4PGI_ts8e_DiJEmwW2WXe3pxJrhuefN6jAf7-5m7PLEgsNyyLpHDE7U-Z2DnV4cmJRcOBNanMXMY4f-w1u85mYclV7urQ

请求方式:GET

状态码:302

我已经彻底检查了我的后端,但我没有发现任何具体的错误。我应该寻找任何具体的东西或关于如何进一步解决此问题的任何建议吗?任何帮助将不胜感激。

法典:

Security Class`


`http
    .oauth2Login(oauth2Login ->
       oauth2Login
           .loginProcessingUrl("/login")
           .loginPage("/oauth2/code/google")
           .userInfoEndpoint()
           .userService(oauthUserService)
           .and()
              .successHandler(new AuthenticationSuccessHandler() {
              @Override
              public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,Authentication authentication) throws IOException, ServletException {
                    CustomOAuth2User oauthUser = (CustomOAuth2User) authentication.getPrincipal();
                          userService.processOAuthPostLogin(oauthUser.getEmail());
                          response.sendRedirect("http://localhost:3000");
                         }
                       })
                );`



`CustomOAuth2User class`



`public class CustomOAuth2User implements OAuth2User {

    private OAuth2User oAuth2User;

    public CustomOAuth2User(OAuth2User oAuth2User) {
        this.oAuth2User = oAuth2User;
    }

    @Override
    public Map<String, Object> getAttributes() {
        return oAuth2User.getAttributes();
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return oAuth2User.getAuthorities();
    }

    @Override
    public String getName() {
        return oAuth2User.getAttribute("name");
    }

    public String getEmail() {
        return oAuth2User.<String>getAttribute("email");
    }
}`



`CustomOAuth2UserService class`



`@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException{
        OAuth2User user =  super.loadUser(userRequest);
        return new CustomOAuth2User(user);
    }
}`




`User Service`



`@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public void processOAuthPostLogin(String username) {
        UserEntity existUser = userRepository.findByUsername(username);

        if (existUser == null) {
            UserEntity newUser = new UserEntity();
            newUser.setUsername(username);
            newUser.setProvider(Provider.GOOGLE);
            //newUser.setEnabled(true);

            userRepository.save(newUser);
        }

    }
}`

我用这个 doucmentation 来完成代码:https://www.codejava.net/frameworks/spring-boot/oauth2-login-with-google-example

调试:我在 Spring Boot 应用程序的相关代码部分添加了调试语句,例如 Google 身份验证配置和控制器方法。但是,我无法在身份验证流程中捕获任何错误或意外行为。

我遇到了在Spring Boot应用程序中使用自定义JWT身份验证的情况。在此设置中,我将 URL 配置为不经过 JWT 过程,这部分按预期工作。当 URL 符合特定条件时,以下块中的代码将按预期执行:''

`if (request.getServletPath().equals("/user/add") || request.getServletPath().equals("/user/update") || /* ...other paths... */) {
    filterChain.doFilter(request, response);
}`

但是,当我深入研究我的代码库时,问题就出现了。尽管我有其他 API 可以在没有 JWT 身份验证的情况下工作,但在这种特殊情况下,在代码到达以下行之后:

`filterChain.doFilter(request, response);`
It doesn't execute the expected functions in my other classes. The program flow seems to be similar to other functional APIs, but the behavior is inconsistent.

为了提供上下文,这是我处理 JWT 身份验证的 doFilterInternal 方法的一部分:

`@Override
protected void doFilterInternal(HttpServletRequest request,
                                HttpServletResponse response,
                                FilterChain filterChain) throws ServletException, IOException {
    // ... (previous code)

    try {
        filterChain.doFilter(request, response);
    } catch (Exception e) {
        log.info("Error during login: {}", e.getMessage());
    }
}`

我已执行调试以跟踪执行流,但无法确定问题的确切点。值得注意的是,我已经成功地将这种方法用于其他端点,没有任何问题。我的期望是,与指定 URL 相关的函数应该在 filterChain.doFilter(request, response) 中按预期运行;块,就像其他端点一样。

是否有人遇到过类似的情况,或者可以就如何进一步解决此行为提供指导?任何见解或建议将不胜感激。

这是完整的代码

`public class CustomAuthorizationFilter extends OncePerRequestFilter {
    private final JwtConfig jwtConfig;
    private final SecretKey secretKey;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        if (request.getServletPath().equals("/user/add") || request.getServletPath().equals("/user/update") || /* ...other paths... */) {
            filterChain.doFilter(request, response);
        } else {
            String authorizationHeader = request.getHeader(jwtConfig.getAuthorizationHeader());

            if (Strings.isNullOrEmpty(authorizationHeader) || !authorizationHeader.startsWith(jwtConfig.getTokenPrefix())) {
                filterChain.doFilter(request, response);
            }

            String token = authorizationHeader.replace(jwtConfig.getTokenPrefix(), "");
            try {
                Jws<Claims> claimsJws = Jwts.parserBuilder()
                        .setSigningKey(secretKey)
                        .build()
                        .parseClaimsJws(token);

                Claims body = claimsJws.getBody();

                String username = body.getSubject();

                var authorities = (List<Map<String, String>>) body.get("authorities");

                Set<SimpleGrantedAuthority> simpleGrantedAuthorities = authorities.stream()
                        .map(m -> new SimpleGrantedAuthority(m.get("authority")))
                        .collect(Collectors.toSet());

                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        username,
                        null,
                        simpleGrantedAuthorities
                );

                SecurityContextHolder.getContext().setAuthentication(authentication);

            } catch (JwtException ex) {
                log.info("Error in login: {}", ex.getMessage());
                HashMap<String, String> error = new HashMap<>();
                error.put("error_message", ex.getMessage());
                response.setContentType(APPLICATION_JSON_VALUE);
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                new ObjectMapper().writeValue(response.getOutputStream(), error);
            }

            try {
                filterChain.doFilter(request, response);
            } catch (Exception e) {
                log.info("Error in login: {}", e.getMessage());
            }
        }
    }
}

`

spring-boot spring-security google-oauth http-status-code-302

评论


答: 暂无答案