Spring security 为什么在使用basic auth进行第二次rest调用后,我会收到NullPointerException?

Spring security 为什么在使用basic auth进行第二次rest调用后,我会收到NullPointerException?,spring-security,basic-authentication,Spring Security,Basic Authentication,由于我在每次执行rest调用时都将spring安全性添加到我的项目中,因此它可以正常工作,尽管由于某种原因,同一个调用如果执行两次会报告NullPointerException。我使用的是Basic Auth。可能是在第一次通话后我根本不应该发送我的用户凭证,还是更复杂 我的配置: @Override protected void configure(HttpSecurity http) throws Exception { http .c

由于我在每次执行rest调用时都将spring安全性添加到我的项目中,因此它可以正常工作,尽管由于某种原因,同一个调用如果执行两次会报告NullPointerException。我使用的是Basic Auth。可能是在第一次通话后我根本不应该发送我的用户凭证,还是更复杂

我的配置:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/product")
                    .authenticated()
                .antMatchers("/")
                    .permitAll()
                .and()
                .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService)
                .passwordEncoder(passwordEncoder);

    }
用户详细信息服务:

@Service
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        Optional<User> optionalUser = userRepository.findByUserName(s);

        optionalUser.orElseThrow(() -> new UsernameNotFoundException("Username not found"));

        return optionalUser.map(UserDetailsModel::new).get();
    }
}
所以基本上只是一个NullPointerException

用户类别:

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    private String password;

    //proveriti fetch i orphan
    @OneToMany(mappedBy = "user",
            cascade = CascadeType.ALL,
            fetch = FetchType.EAGER)
    private Set<Role> roles;

    @OneToMany(
            mappedBy = "user",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    @JsonManagedReference(value = "product")
    private List<Product> products = new ArrayList<>();

    @OneToMany(
            mappedBy = "user",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    @JsonManagedReference(value = "userO")
    private List<Orders> orders = new ArrayList<>();

    public User() {
    }

    public User(User user){
        this.firstName = user.getFirstName();
        this.lastName = user.getLastName();
        this.password = user.getPassword();
        this.roles = user.getRoles();
        this.id = user.getId();
    }
@实体
@表(name=“user”)
公共类用户{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私有int-id;
@列(name=“user\u name”)
私有字符串用户名;
@列(name=“first_name”)
私有字符串名;
@列(name=“last_name”)
私有字符串lastName;
私有字符串密码;
//普罗维瑞蒂,我是孤儿
@OneToMany(mappedBy=“用户”,
cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
私人设定角色;
@独身癖(
mappedBy=“用户”,
cascade=CascadeType.ALL,
孤立删除=真
)
@JsonManagedReference(value=“产品”)
私有列表产品=新的ArrayList();
@独身癖(
mappedBy=“用户”,
cascade=CascadeType.ALL,
孤立删除=真
)
@JsonManagedReference(value=“userO”)
私有列表顺序=新的ArrayList();
公共用户(){
}
公共用户(用户){
this.firstName=user.getFirstName();
this.lastName=user.getLastName();
this.password=user.getPassword();
this.roles=user.getRoles();
this.id=user.getId();
}

如果没有更多信息,要知道导致
NullPointerException
的原因相当复杂(日志是否提供了有关原因的线索?)。关于是否必须在每个请求中发送凭据(使用基本身份验证),考虑到您当前的配置,答案是
。我添加了我得到的错误,它没有给出任何线索。我发现唯一有帮助的是Servlet.service()正在引发异常。如果需要任何其他方法来解决此问题,我将在需要时添加,我只是不确定我还应该写些什么。看起来你的
用户
类没有返回用户名。发布你的
用户
类以查看
超级(用户)是什么
可以。您可以调试项目中的内部Spring类
BasicAuthenticationFilter
,以了解根本原因。考虑到日志中包含的版本,这是合适的版本:正如@dur所提到的,
username
属性似乎有问题,请查看
的实现>public User(User User User)
@arata您的用户在第一次请求时被发现并保存在HTTP会话中。第二次请求尝试从缓存中加载您的用户。但是您的用户没有用户名。如果没有更多信息,要知道您的
NullPointerException
(日志是否提供了有关原因的线索?)。关于是否必须在每个请求中发送凭据(使用基本身份验证),考虑到您当前的配置,答案是
yes
。我添加了收到的错误,但没有给出任何线索。我发现唯一有帮助的是Servlet.service()正在引发异常。如果需要任何其他方法来解决此问题,我将在需要时添加,我只是不确定我还应该写些什么。看起来你的
用户
类没有返回用户名。发布你的
用户
类以查看
超级(用户)是什么
可以。您可以调试项目中的内部Spring类
BasicAuthenticationFilter
,以了解根本原因。考虑到日志中包含的版本,这是合适的版本:正如@dur所提到的,
username
属性似乎有问题,请查看
的实现>public User(User User User)
@arata您的用户在第一次请求时被找到并保存在HTTP会话中。第二次请求尝试从缓存加载您的用户。但您的用户没有用户名。
@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductService productService;

    @PreAuthorize("hasAuthority('see:stock')")
    @GetMapping("/getAll")
    public List<ProductVO> getProducts(){
        return productService.getProducts();
    }

    @PreAuthorize("hasAuthority('add:stock')")
    @PostMapping("/update")
    void ProductUpdate(@RequestBody UpdateProductVO updateProductVO){
        productService.update(updateProductVO);
    }

    @PreAuthorize("hasAuthority('see:changes')")
    @GetMapping("/getUpdateHistory")
    List<UpdateProductVO> updatedProducts(){
        return productService.getUpdatedProducts();
    }
}
java.lang.NullPointerException: null
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.authenticationIsRequired(BasicAuthenticationFilter.java:223) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:167) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    private String password;

    //proveriti fetch i orphan
    @OneToMany(mappedBy = "user",
            cascade = CascadeType.ALL,
            fetch = FetchType.EAGER)
    private Set<Role> roles;

    @OneToMany(
            mappedBy = "user",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    @JsonManagedReference(value = "product")
    private List<Product> products = new ArrayList<>();

    @OneToMany(
            mappedBy = "user",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    @JsonManagedReference(value = "userO")
    private List<Orders> orders = new ArrayList<>();

    public User() {
    }

    public User(User user){
        this.firstName = user.getFirstName();
        this.lastName = user.getLastName();
        this.password = user.getPassword();
        this.roles = user.getRoles();
        this.id = user.getId();
    }