SDN4 - 将GraphModel映射到实例时出错

时间:2015-07-23 11:39:38

标签: spring-data-neo4j-4

在我的网络应用程序中,我正在针对Neo4j服务器存储和验证用户。

在我的流程中,如果我向应用注册(从而保存用户实例),然后进入登录页面,我可以正常登录。如果我停止服务器并再次启动它,我无法登录。错误是:

    @login_required
def profile(request):
    form = UrlUploadForm(request.POST, request.FILES)
    queryset = UrlUpload.objects.all()
    if form.is_valid():
        instance = form.save(commit=False)
        instance.save()
        print instance
    context = {
        "form" : form,
        "queryset": queryset

    }
    return render(request, "profile.html", context)

用户在数据库中。如果我删除用户,再次注册并登录它可以正常工作,直到我重新启动服务器,所以它是可重复的。

使用SDN 4.0.0.RC1

代码

org.springframework.security.authentication.InternalAuthenticationServiceException: Error mapping GraphModel to instance of co.foo.data.models.User

用户实体

public interface MyUserDetailsService extends UserDetailsService {
    @Override
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;

    User getUserFromSession();

    @Transactional
    User register(String username, String firstName, String lastName, String password);
}

public interface UserRepository extends GraphRepository<User>, MyUserDetailsService {
    User findByUsername(String username);
}

@Primary
@Service
public class UserRepositoryImpl implements MyUserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    private User findByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        final User user = findByUsername(username);
        if (user==null) throw new UsernameNotFoundException("Username not found: " + username);
        return new MyUserDetails(user);
    }

    @Override
    public User getUserFromSession() {
        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();
        Object principal = authentication.getPrincipal();
        if (principal instanceof MyUserDetails) {
            MyUserDetails userDetails = (MyUserDetails) principal;
            return userDetails.getUser();
        }
        return null;    
}


    @Override
    @Transactional
    public User register(String username, String firstName, String lastName, String password) {
        User found = findByUsername(username);
        if (found!=null) throw new RuntimeException("Login already taken: " + username);
        if (firstName==null || firstName.isEmpty()) throw new RuntimeException("No first name provided.");
        if (lastName==null || lastName.isEmpty()) throw new RuntimeException("No last name provided.");
        if (password==null || password.isEmpty()) throw new RuntimeException("No password provided.");
        User user = new User(username, firstName, lastName, password, null, passwordEncoder, User.Roles.ROLE_USER);
        userRepository.save(user);
        setUserInSession(user);
        return user;
    }

    void setUserInSession(User user) {
        SecurityContext context = SecurityContextHolder.getContext();
        MyUserDetails userDetails = new MyUserDetails(user);
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, user.getPassword(),userDetails.getAuthorities());
        context.setAuthentication(authentication);
    }

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @AuthenticationPrincipal
    public @interface CurrentUser {

    }

}

@Configuration
@EnableWebSecurity
@Order(2)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login/**", "/resources/**", "/web/register").permitAll()
                .antMatchers("/web/**").authenticated()
                .and()
                .formLogin().loginProcessingUrl("/login").failureUrl("/login?authorization_error=true").defaultSuccessUrl("/web/home").loginPage("/login").permitAll()
                .and()
                .logout().logoutUrl("/logout").logoutSuccessUrl("/login")
                .permitAll();
    }

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
                auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

1 个答案:

答案 0 :(得分:0)

这不是由Spring直接引起的,而是由SDE尝试创建对象时引起的NPE引起的,调用setPassword()后又尝试使用nullE的passwordEncoder字段。

我尝试自动加载此字段,但正如此this question显示实体不会自动装配。

此外,无论如何我无法使自动装配工作,所以我在setPassword方法中做了一个解决方法。