Spring:通过 Angular 应用授权 header 始终为空
Spring: Authorization header is always null via Angular app
我正在使用 Spring 和 Angular 构建一个应用程序,现在,我尝试使用 Spring 安全和 (JWT)
实现安全阶段
问题是,当我从 Angular Spring 发送 Authorization header 时,Spring 没有收到!
即使我确定它已经在请求中(来自 chrome 开发工具)。
此外,当我从 ARC(来自 chrome 的高级 REST 客户端)发送具有相同 header 的相同请求时, spring 收到它并且 returns数据!
在 Angular 方面,我当然使用 HttpInterceptor
将令牌添加到请求中,如下所示:
export class HttpInterceptorService implements HttpInterceptor{
private _api = `${environment.api}/api`;
constructor(
private _authService: AuthenticationService
) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
if(req.url.startsWith(this._api)){
req = req.clone({
setHeaders: {
Authorization: `Bearer ${this._authService.getToken()}`
}
});
}
return next.handle(req);
}
}
这就是我在里面做的 spring:
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private JwtUserDetailsService jwtUserDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
private List<String> excludedURLsPattern = Arrays.asList(new String[]{"/authenticate"});
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
return excludedURLsPattern
.stream()
.anyMatch(urlPattern -> request.getRequestURL().toString().contains(urlPattern));
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
System.out.println("=== request URL: "+request.getRequestURL());
final String requestTokenHeader = request.getHeader("Authorization");
System.out.println("=== requestTokenHeader: "+requestTokenHeader);// in this line I always get null (when using Angular not ARC) !!
String username = null;
String jwtToken = null;
// JWT Token is in the form "Bearer token". Remove Bearer word and get
// only the Token
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
} catch (IllegalArgumentException e) {
System.out.println("Unable to get JWT Token");
} catch (ExpiredJwtException e) {
System.out.println("JWT Token has expired");
}
} else {
logger.warn("JWT Token does not begin with Bearer String");
}
// Once we get the token validate it.
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
// if token is valid configure Spring Security to manually set
// authentication
if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
这是我收到的消息:
2020-10-14 15:11:17.664 WARN 9856 --- [nio-5000-exec-1] c.s.c.security.config.JwtRequestFilter : JWT Token does not begin with Bearer String
好的,我会把解决方案留在这里,以备不时之需。
如 this blog 中所述,并且由于我使用的是 Sring Security,因此我必须在 Spring 安全级别 [= 启用 CORS 12=]
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()...// this one right here
}
}
我正在使用 Spring 和 Angular 构建一个应用程序,现在,我尝试使用 Spring 安全和 (JWT)
实现安全阶段
问题是,当我从 Angular Spring 发送 Authorization header 时,Spring 没有收到!
即使我确定它已经在请求中(来自 chrome 开发工具)。
此外,当我从 ARC(来自 chrome 的高级 REST 客户端)发送具有相同 header 的相同请求时, spring 收到它并且 returns数据!
在 Angular 方面,我当然使用 HttpInterceptor
将令牌添加到请求中,如下所示:
export class HttpInterceptorService implements HttpInterceptor{
private _api = `${environment.api}/api`;
constructor(
private _authService: AuthenticationService
) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
if(req.url.startsWith(this._api)){
req = req.clone({
setHeaders: {
Authorization: `Bearer ${this._authService.getToken()}`
}
});
}
return next.handle(req);
}
}
这就是我在里面做的 spring:
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private JwtUserDetailsService jwtUserDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
private List<String> excludedURLsPattern = Arrays.asList(new String[]{"/authenticate"});
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
return excludedURLsPattern
.stream()
.anyMatch(urlPattern -> request.getRequestURL().toString().contains(urlPattern));
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
System.out.println("=== request URL: "+request.getRequestURL());
final String requestTokenHeader = request.getHeader("Authorization");
System.out.println("=== requestTokenHeader: "+requestTokenHeader);// in this line I always get null (when using Angular not ARC) !!
String username = null;
String jwtToken = null;
// JWT Token is in the form "Bearer token". Remove Bearer word and get
// only the Token
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
} catch (IllegalArgumentException e) {
System.out.println("Unable to get JWT Token");
} catch (ExpiredJwtException e) {
System.out.println("JWT Token has expired");
}
} else {
logger.warn("JWT Token does not begin with Bearer String");
}
// Once we get the token validate it.
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
// if token is valid configure Spring Security to manually set
// authentication
if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
这是我收到的消息:
2020-10-14 15:11:17.664 WARN 9856 --- [nio-5000-exec-1] c.s.c.security.config.JwtRequestFilter : JWT Token does not begin with Bearer String
好的,我会把解决方案留在这里,以备不时之需。
如 this blog 中所述,并且由于我使用的是 Sring Security,因此我必须在 Spring 安全级别 [= 启用 CORS 12=]
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()...// this one right here
}
}