在我的网络应用程序中,我正在针对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();
}
}
答案 0 :(得分:0)
这不是由Spring直接引起的,而是由SDE尝试创建对象时引起的NPE引起的,调用setPassword()后又尝试使用nullE的passwordEncoder字段。
我尝试自动加载此字段,但正如此this question显示实体不会自动装配。
此外,无论如何我无法使自动装配工作,所以我在setPassword方法中做了一个解决方法。