Cannot save an object with GrantedAuthority field (no Creators, like default construct, exist)

huangapple 未分类评论52阅读模式
标题翻译

Cannot save an object with GrantedAuthority field (no Creators, like default construct, exist)

问题

我一直在尝试在我的项目中启用基于表单的用户注册。

只是注册一个没有角色的用户运行良好,但是添加一些角色会给我一个错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 无法构造org.springframework.security.core.GrantedAuthority的实例(不存在默认构造函数等创建者):抽象类型需要映射到具体类型,具有自定义反序列化器或包含附加类型信息
在[源:(PushbackInputStream); 行:9,列:21]处(通过引用链:com.warehousing.model.User ["authorities"] - > java.util.HashSet [0])

我怀疑问题是由于Spring不知道如何将我的权限表示从一些扩展GrantedAuthority的内容转换过来。话虽如此,我尝试将GrantedAuthority切换到SimpleGrantedAuthority,但问题仍然存在。

我的User类如下所示:

public class User implements UserDetails {
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	private String fName;
	private String lName;
	private String phone;
	private String email;
	
	// Spring认证属性
	
	@ElementCollection(targetClass=SimpleGrantedAuthority.class, fetch = FetchType.EAGER)
	@JsonDeserialize(as = SimpleGrantedAuthority.class)
	private Set<? extends GrantedAuthority> grantedAuthorities;
	@NotNull
	private String password;
    @NotNull
	private String username;
	private boolean isAccountNonExpired;
	private boolean isAccountNonLocked;
	private boolean isCredentialsNonExpired;
	private boolean isEnabled;

	public User(String fName, String lName, String phone, String email, 
                Set<SimpleGrantedAuthority> grantedAuthorities, String password, String username, 
                boolean isAccountNonExpired, boolean isAccountNonLocked, 
                boolean isCredentialsNonExpired, boolean isEnabled) {		
		this.fName = fName;
		this.lName = lName;
		this.phone = phone;
		this.email = email;
		this.grantedAuthorities = grantedAuthorities;
		this.password = password;
		this.username = username;
		this.isAccountNonExpired = isAccountNonExpired;
		this.isAccountNonLocked = isAccountNonLocked;
		this.isCredentialsNonExpired = isCredentialsNonExpired;
		this.isEnabled = isEnabled;
	}
    // 获取器、设置器和构造函数
}

我的UserController中用于创建新用户的方法:

@RestController
public class UserController {
	@Autowired
	UserService userService;

    @PostMapping("/users")
	public User createNew(@Valid @RequestBody User user) {
		return userService.addUser(user);
	}
}

该方法调用了UserService

public class UserService implements UserDetailsService {
	
	@Autowired
	UserRepository userRepo;

	public User addUser(User user) {
		
		Set<SimpleGrantedAuthority> userRoles = user.getGrantedAuthorities()
				.stream()
				.map(p -> new SimpleGrantedAuthority(p.getAuthority()))
				.collect(Collectors.toSet());

		User newUser = new User(user.getfName(), user.getlName(), 
				user.getPhone(), user.getEmail(), 
				userRoles, 
				user.getPassword(), user.getUsername(), 
				user.isAccountNonExpired(), 
				user.isAccountNonLocked(), 
				user.isCredentialsNonExpired(), 
				user.isEnabled());
		
		return userRepo.save(newUser);
	}
}

现在,像这样发布一个JSON可以正常工作:

{
	"fName": "First",
    "lName": "Last",
    "phone": "+3111111111",
    "email": "test@mail.com",
    "password": "password",
    "username": "user",
    "enabled": true,
    "authorities": [],
    "accountNonLocked": true,
    "accountNonExpired": true,
    "credentialsNonExpired": true
}

然而,添加某种权限会导致上述错误:

{
	"fName": "First",
    "lName": "Last",
    "phone": "+3111111111",
    "email": "test@mail.com",
    "password": "password",
    "username": "user",
    "enabled": true,
    "authorities": [{
            "authority": "inventory:read"
        }],
   "accountNonLocked": true,
    "accountNonExpired": true,
    "credentialsNonExpired": true
}

欢迎提供任何帮助!

英文翻译

I have been trying to enable a form-based user registration in my project.

Just registering a user with no roles works fine, however adding some roles gives me an error:
>
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of org.springframework.security.core.GrantedAuthority (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (PushbackInputStream); line: 9, column: 21] (through reference chain: com.warehousing.model.User["authorities"]->java.util.HashSet[0])

