Spring 为什么PermissionEvaluator中的Serializable targetId在某些情况下为null,而在其他情况下不为null?
我们正在实现Spring 为什么PermissionEvaluator中的Serializable targetId在某些情况下为null,而在其他情况下不为null?,spring,spring-security,Spring,Spring Security,我们正在实现PermissionEvaluator,如下所示,它抛出一个NullPointerException(注释为“NPE HERE”): 查看后,targetId似乎为null。但是,此代码的原始作者能够毫无问题地运行此代码。我试图对我们的回购协议进行区分,但没有发现任何有意义的东西。我也搜索了SO和google,但没有找到多少信息 可序列化的targetId保存在哪里?为什么它在某些情况下是空的,而在其他情况下不是空的 考虑到这可能是我实现UserDetails的方式,下面是相关的部分
PermissionEvaluator
,如下所示,它抛出一个NullPointerException
(注释为“NPE HERE”):
查看后,targetId似乎为null。但是,此代码的原始作者能够毫无问题地运行此代码。我试图对我们的回购协议进行区分,但没有发现任何有意义的东西。我也搜索了SO和google,但没有找到多少信息
可序列化的targetId保存在哪里?为什么它在某些情况下是空的,而在其他情况下不是空的
考虑到这可能是我实现UserDetails的方式,下面是相关的部分。它们是基于惠勒和怀特在春季实践中的实现
我正在实施以下UserDetails:
public class UserDetailsAdapter implements UserDetails {
public UserDetailsAdapter(Account account) {
this.account = account;
}
public Account getAccount() {
return account;
}
public Integer getId() {
return account.getId();
}
public String getFirstName() {
return account.getFirstName();
}
public String getLastName() {
return account.getLastName();
}
public String getEmail() {
return account.getEmail();
}
@Override
public String getUsername() {
return account.getEmail();
}
@Override
public String getPassword() {
return account.getPassword();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return account.isEnabled();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<>();
for (Role role : account.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
private Account account;
private static final long serialVersionUID = 2251948358105443813L;
@Override
public String toString() {
return "UserDetailsAdapter [account=" + account + ", firstName=" +
account.getFirstName() + ", lastName=" + account.getLastName() + "]";
}
}
在@Controller中:
@RequestMapping(value = {"/company"}, method = RequestMethod.GET)
public String createForm(Model model) {
model.addAttribute("company", companyService.createCompany());
return "company";
}
在@服务中:
public Company createCompany() {
return companyDao.create();
}
我看到它一直存在于数据库中,并分配了一个ID 我们的开发人员能够通过在编译时将调试信息添加到构建中(在我们的例子中,是一个ant
build.xml
)来纠正这个问题
例如,在调试级别中包括“vars”:
<target name="compile" depends="init"
description="compile the source">
<javac srcdir="${src}" destdir="${build}" source="1.7" target="1.7"
nowarn="true" debug="true" debuglevel="lines,source,vars"
includeantruntime="true" deprecation="${deprecation}">
<compilerarg value="-Xbootclasspath/p:${toString:pathing.classpath}"/>
</javac>
<javac srcdir="${project_dir}/src/test" destdir="${build}" source="1.7" target="1.7"
nowarn="true" debug="true" debuglevel="lines,source,vars"
includeantruntime="true" deprecation="${deprecation}">
<compilerarg value="-Xbootclasspath/p:${toString:pathing.classpath}"/>
</javac>
</target>
我认为Maven
pom.xml的解决方案类似于Mavenpom.xml,我猜当您有一个新创建的对象尚未保存时(即,id是在保存后生成的)。感谢您的评论,@RobWinch,特别是来自Spring作者的评论。我会看一看。我试图保存对象,但没有成功。在pom.xml中,这意味着添加到maven编译器插件:true行、vars、source
<authentication-manager >
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="myUserDetailsService"
class="com.company.service.UserDetailsServiceImpl" />
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<global-method-security secured-annotations="enabled" pre-post-annotations="enabled">
<expression-handler ref="expressionHandler"/>
</global-method-security>
<beans:bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<beans:property name="permissionEvaluator">
<beans:bean id="permissionEvaluator" class="com.company.web.security.MethodsPermissionEvaluator"/>
</beans:property>
</beans:bean>
@Override
public Company create() {
Company company = new Company();
company.setCreationDate(new Date());
save(company);
return company;
}
@RequestMapping(value = {"/company"}, method = RequestMethod.GET)
public String createForm(Model model) {
model.addAttribute("company", companyService.createCompany());
return "company";
}
public Company createCompany() {
return companyDao.create();
}
<target name="compile" depends="init"
description="compile the source">
<javac srcdir="${src}" destdir="${build}" source="1.7" target="1.7"
nowarn="true" debug="true" debuglevel="lines,source,vars"
includeantruntime="true" deprecation="${deprecation}">
<compilerarg value="-Xbootclasspath/p:${toString:pathing.classpath}"/>
</javac>
<javac srcdir="${project_dir}/src/test" destdir="${build}" source="1.7" target="1.7"
nowarn="true" debug="true" debuglevel="lines,source,vars"
includeantruntime="true" deprecation="${deprecation}">
<compilerarg value="-Xbootclasspath/p:${toString:pathing.classpath}"/>
</javac>
</target>