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

Angular 6基本身份验证从客户端返回401

商绍元
2023-03-14

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

感谢任何帮助

以下是相关代码

log-in.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();
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors()
                .and()
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/h2/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .httpBasic()
                .authenticationEntryPoint(getBasicAuthEntryPoint())
                .and()
            .headers()
                .frameOptions().disable()
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser("admin").password("1234").roles("ADMIN");
    }

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    protected void configureAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());
    }

    @Bean
    public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint(){
        return new CustomBasicAuthenticationEntryPoint();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
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();
    }
}
@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);
    }
}

共有1个答案

柳和怡
2023-03-14

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

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

如果您使用的是angular 6,那么您实际上应该使用新的HttpClient类,而旧的HTTP类不推荐使用

 类似资料:
  • 问题内容: 我在Glassfish之上创建了一个JAX-WS Web服务,它需要基本的HTTP身份验证。 现在,我想为该Web服务创建一个独立的Java应用程序客户端,但是我不知道如何传递用户名和密码。 它可以与Eclipse的Web Service资源管理器一起使用,并检查连接线,我发现了这一点: 如何使用Java代码在此“授权”标头中传递用户名和密码?是散列还是类似的东西?什么是算法? 没有涉

  • 我不熟悉SSL和证书。我一直在做关于客户端证书认证的研究。我看过这个和wiki。 因此,如果我必须为我的B2B REST服务实现客户端证书身份验证解决方案,我应该执行以下操作 要求客户端生成自己的私钥,并为其公钥生成证书(CA 颁发?)。通过电子邮件或 USB 闪存盘发送该证书。 在服务器端将客户端的公共证书导入信任存储区并启用客户端身份验证 在握手期间,客户端会出示其证书并进行身份验证,因为服务

  • 授权服务器为进行客户端身份验证的目的,为Web应用客户端创建客户端凭据。授权服务器被鼓励考虑比客户端密码更强的客户端身份验证手段。Web应用程序客户端必须确保客户端密码和其他客户端凭据的机密性。 授权不得向本地应用程序或基于用户代理的应用客户端颁发客户端密码或其他客户端凭据用于客户端验证目的。授权服务器可以颁发客户端密码或其他凭据给专门的设备上特定安装的本地应用程序客户端。 当客户端身份验证不可用

  • 在向令牌端点发起请求时,机密客户端或其他被颁发客户端凭据的客户端必须如2.3节所述与授权服务器进行身份验证。客户端身份验证用于: 实施刷新令牌和授权码到它们被颁发给的客户端的绑定。当授权码在不安全通道上向重定向端点传输时,或者 当重定向URI没有被完全注册时,客户端身份验证是关键的。 通过禁用客户端或者改变其凭据从被入侵的客户端恢复,从而防止攻击者滥用被盗的刷新令牌。改变单套客户端凭据显然快于撤销

  • 如果客户端类型是机密的,客户端和授权服务器建立适合于授权服务器的安全性要求的客户端身份验证方法。授权服务器可以接受符合其安全要求的任何形式的客户端身份验证。 机密客户端通常颁发(或建立)一组客户端凭据用于与授权服务器进行身份验证(例如,密码、公/私钥对)。授权服务器可以与公共客户端建立客户端身份验证方法。然而,授权服务器不能依靠公共客户端身份验证达到识别客户端的目的。 客户端在每次请求中不能使用一

  • 有时需要对某些网络资源(如Servlet、JSP等)进行访问权限验证,也就是说,有访问权限的用户才能访问该网络资源。进行访问权限验证的方法很多,但通过HTTP响应消息头的WWW-Authenticate字段进行访问权限的验证应该是众多权限验证方法中比较简单的一个。 通过HTTP响应消息头的WWW-Authenticate字段可以使浏览器出现一个验证对话框,访问者需要在这个对话框中输入用户名和密码,