使用PlainUsername的空指针异常

时间:2016-09-23 06:52:10

标签: grails spring-security

当我编辑用户时,所有人都在保存,但是当我更改密码时,它会收到错误。请帮助我。

 NullPointerException occurred when processing request: [POST] /openbrm   /user/save
 Stacktrace follows:
 java.lang.NullPointerException
at     com.sapienter.jbilling.client.authentication.CompanyUserDetails.getPlainUsername(CompanyUserDetails.java:84)
at  com.sapienter.jbilling.client.authentication.JBillingPasswordEncoder.isPasswordValid(JBillingPasswordEncoder.java:75)
at com.sapienter.jbilling.client.user.UserHelper.bindPassword(UserHelper.groovy:155)
at jbilling.UserController.save(UserController.groovy:304)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

UserController.groovy

def save () {
    UserWS user = new UserWS()
    user.mainRoleId= Constants.TYPE_ROOT
    UserHelper.bindUser(user, params)
    def contacts = []

    def userId= params['user']['userId'] as Integer

    log.debug "Save called for user ${userId}"

    def oldUser = userId ? webServicesSession.getUserWS(userId) : null

    def company_id = session['company_id']
    def company = CompanyDTO.createCriteria().get {
        eq("id", company_id)
        fetchMode('contactFieldTypes', FM.JOIN)
    }


    if ( !oldUser || SpringSecurityUtils.ifAllGranted('ROLE_SUPER_USER') || SpringSecurityUtils.ifAllGranted('MY_ACCOUNT_162') ) {
        UserHelper.bindUser(user, params)
        UserHelper.bindContacts(user, contacts, company, params)
    } else {
        user= oldUser
        contacts= userId ? webServicesSession.getUserContactsWS(userId) : null
    }



    if ( !oldUser || SpringSecurityUtils.ifAllGranted('ROLE_SUPER_USER') || SpringSecurityUtils.ifAllGranted('MY_ACCOUNT_161') ) {
        UserHelper.bindPassword(user, oldUser, params, flash)
    } else {
        user.password= null
    }
    UserDTO loggedInUser = UserDTO.get(springSecurityService.principal.id)
    if (flash.error) {
        user = new UserWS()
        UserHelper.bindUser(user, params)
        contacts = []
        UserHelper.bindContacts(user, contacts, company, params)
        render view: 'edit', model: [user: user, contacts: contacts, company: company, loggedInUser: loggedInUser, roles: loadRoles()]
        return
    }

    try {

        if (!oldUser) {
            log.debug("creating user ${user}")

            user.userId = webServicesSession.createUser(user)

            flash.message = 'user.created'
            flash.args = [user.userId as String]

        } else {
            log.debug("saving changes to user ${user.userId}")

            webServicesSession.updateUser(user)

            flash.message = 'user.updated'
            flash.args = [user.userId as String]
        }

        // save secondary contacts
        if (user.userId) {
            contacts.each {
                webServicesSession.updateUserContact(user.userId, it);
            }
        }

    } catch (SessionInternalError e) {
        flash.clear()
        viewUtils.resolveException(flash, session.locale, e)
        contacts = userId ? webServicesSession.getUserContactsWS(userId) : null
        if(!contacts && !userId){
            contacts = [user.getContact()]
        }
        render view: 'edit', model: [user: user, contacts: contacts, company: company, loggedInUser: loggedInUser, roles: loadRoles()]
        return
    }

    if ( SpringSecurityUtils.ifAnyGranted("MENU_99") || SpringSecurityUtils.ifAnyGranted("ROLE_SUPER_USER") ) {
        chain action: 'list', params: [id: user.userId]
    } else {
        chain action: 'edit', params: [id: user.userId]
    }
}

在UserHelper.groovy中,此方法出现错误

       static def bindPassword(UserWS newUser, UserWS oldUser, GrailsParameterMap params, flash) {
       if (oldUser) {
        // validate that the entered confirmation password matches the users existing password
        if (params.newPassword) {

            //read old password directly from DB. API does not reveal password hashes
            def oldPassword = UserDTO.get(oldUser.userId).password

            PasswordEncoder passwordEncoder = Context.getBean(Context.Name.PASSWORD_ENCODER)
            //fake user details so we can verify the customers password
            //should we move this to the server side validation?
            CompanyUserDetails userDetails = new CompanyUserDetails(
                    oldUser.getUserName(), oldPassword, true, true, true, true,
                    Collections.EMPTY_LIST, null,null,oldUser.getUserId(), oldUser.getMainRoleId(), oldUser.getEntityId(),
                    oldUser.getCurrencyId(), oldUser.getLanguageId()
            )
            if (!passwordEncoder.isPasswordValid(oldPassword, params.oldPassword, userDetails)) {
                flash.error = 'current.password.doesnt.match.existing'
                return
            }

        } else {
            newUser.setPassword(null)
        }
    }

    // verify passwords only when new password is present
    if (params.newPassword) {
        if (params.newPassword == params.verifiedPassword) {
            if (params.newPassword)
                newUser.setPassword(params.newPassword)
        } else {
            flash.error = 'passwords.dont.match'
        }
    } else {
        newUser.setPassword(null)
    }
    }

