**已关闭。**此问题不符合Stack Overflow guidelines。目前不接受回答。
这个问题似乎与help center中定义的范围内的编程无关。
21天前关闭
Improve this question的
我正在创建一个Java API,在安全过滤器中收到此错误:
java.lang.NullPointerException:无法调用“school.pachecos. API.users.UserRepository.findByEmail(String)”,因为“this.user_repository”为null
我有这个代码:
安全过滤器
@Component
public class SecurityFilter extends OncePerRequestFilter {
@Autowired
TokenService token_service = new TokenService();
@Autowired
private UserRepository user_repository;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filter_chain) throws ServletException, IOException {
String token = getToken(request);
if(token != null){
String token_subject = token_service.getTokenSubject(token);
UserDetails user_entity = user_repository.findByEmail(token_subject);
Authentication authentication = new UsernamePasswordAuthenticationToken(user_entity, null, user_entity.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filter_chain.doFilter(request, response);
}
private String getToken(HttpServletRequest request){
String token = request.getHeader("Authorization");
if(token == null){
return null;
}
return token.replace("Bearer", "");
}
}
字符串
安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfigurations {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(http_request -> http_request
.requestMatchers("/auth/login").permitAll()
.anyRequest().authenticated()
)
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.addFilterBefore(new SecurityFilter(), UsernamePasswordAuthenticationFilter.class)
.build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration auth_config) throws Exception {
return auth_config.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
型
令牌配置
@Service
public class TokenService {
private final String secret = "b0eMdsHE5jKDW9RsjuC5VrF8BT7P2oHubObbdBvaVbfzlXgKftxQ2WrZfX4RtU04";
private final String ISSUER = "API Pacheco's School";
public String createToken(UserEntity user){
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.create()
.withIssuer(ISSUER)
.withExpiresAt(getExpiresAt())
.withSubject(user.getUsername())
.sign(algorithm);
} catch (JWTCreationException exception){
return null;
}
}
private Instant getExpiresAt(){
return LocalDateTime.now().plusDays(1).toInstant(ZoneOffset.of("-03:00"));
}
public String getTokenSubject(String token){
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.require(algorithm)
.withIssuer(ISSUER)
.build()
.verify(token)
.getSubject();
} catch (JWTVerificationException exception){
return null;
}
}
}
型
用户仓库
public interface UserRepository extends JpaRepository<UserEntity, Long> {
@Query(value = "SELECT u FROM UserEntity u WHERE " +
"u.name LIKE CONCAT('%', :name, '%') " +
"OR u.birth_date = :date " +
"OR u.email LIKE CONCAT('%', :email, '%') " +
"OR cellphone LIKE CONCAT('%', :cellphone, '%') "
)
Collection<UserEntity> searchUsers(String name, LocalDate date, String email, String cellphone);
UserDetails findByEmail(String email);
}
型
我在安全过滤器中的令牌服务也遇到了同样的错误,但由于它是一个类,我只是用new
创建了它,但我不能用user_repository
来创建它。
2条答案
按热度按时间q7solyqu1#
这段代码中有几个错误,我将指出它们。
首先,我要指出最大的问题,(spring security)内置了很多预构建的安全标准。Basic login *,FormLogin,Oauth2,SAML,mTLS 等。但是你选择忽略所有这些预构建的标准,并决定构建某种自定义的安全解决方案,直接向浏览器分发JWT,并将其用作会话。
您构建的这种类型的身份验证有点类似于Oauth2 rfc6749定义的 Resource Owner Password Credentials Grant 或 implicit grant。
这两种身份验证类型都被视为“不得使用”或“不应使用”,因为已发现与它们相关的多个严重漏洞。
因此,这里的重点是,这种类型的身份验证不应该在2023年之前内置到新系统中。
现在来看看代码中更多的技术问题。
您已经注解了自定义过滤器
@Component
,这意味着当服务器启动并扫描文件树中主类下面的所有类时,这个类将被spring上下文拾取并添加为Bean
。只有 spring beans 可以使用
Autowire
annotation,因为如果不是spring示例化了你的类,spring怎么知道要自动连接到哪个类?然后你也会调用
new SecurityFilter()
,这意味着你正在手动示例化这个类,所以spring完全不知道这个类是什么,并且ofc你的autowired字段将返回null。你得选一个
这是基本的 Spring Bean 知识,我建议你读了基础知识。
如前所述,应该删除整个安全实现。JWT不应该用作会话。
https://developer.okta.com/blog/2017/08/17/why-jwts-suck-as-session-tokens的
https://redis.com/blog/json-web-tokens-jwt-are-dangerous-for-user-sessions/的
http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/的
http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/的
可悲的是,有太多的博主在那里写教程,制作youtube视频,他们不知道真实的安全是如何工作的,甚至从来没有读过spring安全文档。
Springs own recommendations for implementing SPA applications
ybzsozfc2#
我找到了解决办法
我已经在spring安全函数中初始化了
new SecurityFilter()
:.addFilterBefore(new SecurityFilter(), UsernamePasswordAuthenticationFilter.class)
个我应该把它写成
@Autowired
:安全问题
字符串