Spring 在自定义PermissionEvaluator中访问用户数据

Spring 在自定义PermissionEvaluator中访问用户数据,spring,spring-security,Spring,Spring Security,我的自定义permissionevaluator有一些问题 我在尝试访问hasPermission中的userdata时遇到nullpointer异常 我的权限评估器: @Override public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { if (authentication == null) { Sys

我的自定义permissionevaluator有一些问题

我在尝试访问hasPermission中的userdata时遇到nullpointer异常

我的权限评估器:

 @Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {

    if (authentication == null) {
        System.out.println("Auth is NULL");
        return false;
    }
    User currentUser = (User) authentication.getPrincipal();
    if (targetDomainObject instanceof Asset) {

        Asset currentAsset = (Asset) targetDomainObject;
        for (Role r : currentUser.getRoleList()) {
            if ("admin".equals(r.getRole())) {
                return true;
            }
        }

        //Check if owner of asset
        for (Asset a : currentUser.getAssets()) {
            if (null!=a && a.equals(currentAsset)) {
                return true;
            }
        }
角色r:currentUser.getRoleList{的工作方式与预期相同,但资产a:currentUser.getAssets{的行创建了一个空指针选项

我的CustomUserDetails服务:

public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {

    com.redast.model.User domainUser = getUserDAO().findByLogin(login);
    if(domainUser == null){
        throw new UsernameNotFoundException("could not find user"+login);
    }

    return new UserDAOUserDetails(domainUser);

}

private final static class UserDAOUserDetails extends com.redast.model.User implements UserDetails {

    private UserDAOUserDetails(com.redast.model.User user){
        super(user);
    }

....
}
当我使用Hibernate时,com.redast.model.User是一个实体类

登录名:

public String login() {
    try {

        Authentication request = new UsernamePasswordAuthenticationToken(this.getUserName(), this.getPassword());

        Authentication result = authenticationManager.authenticate(request);

        SecurityContextHolder.getContext().setAuthentication(result);
    } catch (AuthenticationException e) {
        return "/pages/unsecure/login";
    }
    return "/pages/unsecure/welcomePage?faces-redirect=true";
}
我的猜测是UserDAOUserDetails的构造不正确。我希望我所做的是有意义的,你可以给我一些见解来解决这个问题,谢谢

编辑:

我认为my security-context.xml可能会有所帮助:

 <!-- Set customUserDetailsService class as the authentication Manager for Spring Security-->
<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider user-service-ref="customUserDetailsService">
        <sec:password-encoder hash="bcrypt"></sec:password-encoder>
    </sec:authentication-provider>
</sec:authentication-manager>

<beans:bean id="customUserDetailsService"
            class="com.redast.service.CustomUserDetailsService">
</beans:bean>

<beans:bean id="expressionHandler"
            class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <beans:property name="permissionEvaluator" ref="myPermissionEvaluator"/>
</beans:bean>

<beans:bean id="myPermissionEvaluator" name="myPermissionEvaluator" class="com.redast.security.CustomPermissionEvaluator">

</beans:bean>
堆栈:

Information:   09:14:14.326 [http-listener-1(4)] DEBUG     o.s.orm.jpa.JpaTransactionManager - Initiating transaction rollback
Information:   09:14:14.326 [http-listener-1(4)] DEBUG o.s.orm.jpa.JpaTransactionManager - Rolling back JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@3dbdb407]
Schwerwiegend:   Error Rendering View[/pages/secure/asset.xhtml]
javax.el.ELException: /pages/secure/asset.xhtml @13,75 value="# {assets.currentAsset.assetTitle}": java.lang.NullPointerException
at   com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at  javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:174)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:83)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:66)
at org.primefaces.component.panel.PanelRenderer.encodeContent(PanelRenderer.java:206)
at org.primefaces.component.panel.PanelRenderer.encodeMarkup(PanelRenderer.java:123)
at org.primefaces.component.panel.PanelRenderer.encodeEnd(PanelRenderer.java:58)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:176)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.el.ELException: java.lang.NullPointerException
at javax.el.BeanELResolver.getValue(BeanELResolver.java:368)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
... 92 more
Caused by: java.lang.NullPointerException
at   com.redast.security.CustomPermissionEvaluator.hasPermission(CustomPermissionEvaluator.java:56)
at  org.springframework.security.access.expression.SecurityExpressionRoot.hasPermission(SecurityExpressionRoot.java:136)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:112)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:85)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:299)
at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:11)
at org.springframework.security.access.expression.method.ExpressionBasedPostInvocationAdvice.after(ExpressionBasedPostInvocationAdvice.java:51)
at org.springframework.security.access.prepost.PostInvocationAdviceProvider.decide(PostInvocationAdviceProvider.java:38)
at org.springframework.security.access.intercept.AfterInvocationProviderManager.decide(AfterInvocationProviderManager.java:73)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterInvocation(AbstractSecurityInterceptor.java:282)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:68)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.redast.service.AssetService$$EnhancerBySpringCGLIB$$32adb660.getById(<generated>)
at com.redast.managedController.AssetBean.getCurrentAsset(AssetBean.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:363)
... 99 more
我正在使用 Spring security:3.2.6.1版本 弹簧:4.1.4.释放 spring-data.jpa:1.7.2.0版本 hibernate 4.3.8.1最终版本

