Java Angular 6 Basic Auth从客户端返回401

Java Angular 6 Basic Auth从客户端返回401,java,angular,angular6,basic-authentication,Java,Angular,Angular6,Basic Authentication,所以我已经四处寻找我的问题的答案好长一段时间了,尝试了很多建议,但我似乎找不到答案 问题是,当我使用Postman检查基本身份验证是否有效时,我得到了一个200代码,一切正常,但当我尝试使用登录组件进行身份验证时,我得到了代码401,并说“访问此资源需要完全身份验证” 我对Angular是相当陌生的,对使用Basic Auth也是完全陌生的,所以我不知道为什么它可以与Postman一起使用,为什么它不能从应用程序中使用 谢谢你的帮助 以下是相关代码 登录.component.ts: onLogi

所以我已经四处寻找我的问题的答案好长一段时间了,尝试了很多建议,但我似乎找不到答案

问题是,当我使用Postman检查基本身份验证是否有效时,我得到了一个200代码,一切正常,但当我尝试使用登录组件进行身份验证时,我得到了代码401,并说“访问此资源需要完全身份验证”

我对Angular是相当陌生的,对使用Basic Auth也是完全陌生的,所以我不知道为什么它可以与Postman一起使用,为什么它不能从应用程序中使用

谢谢你的帮助

以下是相关代码

登录.component.ts:

onLogin(form: NgForm) {
    /* ... */
    let headers = new Headers();
    let userCredentials = user.userName + ":" + user.password;
    headers.append("Origin", "http://localhost:8080");
    headers.append("Authorization", "Basic " + btoa(userCredentials));

    return this.http.post('http://localhost:8080/api/users/login', headers).subscribe(
      (response) => {
        /* ... */
      },
      (error) => {
        console.log(error);
      }
    );
}
服务器端的终结点:

@PostMapping(LOG_IN)
public ResponseEntity<User> login() {
    return ResponseEntity.ok().build();
}
CustomBasicAuthenticationEntryPoint:

public class CustomBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void commence(final HttpServletRequest request, 
            final HttpServletResponse response, 
            final AuthenticationException authException) throws IOException, ServletException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName() + "");

        PrintWriter writer = response.getWriter();
        writer.println("HTTP Status 401 : " + authException.getMessage());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("MY REALM");
        super.afterPropertiesSet();
    }
}
MyUserDetails服务:

@Service
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private AuthenticatedUser authenticatedUser;

    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<User> oUser = userRepository.findByUserName(username);

        if (!oUser.isPresent()) {
            throw new UsernameNotFoundException(username);
        }

        User user = oUser.get();
        authenticatedUser.setUser(user);
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
    grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().toString()));

        return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), grantedAuthorities);
    }
}
@服务
公共类MyUserDetailsService实现UserDetailsService{
@自动连线
私有用户存储库用户存储库;
@自动连线
私有身份验证用户身份验证用户;
@凌驾
@事务(只读=真)
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException{
可选的oUser=userRepository.findByUserName(用户名);
如果(!oUser.isPresent()){
抛出新用户名NotFoundException(用户名);
}
User=oUser.get();
authenticatedUser.setUser(用户);
Set grantedAuthories=new HashSet();
添加(新的SimpleGrantedAuthority(user.getRole().toString());
返回新的org.springframework.security.core.userdetails.User(User.getUserName(),User.getPassword(),grantedAuthories);
}
}

这是因为在发送请求之前,浏览器已将选项方法发送到服务器,请尝试通过允许选项方法更新安全配置。像这样

protected void configure(HttpSecurity http) throws Exception
{
     http
    .csrf().disable()
    .authorizeRequests()
      .antMatchers(HttpMethod.OPTIONS,"/path/to/allow").permitAll()//allow CORS option calls
      .antMatchers("/resources/**").permitAll()
      .anyRequest().authenticated()
    .and()
    .formLogin()
    .and()
    .httpBasic();
}

您需要将标题作为post方法的第三个参数传递。第二个是身体

return this.http.post('http://localhost:8080/api/users/login', {}, {headers}).subscribe(
  (response) => {

如果您使用的是angular 6,那么您真的应该使用新的
HttpClient
类,旧的
Http
类被弃用了

我以前已经尝试过一次了。我又试了一次,但根本没用。在ChromeDevToolsInNetwork选项卡中,我看到两个登录请求,一个是OPTIONS,返回值为200,但后面的一个是POST,返回值为401。我假设选项一是飞行前?您的http实例的类型是什么?Http还是HTTPClient?它是Http。这会导致问题吗?哦,我的天啊,谢谢你!我简直不敢相信我花了几个小时的调试和谷歌搜索才发现这一直都是一个这样的打字错误!非常感谢D
return this.http.post('http://localhost:8080/api/users/login', {}, {headers}).subscribe(
  (response) => {