[英]@Value for jwt secret not working properly in Spring Security
I am trying to use jwt for my spring boot project and have Spring Security setup.我正在尝试将 jwt 用于我的 spring 引导项目并进行 Spring 安全设置。 When I use the Internal filter which is this当我使用这个内部过滤器时
@Slf4j
@RequiredArgsConstructor
public class CustomAuthorizationFilter extends OncePerRequestFilter {
private final JwtProvider jwtProvider;
private final String tokenPrefix = "Bearer ";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
log.info("INITIALIZE | CustomAuthorizationFilter | doFilterInternal | " + request.getRequestURI());
LocalDateTime initTime = LocalDateTime.now();
String token = request.getHeader(AUTHORIZATION);
if (token != null && token.startsWith(tokenPrefix)) {
jwtProvider.verifyJwt(token);
} else {
filterChain.doFilter(request, response);
}
log.info("COMPLETE | CustomAuthorizationFilter | doFilterInternal | " +
Duration.between(initTime, LocalDateTime.now()) + " | " + request.getRequestURI());
}
}
Problem : In my verifyJwt, it reads the secret which is declared as below as null
for some reason.问题:在我的 verifyJwt 中,由于某种原因,它读取如下声明为null
的秘密。
@Value("${jwt.secret}")
private String secret;
And this is my verifyJwt method这是我的 verifyJwt 方法
public User verifyJwt(String token) {
log.info("INITIALIZE | JwtProvider | verifyJwt | " + token);
LocalDateTime initTime = LocalDateTime.now();
if (token == null || !token.startsWith(tokenPrefix)) {
throw new UnauthorizedException();
}
token = token.substring(tokenPrefix.length());
Algorithm algorithm = Algorithm.HMAC256(secret.getBytes(StandardCharsets.UTF_8));
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT decodedJWT = verifier.verify(token);
String username = decodedJWT.getSubject();
String[] roles = decodedJWT.getClaim("roles").asArray(String.class);
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
stream(roles).forEach(role -> {
authorities.add(new SimpleGrantedAuthority(role));
});
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(username, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
log.info("COMPLETE | JwtProvider | verifyJwt | " + Duration.between(initTime, LocalDateTime.now()) + " | " +
username);
return (User) userDetailsService.loadUserByUsername(username);
}
The @Value is not working obviously, but it is working fine for other methods. @Value 显然不起作用,但它对其他方法工作正常。
Anyone has a solution to fix this problem except for declaring it like this private String secret = "secret"
任何人都有解决此问题的解决方案,除了像这样声明它private String secret = "secret"
This is my SpringSecurityConfiguration这是我的 SpringSecurityConfiguration
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
JwtProvider jwtProvider = new JwtProvider(userDetailsService);
http
.csrf().disable()
.cors()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/contact/**",
"/user/duplicate/**",
"/user/new/**",
"/user/login/**",
"/user/auth/**",
"/user/findId/**",
"/user/findPw/**/**",
"/swagger-ui/index.html/**")
.permitAll()
.antMatchers("/user", "/user/**",
"/profile/**")
.authenticated()
.and()
.addFilterBefore(new CustomAuthorizationFilter(jwtProvider),
UsernamePasswordAuthenticationFilter.class);
}
}
Register your CustomAuthorizationFilter
as a spring bean component.将您的CustomAuthorizationFilter
注册为 spring bean 组件。
@Slf4j
@RequiredArgsConstructor
@Component // <-----------------
public class CustomAuthorizationFilter extends OncePerRequestFilter {
....
}
Then register your custom filter to be used just before UsernamePasswordAuthenticationFilter
然后注册您的自定义过滤器,以便在UsernamePasswordAuthenticationFilter
之前使用
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Override
protected void configure(HttpSecurity httpSecurity) {
// Add a filter to validate the tokens with every request
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
This way your filter will be invoked just in the right order and also would be registered as a spring bean so that it has access to application context where @Value
will be able to function.这样,您的过滤器将以正确的顺序被调用,并且还将被注册为 spring bean,以便它可以访问应用程序上下文,其中@Value
将能够访问 function。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.