编辑:

用户类别:

@Entity
@Table(name = "users")
public class User implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "login")
private String login;
@Column(name = "password")
private String password;
// @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
@Column(name = "email")
private String email;
@Column(name = "firstName")
private String firstName;
@Column(name = "lastName")
private String lastName;
@Column(name = "enabled")
private Boolean enabled;

@JoinTable(name = "user_roles", joinColumns = {
    @JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {
    @JoinColumn(name = "role_id", referencedColumnName = "id")})
@ManyToMany(fetch = FetchType.LAZY)
private List<Role> roleList;

@JoinTable(name = "user_assets", joinColumns = {
    @JoinColumn(name = "users_id", referencedColumnName = "id")}, inverseJoinColumns = {
    @JoinColumn(name = "assets_id", referencedColumnName = "id")})
@ManyToMany(fetch = FetchType.LAZY)
private List<Asset> assets;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "userOuPK.user", fetch = FetchType.LAZY)
private List<UsersOu> usersOU;

public User(User user) {
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String hashedPassword = passwordEncoder.encode(user.password);

    this.id = user.id;
    this.email = user.email;
    this.enabled = user.enabled;
    this.firstName = user.firstName;
    this.lastName = user.lastName;
    this.login = user.login;
    this.roleList = user.roleList;
    this.password = user.password;
}

public User() {
}

public User(Integer id) {
    this.id = id;
}

public User(Integer id, String login, String password) {
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String hashedPassword = passwordEncoder.encode(password);
    this.id = id;
    this.login = login;
    this.password = password;
}

...getter and setter

}
用户道:

Public interface UserDAO extends JpaRepository<User, Integer>{
   User findByLogin(String login);
}

在我看来,一切都很好您的CustomPermissionEvaluator配置正确,hasPermission也被调用,这里只有一个问题是谁在引发null pOnter,从代码来看,它看起来像是从返回null值。getAssets正在抛出它

编辑: 失踪


在复制构造函数中

查看在资产a:currentUser.getAssets{'或在'if a.equalscurrentAsset'上获取空指针的确切位置{'?。在我看来,您似乎没有在getUserDAO.findByLogin方法中填充User对象的asset属性,如果您试图访问currentUser.getAssets,则currentUser不能为null。实际循环头中会出现其他异常。但是currentUser不能为null,否则第一个循环中会发生异常t loop getRoleList.Asset实际上是由hibernate延迟加载的,或者至少beI应该在if条件中添加一个null签入,查看是否仍然获得null pointer否,循环头中发生异常。检查当前用户是否为null。添加了堆栈。可能我缺少CustomPermissionEvaluator.java第56行中的内容:56?
this.assets = user.assets;
this.usersOU = user.usersOU;