2014-07-27 16 views
12

Zaimplementowałem uwierzytelnianie użytkownika za pomocą Spring Security Framework i wszystko działa poprawnie. mogę się zalogować i wylogować, mogę się zalogować nazwę użytkownika, na przykład tak:Zabezpieczenie przed wiosennym pobraniem obiektu użytkownika

String userName = ((UserDetails) auth.getPrincipal()).getUsername(); 

Teraz chcę uzyskać użytkownikowi jak przedmiot z bazy danych (muszę identyfikator użytkownika i inne właściwości użytkownika).

ten sposób próbowałem dotąd:

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 

Następnie dostałem następujący wyjątek:

Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to net.viralpatel.contact.model.User 

Oto jest pytanie - w jaki sposób można uzyskać użytkownika, jak przedmiot, jak należy zmodyfikować mój klasy UserDetailsServiceImpl i UserAssembler, wszelkie pomysły?

@Component 
@Transactional 
public class UserDetailsServiceImpl implements UserDetailsService{ 

    @Autowired 
    private UserDAO userDAO; 

    @Autowired 
    private UserAssembler userAssembler; 

    private static final Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class); 

    @Transactional(readOnly = true) 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { 
     User user = userDAO.findByEmail(username); 

     if(null == user) throw new UsernameNotFoundException("User not found"); 
     return userAssembler.buildUserFromUser(user); 
    } 
} 

I jeszcze jedno:

@Service("assembler") 
public class UserAssembler { 

    @Autowired 
    private UserDAO userDAO; 

    @Transactional(readOnly = true) 
    public User buildUserFromUser(net.viralpatel.contact.model.User user) { 
     String role = "ROLE_USER";//userEntityDAO.getRoleFromUserEntity(userEntity); 

     Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
     authorities.add(new GrantedAuthorityImpl(role)); 

     return new User(user.getLogin(), user.getPassword(), true, true, true, true, authorities); 
    } 
} 

Odpowiedz

0

Wygląda klasy użytkownika w nie rozszerzające klasę Wiosny org.springframework.security.core.userdetails.User.

Oto przykładowy kod dla odniesienia, nazwałem klasę o nazwie jako „AuthenticUser”:

public class AuthenticUser extends User { 

     public AuthenticUser(String username, String password, boolean enabled, 
     boolean accountNonExpired, boolean credentialsNonExpired, 
     boolean accountNonLocked, 
     Collection<? extends GrantedAuthority> authorities) { 

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

Teraz można utworzyć obiekt tej klasy w kodzie i ustawić ją jako część kontekstu Authentication Wiosna np

AuthenticUser user = new AuthenticUser(username, password, .... rest of the parameters); 
    Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, 
     user.getAuthorities()); 
    SecurityContextHolder.getContext().setAuthentication(authentication); 

Spowoduje to uwierzytelnienie użytkownika i ustawienie użytkownika w kontekście zabezpieczeń.

+0

moja klasa Użytkownik nie jest tylko Podmiot – user3127896

+0

Jak wspomniano, trzeba rozszerzyć Wiosenna klasa użytkownika. –

+0

Mam błąd - nie ma domyślnego konstruktora dla użytkownika – user3127896

12

Zasadniczo musisz zwrócić implementację UserDetails, która zapewnia dostęp do Twojego User.

Masz dwie opcje:

  • Dodaj swoją User jako pole (można zrobić to być rozszerzenie org.springframework.security.core.userdetails.User):

    public class UserPrincipal extends org.springframework.security.core.userdetails.User { 
        private final User user; 
        ... 
    } 
    

    i uzyskać User z tej dziedziny:

    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    User user = ((UserPrincipal) principal).getUser(); 
    
  • Utwórz klasę tha t rozszerza User i wdraża UserDetails:

    public class UserPrincipal extends User implements UserDetails { 
        ... 
        public UserPrincipal(User user) { 
         // copy fields from user 
        } 
    } 
    

    Takie podejście pozwala rzucić kapitał do User bezpośrednio:

    User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    
0

Trzeba zaimplementować własną UserDetailsService i własne UserDetails object (zgodnie z życzeniem):

public class CustomService implements UserDetailsService { 
@Transactional(readOnly = true) 
public UserDetails loadUserByUsername(String userId) { 

    Account account = accountDAO.findAccountByName(userId); 

    // validation of the account 
    if (account == null) { 
     throw new UsernameNotFoundException("not found"); 
    } 
    return buildUserFromAccount(account); 
} 


@SuppressWarnings("unchecked") 
@Transactional(readOnly = true) 
private User buildUserFromAccount(Account account) { 

    // take whatever info you need 
    String username = account.getUsername(); 
    String password = account.getPassword(); 
    boolean enabled = account.getEnabled(); 
    boolean accountNonExpired = account.getAccountNonExpired(); 
    boolean credentialsNonExpired = account.getCredentialsNonExpired(); 
    boolean accountNonLocked = account.getAccountNonLocked(); 

    // additional information goes here 
    String companyName = companyDAO.getCompanyName(account); 


    Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
    for (Role role : account.getRoles()) { 
     authorities.add(new SimpleGrantedAuthority(role.getName())); 
    } 

    CustomUserDetails user = new CustomUserDetails (username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, 
      authorities, company); 

    return user; 
} 


public class CustomUserDetails extends User{ 

// ... 
public CustomUserDetails(..., String company){ 
    super(...); 
    this.company = company; 
} 

private String company; 

public String getCompany() { return company;} 

public void setCompany(String company) { this.company = company;} 
} 

Uwaga:
Jest to domyślna implementacja klasy User Ci trzeba mieć pewne informacje niestandardowe, które można zrobić niestandardową klasę i rozszerzyć klasę użytkownika

Powiązane problemy