2013-11-18 2 views
4

Я хочу рассматривать роль как атрибут пользователя, а не иметь независимый класс ролей, поэтому мне не нужно иметь таблицу для ролей в моей БД. Но общая весна UserDetails служба проходит GrantedAuthority (т.е. Collection<GrantedAuthority> getAuthorities()) в качестве одного из параметров детализации пользователя.Исключая GrantedAuthority от userDetails весной безопасности

То, что я хочу сделать, это заменить этот общий GrantedAuthority параметр с ролью (String роль), объявленной в моем классе «User», как показано . ниже

@Entity(name="usr") 
public class User { 
    @Id 
    @Column(unique=true) 
    private String username; 
    private String password; 
    private String role; 

    public String getUsername() {    
     return username;   
    } 

    public void setUsername(String username) {   
     this.username = username;  
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public String getRole() { 
     return role; 
    } 

    public void setRole(String role) { 
     this.role = role; 
    } 
} 

И мой класс customUserdetail обслуживание:

@Service 
@Transactional(readOnly = true) 
public class CustomUserDetailsService implements UserDetailsService { 

    @Autowired 
    private UserRepository repository; 

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {    
     try { 
      x.y.User user = repository.findByUsername(username); 

      boolean enabled = true; 
      boolean accountNonExpired = true; 
      boolean credentialsNonExpired = true; 
      boolean accountNonLocked = true; 

      return new User(
        user.getUsername(), 
        user.getPassword(), 
        enabled, 
        accountNonExpired, 
        credentialsNonExpired, 
        accountNonLocked, 
        user.getRole());   

     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    }    
} 

возвращает ошибку, так как я прошел user.getRole(), который является String, вместо от Collection<GrantedAuthority> getAuthorities(), который является типом по умолчанию в весенней безопасности.

Как его настроить, чтобы я мог использовать роль (которая является строковым типом), которую я объявила как атрибут класса «Пользователь»?

Mind: нормальный поток безопасности должен быть сохранен !. что не влияет на нормальный поток пружинной безопасности.

Заранее благодарен !.

ответ

3

Это может быть сделано путем реализующего интерфейс UserDetails вашим лицом пользователя и первостепенных getAuthorities() метод:

public class User implements UserDetails { 
    ... 
    private String role; 
    ... 

    @Override 
    public Set<GrantedAuthority> getAuthorities() { 
     Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); 
     authorities.add(new SimpleGrantedAuthority(this.role)); 
     return authorities; 
    } 
} 

И это лучше держать в Spring Security именования для имен ролей, то есть, чтобы запустить его с Префикс "ROLE_".

+0

Я попытался сделать то же самое. Но ** this.role ** всегда null, когда метод ** getAuthorities() ** вызван. – annoirq

3

Ваша модель данных решительно отличается от Spring Security и ее контракта. Для экономии в Spring Security пользователь может иметь несколько ролей. Это часть контракта, установленного его интерфейсами. Ваша предлагаемая модель данных нарушает это, и поэтому не может быть сделано для работы с Spring Security без огромного количества того, что мне нравится называть «Frankensteining». Вы также потеряете большую гибкость, которая придет с дизайном Spring Security. Короче говоря, это больше усилий, чем того стоит.

Смежные вопросы