I suspect that the problem is coming from the fact that Spring has no idea how to convert from my authority representation to something that extends GrantedAuthority. That being said, I tried switching from GrantedAuthority to SimpleGrantedAuthority, but the problem remained.

My User class looks like follows:

public class User implements UserDetails {
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	private String fName;
	private String lName;
	private String phone;
	private String email;
	
	// Properties for Spring authentication
	
	@ElementCollection(targetClass=SimpleGrantedAuthority.class, fetch = FetchType.EAGER)
	@JsonDeserialize(as = SimpleGrantedAuthority.class)
	private Set&lt;? extends GrantedAuthority&gt; grantedAuthorities;
	@NotNull
	private String password;
    @NotNull
	private String username;
	private boolean isAccountNonExpired;
	private boolean isAccountNonLocked;
	private boolean isCredentialsNonExpired;
	private boolean isEnabled;

	public User(String fName, String lName, String phone, String email, 
                Set&lt;SimpleGrantedAuthority&gt; grantedAuthorities, String password, String username, 
                boolean isAccountNonExpired, boolean isAccountNonLocked, 
                boolean isCredentialsNonExpired, boolean isEnabled) {		
		this.fName = fName;
		this.lName = lName;
		this.phone = phone;
		this.email = email;
		this.grantedAuthorities = grantedAuthorities;
		this.password = password;
		this.username = username;
		this.isAccountNonExpired = isAccountNonExpired;
		this.isAccountNonLocked = isAccountNonLocked;
		this.isCredentialsNonExpired = isCredentialsNonExpired;
		this.isEnabled = isEnabled;
	}
    // Getters, setters &amp; constructors
}

My UserController`s method to create a new user:

@RestController
public class UserController {
	@Autowired
	UserService userService;

    @PostMapping(&quot;/users&quot;)
	public User createNew(@Valid @RequestBody User user) {
		return userService.addUser(user);
	}
}

Which calls the UserService:

public class UserService implements UserDetailsService {
	
	@Autowired
	UserRepository userRepo;

	public User addUser(User user) {
		
		Set&lt;SimpleGrantedAuthority&gt; userRoles = user.getGrantedAuthorities()
				.stream()
				.map(p -&gt; new SimpleGrantedAuthority(p.getAuthority()))
				.collect(Collectors.toSet());

		User newUser = new User(user.getfName(), user.getlName(), 
				user.getPhone(), user.getEmail(), 
				userRoles, 
				user.getPassword(), user.getUsername(), 
				user.isAccountNonExpired(), 
				user.isAccountNonLocked(), 
				user.isCredentialsNonExpired(), 
				user.isEnabled());
		
		return userRepo.save(newUser);
	}
}

Now, posting a JSON like this works fine:

{
	&quot;fName&quot;: &quot;First&quot;,
    &quot;lName&quot;: &quot;Last&quot;,
    &quot;phone&quot;: &quot;+3111111111&quot;,
    &quot;email&quot;: &quot;test@mail.com&quot;,
    &quot;password&quot;: &quot;password&quot;,
    &quot;username&quot;: &quot;user&quot;,
    &quot;enabled&quot;: true,
    &quot;authorities&quot;: [],
    &quot;accountNonLocked&quot;: true,
    &quot;accountNonExpired&quot;: true,
    &quot;credentialsNonExpired&quot;: true
}

However, adding some kind of authority will cause the error mentioned above:

{
	&quot;fName&quot;: &quot;First&quot;,
    &quot;lName&quot;: &quot;Last&quot;,
    &quot;phone&quot;: &quot;+3111111111&quot;,
    &quot;email&quot;: &quot;test@mail.com&quot;,
    &quot;password&quot;: &quot;password&quot;,
    &quot;username&quot;: &quot;user&quot;,
    &quot;enabled&quot;: true,
    &quot;authorities&quot;: [{
            &quot;authority&quot;: &quot;inventory:read&quot;
        }],
   &quot;accountNonLocked&quot;: true,
    &quot;accountNonExpired&quot;: true,
    &quot;credentialsNonExpired&quot;: true
}

Any kind of help is appreciated!

huangapple
  • 本文由 发表于 2020年3月16日 23:11:25
  • 转载请务必保留本文链接:https://java.coder-hub.com/60708489.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定