You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

认证成功后如何调用Controller的login方法返回响应

让Spring Security认证成功后调用Controller方法返回响应

Alright, let's break down why your login() controller method isn't firing and how to adjust your setup to make it work as expected:

问题根源

Your MobileAuthenticationFilter is intercepting the /api/users/login request first. By default, once authentication succeeds in this filter, Spring Security will use the configured AuthenticationSuccessHandler to handle the response directly—it doesn't forward the request to the DispatcherServlet (and thus your controller). That's why your controller method never gets called.

具体实现方案

Here's how to modify your code to let the request flow to your controller after successful authentication:

  1. Adjust the Authentication Success Handler in your Filter Bean
    Remove your current success handler logic that prints the request, and instead configure it to forward the request to your controller after storing the authentication in the security context.

    @Bean
    public MobileAuthenticationFilter mobileAuthenticationFilter(ObjectMapper objectMapper) throws Exception {
        MobileAuthenticationFilter mobileAuthenticationFilter = new MobileAuthenticationFilter(objectMapper);
        mobileAuthenticationFilter.setAuthenticationManager(authenticationManager());
        mobileAuthenticationFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            // Store the authenticated user in SecurityContext so the controller can access it
            SecurityContextHolder.getContext().setAuthentication(authentication);
            // Forward the request to the controller's login endpoint
            request.getRequestDispatcher(request.getRequestURI()).forward(request, response);
        });
        return mobileAuthenticationFilter;
    }
    
  2. Verify your Controller Method works with Authenticated Context
    Your existing login() method uses a Principal principal parameter—once the authentication is stored in SecurityContextHolder, Spring will automatically inject the authenticated Authentication object as the Principal, so this will work seamlessly. You can even cast it to UsernamePasswordAuthenticationToken if you need specific user details:

    public TokenResponse login(@RequestBody LoginUserRequest loginUserRequest, Principal principal) {
        // Optional: Get authenticated user details
        UsernamePasswordAuthenticationToken authToken = (UsernamePasswordAuthenticationToken) principal;
        String username = authToken.getName();
        // Return your token response as before
        return new TokenResponse().setAccessToken("token");
    }
    
  3. Ensure Security Config Doesn't Block the Forwarded Request
    Your existing WebSecurityConfigurerAdapter setup already permits access to /api/users/login, so no changes are needed here. The forwarded request will bypass further authentication checks because the SecurityContext already contains a valid authentication.

  4. Optional: Clean Up the Filter's Request Parsing
    Your current attemptAuthentication method manually reads the request body with a BufferedReader—you can simplify this using the ObjectMapper directly with the request input stream:

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            LoginUserRequest loginUserRequest = objectMapper.readValue(request.getInputStream(), LoginUserRequest.class);
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(loginUserRequest.getLogin(), loginUserRequest.getPassword());
            return getAuthenticationManager().authenticate(token);
        } catch (IOException e) {
            throw new BadCredentialsException("Failed to parse login request body", e);
        }
    }
    

How it works now

When a login request comes in:

  1. MobileAuthenticationFilter intercepts it, parses the credentials, and authenticates the user.
  2. On success, it stores the authentication in SecurityContextHolder and forwards the request to your controller's /api/users/login endpoint.
  3. The controller method runs, uses the authenticated principal if needed, and returns the TokenResponse following your annotation-based response rules.

内容的提问来源于stack exchange,提问作者Piotr Olaszewski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 21:17:53