Angular 6 Basic Auth从客户端返回401

sn4ckhun:

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

问题是,当我使用邮递员检查基本身份验证是否有效时,我会收到200代码,这一切都很好,但是当我尝试使用登录组件进行身份验证时,我会立即获得代码401,并说“需要完全身份验证访问此资源”。

我对Angular不太熟悉,对使用Basic Auth也不陌生,所以我不知道为什么它可以与Postman一起使用,为什么不可以在应用程序中使用。

任何帮助表示赞赏

以下是相关代码

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();
}

WebSecurityConfig:

@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();
    }
}

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();
    }
}

MyUserDetailsS​​ervice:

@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);
    }
}
大卫 :

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

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

如果您使用的是角度6,则实际上应该使用新的HttpClient类,而旧的Http类已被弃用

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章