Angular app向spring boot发送x-auth-token时出错,我做错了什么?
我有一个角度2前端与弹簧启动后端项目。初始登录页面接受用户名和密码,并将其发送到后端,并获得Angular app向spring boot发送x-auth-token时出错,我做错了什么?,angular,spring,spring-boot,spring-security,Angular,Spring,Spring Boot,Spring Security,我有一个角度2前端与弹簧启动后端项目。初始登录页面接受用户名和密码,并将其发送到后端,并获得“xAuthToken”,作为我存储在localstorage中的响应,当我尝试刷新页面时,angular收到401错误。如何使spring security接受“x-auth-token” 棱角的- @Injectable() export class LoginService { constructor(private http:Http) { } sendCredentials(user
“xAuthToken”
,作为我存储在localstorage
中的响应,当我尝试刷新页面时,angular收到401错误。如何使spring security接受“x-auth-token”
棱角的-
@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();
}
}
@交叉原点(原点=”http://localhost:4200")
@RestController
公共类登录控制器{
@自动连线
私人用户服务;
@请求映射(value=“/token”)
公共映射令牌(HttpSession会话,HttpServletRequest请求){
System.out.println(request.getRemoteHost());
字符串remoteHost=request.getRemoteHost();
int portNumber=request.getRemotePort();
System.out.println(remoteHost+“:”+端口号);
System.out.println(request.getRemoteAddr());
返回Collections.singletonMap(“token”,session.getId());
}
@交叉原点(原点=”http://localhost:4200,allowedHeaders=“x-auth-token”)
@请求映射(value=“/checkSession”)
公众响应性检查会议(){
系统输出打印(“内部检查会话”);
返回新的响应状态(“会话活动”,HttpStatus.OK);
}
}
@配置
@启用Web安全性
公共类SecurityConfig扩展了WebSecurity配置适配器{
@自动连线
环境环境;
@自动连线
用户安全服务使用安全服务;
专用BCryptPasswordEncoder passwordEncoder(){
返回SecurityUtility.passwordEncoder();
}
私有静态最终字符串[]公共数学={
“/css/**”,
“/js/**”,
“/image/**”,
“/book/**”,
“/user/**”
};
@凌驾
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
auth.userDetailsService(useSecurityService).passwordEncoder(passwordEncoder());
}
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
http.authorizeRequests()
.antMatchers(公共数学).permitAll()
.anyRequest().authenticated();
http.csrf().disable()
.cors()
.及()
.httpBasic();
}
}
身份验证流程似乎没有完全通过。您需要通过拦截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();
}
}
请参考您的答案太复杂了,我不明白,还有什么方法可以使用注释来实现?您可以将答案分解为简单的术语吗。@Amal George ThomasYou必须在您的HTTP请求中添加拦截器,即SecurityConfig#configure方法中的HTTP.addFilterBefore()。在内部,您可以拥有从授权中提取会话令牌的逻辑,并通过设置SecurityContextHolder.getContext().setAuthentication(authenticationToken)对用户进行身份验证;我刚刚找到一个简单的方法,可以工作,我会更新我的答案。