[英]How to fix Spring Security Authorization header not being passed?
In one of my REST services, I make use of Spring Security to validate the token that is being passed in the header.在我的 REST 服务之一中,我使用 Spring 安全性来验证在 header 中传递的令牌。 However, spring is unable to find the "Authorization" header, even though it is there.
但是,spring 无法找到“授权”header,即使它在那里。 This was not a problem when testing in test, and even locally but when we deployed to PROD we get this issue.
在测试中甚至在本地进行测试时,这不是问题,但是当我们部署到 PROD 时,我们遇到了这个问题。
As an alternative/workaround I removed Spring security and instead tried to do the validation of my token in the actual endpoint before continueing with the rest of the request like such:作为替代/解决方法,我删除了 Spring 安全性,而是尝试在实际端点中验证我的令牌,然后继续使用请求的 rest,如下所示:
@PostMapping(value="/create",consumes="application/json; charset=utf-8")
@CrossOrigin
public ResponseEntity createAccount(@RequestBody MerchantAccount merchantAccount,@RequestHeader(name="Authorization") String token) {
log.info("Checking User Token");
if(!jwtUtil.isAuthorizedToken(token))
return ResponseEntity.status(401).build();
//some creating Account Logic
}
If I did the above once again it would work in TEST and on LOCAL but not in PROD.如果我再次执行上述操作,它将在 TEST 和 LOCAL 中有效,但在 PROD 中无效。 Error that I would get back would be "Missing Authorization header".
我会回来的错误是“缺少授权标头”。 But yet again it is present.
但它又一次出现了。 (Tested from postman to).
(测试从 postman 到)。
After some research, I saw that I could add ",required=false" so spring would not check for it, but then still there was no token to extract.经过一番研究,我发现我可以添加“,required=false”,这样 spring 就不会检查它,但是仍然没有要提取的令牌。
The only difference between PROD and TEST and my local is the following: PROD 和 TEST 与我的本地之间的唯一区别如下:
Java version java version on test: java version "1.6.0_32"
Java 版本 java 版本正在测试:
java version "1.6.0_32"
java version on PROD: java version "1.8.0_121"
PROD 上的 java 版本:
java version "1.8.0_121"
java version on local: java version "1.8.0_221"
java 本地版本:
java version "1.8.0_221"
On Test we use HTTP and PROD it's HTTPS.在测试中,我们使用 HTTP 和 PROD 它是 HTTPS。 Spring Security Version in POM file is 5.2
POM 文件中的 Spring 安全版本为 5.2
EDIT In my web config I do have a section that allows for the "Authorization" header to be present as seen below.编辑在我的 web 配置中,我确实有一个部分允许“授权”header 出现,如下所示。
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));//YOLO Allow all origins, we can change this once we go to prod
configuration.setAllowedMethods(ImmutableList.of("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH","OPTIONS"));//Allowed Methods
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type","Access-Control-Request-Headers","Access-Control-Request-Method",
"Accept","Access-Control-Allow-Headers"));//Allowed Headers
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
Update On TEST & LOCAL when I iterate through headers in the request filter (as seen below)当我遍历请求过滤器中的标头时更新测试和本地(如下所示)
@Component
@Service
public class JwtRequestFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
logger.info("Done Getting Headers");
Collections.list(request.getHeaderNames()).forEach(item -> logger.info("header name is " + item));
logger.info("Done Getting Headers");
boolean isAccessToken = true;
final String requestTokenHeader = request.getHeader("authorization");//This is null as the Authorization header is not found in request
}
I get the following output.我得到以下 output。 TEST & LOCAL
测试和本地
On PROD I get the following:在 PROD 上,我得到以下信息:
Please help.请帮忙。
After wandering galaxies....在流浪星系之后......
I've fixed it using this:我已经用这个修复了它:
@Configuration
@EnableWebSecurity
public class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and() /*.other stuff */;
}
}
Basically you need to enable cors()
with the http
object.. and then there are multiple ways to handle the cros origin for each controller/method or globally.基本上,您需要使用
http
object 启用cors()
..然后有多种方法可以为每个控制器/方法或全局处理 cros 来源。
My issue was like this:我的问题是这样的:
Whenever I make request from postman it worked & the "Authorization"
key in header was always present, debugged it using request filter just like you.每当我从 postman 发出请求时,它都会起作用,并且 header 中的
"Authorization"
键始终存在,就像您一样使用请求过滤器对其进行调试。
However, each time request made form front end app (react) the browser prevented the "Authorization"
key every single time...但是,每次从前端应用程序(反应)发出请求时,浏览器每次都会阻止
"Authorization"
键......
To configure it globally:要全局配置它:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/greeting-javaconfig")
.allowedOrigins("http://localhost:8080");
}
};
}
Or, controller level,或者,controller级别,
@CrossOrigin(origins = "http://localhost:8080")
@GetMapping("/greeting")
public String greeting() {
return "works!";
}
Ref:参考:
Possible Issue:可能的问题:
When using Spring Security with Spring web flux , I had to use the following config to make it work: -当使用Spring Security和Spring web 通量时,我必须使用以下配置才能使其工作:-
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@EnableWebFluxSecurity
public class WebSecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.cors().and()
.csrf().disable()
.authorizeExchange()
.pathMatchers("/**").permitAll()
.anyExchange()
.authenticated()
.and()
... //more mappings
return http.build();
}
@Bean
CorsConfigurationSource corsConfiguration() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.applyPermitDefaultValues();
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return source;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.