将 x-auth-token 发送到 Spring Boot 时,Angular 应用程序出现 401 错误,我做错了啥?
Posted
技术标签:
【中文标题】将 x-auth-token 发送到 Spring Boot 时,Angular 应用程序出现 401 错误,我做错了啥?【英文标题】: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();
【问题讨论】:
【参考方案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); 来验证用户。我刚刚找到了一种可行的简单方法,我会更新我的答案。以上是关于将 x-auth-token 发送到 Spring Boot 时,Angular 应用程序出现 401 错误,我做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS:未发送 X-Auth-Token(错误 401)
JSESSIONID 或 X-AUTH-TOKEN 在 Spring boot 中对同一用户进行身份验证时重复