JBoss Seam – rozszerzanie magazynu tożsamości
Ostatnio opisałem dodawanie dodatkowych informacji do tożsamości (identity). Tym razem chciałbym zająć się ustawieniem wartości nowych właściwości za na podstawie danych dotyczących użytkownika pobranych z bazy.
Aby ustalić, które pola encji User zawierają interesujące mnie informacje, muszę dodać do nich odpowiednie adnotacje. W celu oznaczenia imienia i nazwiska mogę wykorzystać adnotacje org.jboss.seam.annotations.security.management.UserFirstName i org.jboss.seam.annotations.security.management.UserLastName, ale dla klucza głównego i adresu email muszę zdefiniować własne:
@Target({METHOD,FIELD})
@Documented
@Retention(RUNTIME)
@Inherited
public @interface UserId {
}
@Target({METHOD,FIELD})
@Documented
@Retention(RUNTIME)
@Inherited
public @interface UserEmail {
}
Tworzenie adnotacji częściowo omówiłem przy okazji zapisu do pliku XML. Jednak dwie adnotacje wymagają wyjaśnienia:
java.lang.annotation.Documented- jest wskazówką dla JavaDoc, aby umieścić adnotację w dokumentacji,
java.lang.annotation.Inherited- określa, że adnotacja ma być dziedziczona przez klasy potomne.
Następnym krokiem będzie rozszerzenie encji User. Wpierw dodam nowo utworzoną adnotację @UserId do pola id:
@Id @Column(name = "id") @NotNull @UserId protected long id;
Następnie zdefiniuję pola reprezentujące imię, nazwisko i adres email, z odpowiadającymi im adnotacjami @UserFirstName, @UserLastName i @UserEmail:
@Column(name = "first_name") @Length(max = 32) @UserFirstName protected String firstName; @Column(name = "last_name") @Length(max = 32) @UserLastName protected String lastName; @Column(name = "email") @Email @Length(max = 32) @UserEmail protected String email;
Teraz wreszcie jestem gotów do zdefiniowania nowego komponentu identityStore:
@Name("org.jboss.seam.security.identityStore")
@Scope(ScopeType.APPLICATION)
@Install(precedence = Install.DEPLOYMENT)
@BypassInterceptors
@Startup
public class EnhancedJpaIdentityStore
extends JpaIdentityStore {
private static final long serialVersionUID = 1L;
}
Adnotacje do klasy omówiłem w poprzednim wpisie, jednak dwie wartości różnią się od poprzedniej sytuacji. Zakres komponentu (@Scope) ustawiony jest na aplikację, natomiast pierwszeństwo w adnotacji @Install ma wartość Install.DEPLOYMENT = 30 – zdefiniowaną specjalnie w celu przesłaniania domyślnych komponentów z pierwszeństwem Install.APPLICATION.
Wewnątrz klasy definiuję obiekty klasy org.jboss.seam.util.AnnotatedBeanProperty – odpowiedzialne za dostęp do pól lub właściwości oznaczonych konkretnymi adnotacjami:
private AnnotatedBeanProperty<UserId>
userIdProperty;
private AnnotatedBeanProperty<UserFirstName>
userFirstNameProperty;
private AnnotatedBeanProperty<UserLastName>
userLastNameProperty;
private AnnotatedBeanProperty<UserEmail>
userEmailProperty;
Obiekty te tworzone będą w przeciążonej metodzie init, wywoływanej podczas tworzenia nowej instancji komponentu (adnotacja org.jboss.seam.annotations.Create):
@Create
@Override
public void init() {
super.init();
this.userIdProperty =
new AnnotatedBeanProperty<UserId>(
this.getUserClass(), UserId.class);
this.userFirstNameProperty =
new AnnotatedBeanProperty<UserFirstName>(
this.getUserClass(), UserFirstName.class);
this.userLastNameProperty =
new AnnotatedBeanProperty<UserLastName>(
this.getUserClass(), UserLastName.class);
this.userEmailProperty =
new AnnotatedBeanProperty<UserEmail>(
this.getUserClass(), UserEmail.class);
}
Przeciążona metoda authenticate pozwoli – po udanym uwierzytelnieniu – dodać odpowiednie wartości do rozszerzonej tożsamości:
@Override
public boolean authenticate(String username, String password) {
boolean success = super.authenticate(username, password);
EnhancedIdentity identity = EnhancedIdentity.instance();
if (success) {
Object user = this.lookupUser(username);
if (this.userIdProperty != null) {
identity.setId((Long)
this.userIdProperty.getValue(user));
}
if (this.userFirstNameProperty != null) {
identity.setFirstName((String)
this.userFirstNameProperty.getValue(user));
}
if (this.userLastNameProperty != null) {
identity.setLastName((String)
this.userLastNameProperty.getValue(user));
}
if (this.userEmailProperty != null) {
identity.setEmail((String)
this.userEmailProperty.getValue(user));
}
}
return success;
}
Wykorzystałem tutaj statyczną metodę EnhancedIdentity.instance, w celu pobrania instancji tożsamości odpowiedniej dla aktualnej sesji.
Encja użytkownika o podanej nazwie (loginie) pobierana jest przy pomocy metody lookupUser klasy JpaIdentityStore.
Po odpowiednim uzupełnieniu bazy danych na stronie wyświetlone zostaną personalia zalogowanego użytkownika. Adres email i klucz główny także będą dostępne przy wykorzystaniu komponentu klasy EnhancedIdentity.