我的CompanayUserDetails.java

 package com.sapienter.jbilling.client.authentication;

 import com.sapienter.jbilling.server.user.db.UserDTO;
 import org.springframework.security.core.GrantedAuthority;
 import grails.plugin.springsecurity.userdetails.GrailsUser;
 import java.util.Collection;
 import java.util.Locale;


public class CompanyUserDetails extends GrailsUser {

private final UserDTO user;
private final Locale locale;
private final Integer mainRoleId;
private final Integer companyId;
private final Integer currencyId;
private final Integer languageId;

 public CompanyUserDetails(String username, String password, boolean enabled, boolean accountNonExpired,
                          boolean credentialsNonExpired, boolean accountNonLocked,
                          Collection<GrantedAuthority> authorities,
                          UserDTO user, Locale locale,
                          Integer id, Integer mainRoleId, Integer companyId, Integer currencyId, Integer languageId) {

    super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities, id);

    this.user = user;
    this.locale = locale;
    this.mainRoleId = mainRoleId;
    this.companyId = companyId;
    this.currencyId = currencyId;
    this.languageId = languageId;
}


   public UserDTO getUser() {
    return user;
  }


   public String getPlainUsername() {
    return user.getUserName();
  }


public Locale getLocale() {
    return locale;
}


public Integer getMainRoleId() {
    return mainRoleId;
}


public Integer getUserId() {
    return (Integer) getId();
}


public Integer getCompanyId() {
    return companyId;
}


public Integer getCurrencyId() {
    return currencyId;
}


public Integer getLanguageId() {
    return languageId;
}

  @Override
  public String toString() {
    final StringBuilder sb = new StringBuilder();
    sb.append("CompanyUserDetails");
    sb.append("{id=").append(getId());
    sb.append(", username=").append("'").append(getUsername()).append("'");
    sb.append(", mainRoleId=").append(getMainRoleId());
    sb.append(", companyId=").append(getCompanyId());
    sb.append(", currencyId=").append(getCurrencyId());
    sb.append(", languageId=").append(getLanguageId());
    sb.append(", enabled=").append(isEnabled());
    sb.append(", accountExpired=").append(!isAccountNonExpired());  
    sb.append(", credentialsExpired=").append(!isCredentialsNonExpired());
    sb.append(", accountLocked=").append(!isAccountNonLocked());
    sb.append('}');
    return sb.toString();
    }
 }

3 个答案:

答案 0 :(得分:0)

您正在将null传递给UserDTO

的构造函数

代表

Collection<GrantedAuthority> authorities, UserDTO user, Locale locale,

你正在传递

Collections.EMPTY_LIST, null,null

当然getPlainUsername将失败

答案 1 :(得分:0)

致电new CompanyUserDetails

CompanyUserDetails userDetails = new CompanyUserDetails(
    oldUser.getUserName(), oldPassword, true, true, true, true,
    Collections.EMPTY_LIST, null, <--- param $8 is null

和定义

 public CompanyUserDetails(String username, String password, boolean enabled, boolean accountNonExpired,
     boolean credentialsNonExpired, boolean accountNonLocked,
     Collection<GrantedAuthority> authorities,
     UserDTO user, <--- param #8

最后NPE在您致电getPlainUsername

return user.getUserName();

NPE,无法在null user对象上调用方法。

答案 2 :(得分:0)

因此,要了解您的问题,您需要了解错误代码:

显示java.lang.NullPointerException at com.sapienter.jbilling.client.authentication.CompanyUserDetails.getPlainUsername( CompanyUserDetails.java:84

根据我的编辑第84行

 sb.append(", languageId=").append(getLanguageId());

我建议作为测试将所有这些设置为值

private final Integer mainRoleId=0;
private final Integer companyId=0;
private final Integer currencyId=0;
private final Integer languageId=0;

然后改变

this.mainRoleId = mainRoleId;
    this.companyId = companyId;
    this.currencyId = currencyId;
    this.languageId = languageId

if (mainRoleId)  { this.mainRoleId = mainRoleId;}
if (companyId)  {   this.companyId = companyId; }
if (currencyId)  {   this.currencyId = currencyId; }
if (languageId )  {   this.languageId = languageId }

错误的编码会导致不良问题

相关问题