2014-01-21 82 views
3

我一直在關注JBoss Picketlink 2.5.x documentation found here,試圖創建一個自定義User模型來驗證我的應用程序。我的應用程序是部署在JBoss EAP 6.2上的典型JavaEE 6應用程序。我已經能夠成功創建自定義User模型類,並且能夠堅持用戶沒有問題。按照預期,我可以在數據庫中看到自定義屬性。我的自定義User模式是這樣的:JBoss Picketlink - 身份驗證失敗,自定義用戶模型

public class ExtendedUser extends User { 

    private static final long serialVersionUID = -9132382669181464122L; 

    @AttributeProperty 
    private String uniqueIdentifier = null; 

    ... 

} 

...並創建一個新的用戶帳戶的代碼如下所示:

ExtendedUser u = new ExtendedUser(username); 
u.setFirstName(firstName); 
u.setLastName(lastName); 
u.setEmail(emailAddress); 
u.setUniqueIdentifier(UUID.randomUUID().toString()); 

idm.add(u); 
idm.updateCredential(u, new Password(password)); 

此外,我對用戶帳戶的自定義實體模型看起來像這樣:

@Entity(name = "UserAccount") 
@Table(name = "tbl_user_account", uniqueConstraints = { 
@UniqueConstraint(columnNames = { "email" }) }) 
@IdentityManaged({ ExtendedUser.class, Agent.class }) 
public class UserAccountBean extends BaseAccountIdentityBean implements 
     IdentifiedDomainEntity { 

    private static final long serialVersionUID = -537779599507513418L; 

     <snip... irrelevant fields...> 

    @Column(length = ValidationConstants.UUID_LEN, unique = true) 
    @Unique 
    @Length(max = ValidationConstants.UUID_LEN) 
    @Index(name = "idx_user_account_uniqueid") 
    @AttributeValue(name = "uniqueIdentifier") 
    // @NotEmpty 
    private String uniqueIdentifier = null; 


... 

我看到uniqueIdentifier屬性被填充到數據庫表中按預期。但是,每當我嘗試使用以此方式創建的用戶進行身份驗證時,身份驗證都會失敗。每次。有什麼我需要做的,以利用我的自定義User對象?創建我的IdentityIdentityManager實例時,是否必須在某處指定它?我的驗證碼相對簡單,如下所示:

@Inject 
private DefaultLoginCredentials loginCredentials = null; 

    ... 

     loginCredentials.setUserId(loginName); 
    loginCredentials.setPassword(password); 

    AuthenticationResult result = identity.login(); 
    if (logger.isDebugEnabled()) { 
     logger.debug("authenticate(String, String, String) - AuthenticationResult result=" + result); //$NON-NLS-1$ 
    } 

正如我所提到的,此代碼每次都會失敗。我已經完成了雙重檢查密碼的完整性檢查,並且我知道他們是正確的。我沒有看到寫入日誌的任何異常或錯誤,所以我不確定問題可能是什麼。如果我使用由Picketlink庫提供的標準User對象,即使我爲後端數據庫使用相同的實體,代碼也可以正常工作。它只在使用ExtendedUser時失敗,所以我確信我在我的最後缺少了一些東西。有什麼建議?

更新: Picketlink 2.6.0似乎增加了一些日誌記錄。我已經升級,它仍然失敗了,但現在我看到了以下錯誤消息:

14:41:23,133 DEBUG [org.picketlink.idm.credential] (http-localhost/127.0.0.1:9080-3) Starting validation for credentials [class org.picketlink.idm.credential.UsernamePasswordCredentials][[email protected]07] using identity store [[email protected]] and credential handler [[email protected]387a19c9]. 
14:41:23,134 DEBUG [org.picketlink.idm.credential] (http-localhost/127.0.0.1:9080-3) PLIDM001003: Trying to find account [user6_4] using default account type [class org.picketlink.idm.model.basic.User] with property [loginName]. 
14:41:23,136 DEBUG [org.picketlink.idm.credential] (http-localhost/127.0.0.1:9080-3) PLIDM001003: Trying to find account [user6_4] using default account type [class org.picketlink.idm.model.basic.Agent] with property [loginName]. 
14:41:23,138 DEBUG [org.picketlink.idm.credential] (http-localhost/127.0.0.1:9080-3) Account NOT FOUND for credentials [class org.picketlink.idm.credential.UsernamePasswordCredentials][[email protected]07]. 

所以,很顯然,Picketlink試圖使用標準User對象進行身份驗證,而不是我的自定義對象。也就是說,我如何告訴Picketlink使用我自定義的ExtendedUser對象進行身份驗證?

回答

2

我剛剛和你一樣經歷了同樣的頭痛。我一直在嘗試添加我自己的用戶帳戶。我能夠得到它的唯一原因是你提到PicketLink試圖找到用戶和代理類型帳戶!這意味着你必須實現你自己的PasswordCredentialHandler。別擔心!您可以將this classthis class複製到您的項目中。內AbstractCredentialHandler的「configureDefaultSupportedAccountTypes」的方法,你會看到以下內容:

if (!this.defaultAccountTypes.contains(User.class)) { 
     this.defaultAccountTypes.add(User.class); 
    } 

    if (!this.defaultAccountTypes.contains(Agent.class)) { 
     this.defaultAccountTypes.add(Agent.class); 
    } 

只需將您的自定義帳戶類添加到它像這樣:

if (!this.defaultAccountTypes.contains(CustomUser.class)) { 
     this.defaultAccountTypes.add(CustomUser.class); 

    } 

你必須做的最後一件事就是添加PasswordCredentialHandler到IDMConfigurtion:

private void initConfig() { 
    IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder(); 

    builder 
     .named("default") 
      .stores() 
       .jpa() 
        .mappedEntity(
          AccountTypeEntity.class, 
          RoleTypeEntity.class, 
          GroupTypeEntity.class, 
          IdentityTypeEntity.class, 
          RelationshipTypeEntity.class, 
          RelationshipIdentityTypeEntity.class, 
          PartitionTypeEntity.class, 
          PasswordCredentialTypeEntity.class, 
          AttributeTypeEntity.class, 
          CustomUserEntity.class 
          ) 
        .supportGlobalRelationship(Relationship.class) 
        .addContextInitializer(this.contextInitializer) 
        .addCredentialHandler(PasswordCredentialHandler.class) 
        .supportAllFeatures(); 
    identityConfig = builder.build(); 

我希望這有助於!

1

所以我用PicketLink 2.6.0.Final試了一下。也許你應該重新下載AbstractCredentialHandler和你的類添加到defaultAccountTypes的ArrayList是這樣的:

private void configureDefaultSupportedAccountTypes(final S store) { 
     this.defaultAccountTypes = new ArrayList<Class<? extends Account>>(); 

     for (Class<? extends AttributedType> supportedType : store.getConfig().getSupportedTypes().keySet()) { 
      if (!Account.class.equals(supportedType) && Account.class.isAssignableFrom(supportedType)) { 
       this.defaultAccountTypes.add((Class<? extends Account>) supportedType); 
      } 
     } 

     //Add your CustomUser.class to the list 
     if (!this.defaultAccountTypes.contains(CustomUser.class)) { 
      this.defaultAccountTypes.add(CustomUser.class); 
     } 

     if (this.defaultAccountTypes.isEmpty()) { 
      throw MESSAGES.credentialNoAccountTypeProvided(); 
     } 
    } 

替代: 我不不認爲你需要做的上面,如果你不想。當你配置你的IdentityConfig時,你可以添加像這樣的支持類型:

IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder(); 

    builder 
     .named("default") 
      .stores() 
       .jpa() 
        .supportType(CustomUser.class) 
        .mappedEntity( 

    ...