spring-security Spring套+角形:尝试身份验证请求参数为空

xwmevbvl  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(174)

我正在制作一个Angular应用程序作为前端,它有一个Springboot后端。我已经设置了SpringSecurity来处理登录,如果我尝试使用Postman,一切都正常,但是当我尝试使用Angular登录时,“request.getParameter”调用总是返回“null”。我尝试过用几种方法来改变它,但结果总是一样。
成功登录将返回有关用户和令牌的信息。
下面是Java部分:

@Configuration
@EnableWebSecurity
@ComponentScan
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Lazy
    @Autowired
    CurrentUserDetailsServiceImpl userDetailsService;
    @Autowired
    TokenAuthenticationService tokenAuthService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .headers().cacheControl().disable();
        http
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http
                .headers().xssProtection();
        http
                .exceptionHandling().and()
                .anonymous().and()
                .servletApi().and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/auth/**").permitAll()
                .anyRequest().authenticated().and()
                .addFilterBefore(
                        new LoginFilter("/auth/login", authenticationManager(), tokenAuthService),
                        UsernamePasswordAuthenticationFilter.class)
                // Custom Token based authentication based on the header previously given to the
                // client
                .addFilterBefore(new JWTFilter(tokenAuthService), UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
                .ignoring()
                // Allow anonymous resource requests
                .antMatchers("/favicon.ico");
    }
}

LoginFilter可以执行很多操作,但这是最基本的操作:

public class LoginFilter extends AbstractAuthenticationProcessingFilter {
    private TokenAuthenticationService tokenAuthenticationService;

    public LoginFilter(String urlMapping, AuthenticationManager authenticationManager, TokenAuthenticationService tokenAuthenticationService) {
        super(new AntPathRequestMatcher(urlMapping));
        setAuthenticationManager(authenticationManager);
        this.tokenAuthenticationService = tokenAuthenticationService;
    }

    @Override
    @Transactional
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        System.out.println("USERNAME: " + username + " - PASSWORD: " + password);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
            Authentication authentication) throws IOException, ServletException {
        CurrentUser loggedUser = (CurrentUser) authentication.getPrincipal();
        ...
    }
}

最后,Angular表单执行一些验证并调用服务:

@Injectable({
    providedIn: 'root'
})
export class LoginService {
    apiUrl: string = environment.API_URL;
    constructor(private http: HttpClient) {}
    login(data: LoginInterface): Observable<LoginResult> {
        const formData: string =
            'username=' + data.username + '&password=' + data.password;

        const httpOptions = {
            headers: new HttpHeaders({
                'Content-Type': 'application/x-www-form-urlencoded'
            })
        };

        return this.http.post<LoginResult>(
            this.apiUrl + '/auth/login',
            formData,
            httpOptions
        );
    }
}

我做错了什么?为什么它和 Postman 合作?
谢谢你!
编辑:根据要求,以下是Chrome中呼叫的控制台详细信息
标题:

正文:

Postman 信头:

Postman 数据:

下面的Eclipse显示了到达的空值:
x1c4d 1x指令集
谢谢你!

pdsfdshx

pdsfdshx1#

您可能可以通过使用HttpParams作为请求主体来实现这一点:

login(data: LoginInterface): Observable<LoginResult> {
  const params = new HttpParams({
    fromObject: {
      username: data.username,
      password: data.password,
    },
  });
  return this.http.post<LoginResult>(this.apiUrl + '/auth/login', params, {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
  });
}

相关问题