我正在尝试通过弹簧安全性保护我的REST端点,并使用angular + 2前端使用它。
我知道用户登录时会生成CSRF令牌,并且应该随每个表单提交(POST请求)发送此令牌,但是我的问题是我无法从后端获取该令牌以在forntend中使用它。
>我尝试了很多解决方案,但是它不起作用,也许我错过了一些事情。
这是我的代码:
SecurityConfig
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService addUsers() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("Ali")
.password("mind@123")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("*"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
http.
authorizeRequests()
.antMatchers("**")
.authenticated()
.and().httpBasic();
http
.cors().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterAfter(new CustomeCSRF(),CsrfFilter.class);
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("XSRF-TOKEN");
return repository;
}
}
CustomeCSRF
public class CustomeCSRF extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
//response.setHeader("XSRF-TOKEN", token);
}
}
filterChain.doFilter(request, response);
}
}
这是我的浏览器响应标题
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:4200
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Sat, 19 Oct 2019 12:36:55 GMT
Expires: 0
Pragma: no-cache
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
WWW-Authenticate: Basic realm="Realm"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
前端
export class UserService {
// Headers Config
header = new HttpHeaders({'Content-Type':'application/text '});
CSRF-TOKEN = '';
constructor(private http:HttpClient,private tokenExtractor: HttpXsrfTokenExtractor) {
console.log('constractor of service')
//console.log(this.header);
this.header = this.header.set('Authorization', 'Basic ' + btoa( 'Ali'+':'+'mind@123'));
//this.header = this.header.set('withCredentials',' true'); //{:}
//this.header = this.header.set('Content-Type','text/plain');
//console.log(this.header);
}
createUser(){
let user = new User();
user.id = 100;
user.name = "ALI Angular"
user.phone = "90234809284092834";
return this.http.post('http://localhost:8080/api/addUser',user,{headers:this.header});
}
}
我非常感谢能帮助我找到答案的任何帮助。