【问题标题】:Angular app getting 401 error when sending x-auth-token to spring boot ,what am i doing wrong?将 x-auth-token 发送到 Spring Boot 时,Angular 应用程序出现 401 错误,我做错了什么?
【发布时间】:2021-01-25 12:13:33
【问题描述】:

我有一个带有 Spring Boot 后端项目的 Angular 2 前端。初始登录页面接受用户名和密码并将其发送到后端并得到"xAuthToken"作为响应,我存储在localstorage中,当我尝试刷新页面时,角度得到401错误。我怎样才能让spring security接受@ 987654323@?

角度 -

@Injectable()
export class LoginService {

  constructor(private http:Http) { }

  sendCredentials(username:String,password:String){
      let url="http://localhost:8181/token";
      let encodedCred=btoa(username+":"+password);
      let basicHeader="Basic "+encodedCred;
      let header=new Headers({
        "Content-Type":  "application/json",
        "Authorization": basicHeader
      });
   return this.http.get(url,{headers:header});
  }

  checkSession(){
    let url="http://localhost:8181/checkSession";
    console.log("pp=="+localStorage.getItem('xAuthToken'));
    let header=new Headers({
      'x-auth-token':  localStorage.getItem('xAuthToken')
    });
 return this.http.get(url,{headers:header});
  }


}



export class LoginComponent implements OnInit {

 private credentials={"username":"","password":""};
 private loggedIn:boolean=false;

  constructor(private loginService:LoginService) { }

  onSubmit(){
    this.loginService.sendCredentials(this.credentials.username,this.credentials.password).
    subscribe(res => {
            console.log(res);
            console.log(res.json());
            localStorage.setItem("xAuthToken", res.json().token);
            this.loggedIn=true;
            //location.reload();
          },
          error => {
            console.log(error);
          }
      );
  
  
  }
  
  ngOnInit() {
    this.loginService.checkSession().subscribe(
      res=>{
        this.loggedIn=true;
      },
      error=>{
        console.log(error);
      }
    );
  }

}

春天-

@CrossOrigin(origins = "http://localhost:4200")
@RestController
public class LoginController {

    @Autowired
    private UserService userService;
    
    @RequestMapping(value = "/token")
    public Map<String, String> token(HttpSession session, HttpServletRequest request) {
        System.out.println(request.getRemoteHost());
        
        String remoteHost = request.getRemoteHost();
        int portNumber = request.getRemotePort();
        
        System.out.println(remoteHost+":"+portNumber);
        System.out.println(request.getRemoteAddr());
        
        return Collections.singletonMap("token", session.getId());
    }
    @CrossOrigin(origins = "http://localhost:4200",allowedHeaders = "x-auth-token")
    @RequestMapping(value = "/checkSession")
    public ResponseEntity checkSession() {
        System.out.print("insiden checksession");
        return new ResponseEntity("Session Active", HttpStatus.OK);
    } 
    
}




@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    
    @Autowired
    Environment env; 

    @Autowired
    UserSecurityService useSecurityService;
    
    private BCryptPasswordEncoder passwordEncoder() {
        return SecurityUtility.passwordEncoder();
    }
    
    private static final String[] PUBLIC_MATHCES= {
            "/css/**",
            "/js/**",
            "/image/**",
            "/book/**",
            "/user/**"
    };

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers(PUBLIC_MATHCES).permitAll()
            .anyRequest().authenticated();
        http.csrf().disable()
            .cors()
            .and()
            .httpBasic();
        
    }
    
    
    
    
}

【问题讨论】:

    标签: angular spring spring-boot spring-security


    【解决方案1】:

    身份验证流程似乎没有完全通过。您需要通过拦截 HTTP 请求并注入用户来编写对用户的身份验证,然后只有 spring 提供对经过身份验证的路径的访问。

    @Autowired
    private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1").password(passwordEncoder().encode("user1Pass"))
          .authorities("ROLE_USER");
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // ... standard code here ...
    
        http.addFilterAfter(new CustomFilter(),
          BasicAuthenticationFilter.class);
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    

    }

    请参考Baeldung post for spring security auth

    【讨论】:

    • 你的答案太复杂了,我不明白,有没有办法使用注释来做到这一点?你能把你的答案分解成简单的术语吗?@Amal George Thomas
    • 您必须在 HTTP 请求中添加一个拦截器,即 SecurityConfig#configure 方法中的 http.addFilterBefore()。在里面你可以有从授权中提取会话令牌的逻辑,并通过设置 SecurityContextHolder.getContext().setAuthentication(authenticationToken); 来验证用户。我刚刚找到了一种可行的简单方法,我会更新我的答案。
    猜你喜欢
    • 2014-09-08
    • 2011-11-30
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 2017-10-07
    • 2021-04-03
    • 2020-07-18
    相关资源
    最近更新 更多