2016-11-01 4 views
1

Можно ли предоставить API-интерфейс, созданный с помощью Spring Data Rest, для управления теми же пользователями, что и с весной, для проверки подлинности и контроля доступа?spring data rest: Как опубликовать руководство пользователя api

Рассмотрим сущность:

@Entity 
public class User implements UserDetails { 
    .... 
} 

, который используется с пружинным безопасности:

@Service 
public class RepositoryUserDetailsService implements UserDetailsService{ 

    private final UnsecuredUserRepository users; 

    @Autowired 
    public RepositoryUserDetailsService(UnsecuredUserRepository users) { 
     this.users = users; 
    } 

    @Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     User one = users.findOne(username); 
     if (one == null) { 
      throw new UsernameNotFoundException("No such user"); 
     } 
     return one; 
    } 

} 

Он использует следующий репозиторий весной данных:

public interface UnsecuredUserRepository extends CrudRepository<User, String> { 
} 

Теперь я хочу добавить admin API для управления пользователями. Подставка для данных Spring может сделать это для меня, и я могу использовать весеннюю безопасность для ее защиты.

@PreAuthorize("hasRole('ROLE_USER_MANAGER')") 
public interface UserRepository extends CrudRepository<User, String>, UserSignUpExtension { 

    @Override 
    @PreAuthorize("hasRole('ROLE_USER_MANAGER') or #userName == authentication?.name") 
    void delete(@Param("userName") String userName); 

} 

Проблема заключается в том, что один не может иметь multiple repositories for the same entities with spring data rest, используя обеспеченное репо создает проблему куриного яйца, а также предотвращает меня от стартового кода, который создает пользователь по умолчанию (так как проверки безопасности, уже применяется).

+0

попробуйте выполнить команду curl: http://www.codingpedia.org/ama/how-to-test-a-rest-api-from-command-line-with-curl/ –

+0

Команда curl не поможет , Проблема заключается не в тестировании API, а в том, чтобы разоблачить его в первую очередь. – Alpar

+0

Это действительно смешно. Просто создайте другой репозиторий без разрешения или спящего режима или что-то, что запускается при запуске, чтобы создать учетную запись пользователя. Это репо не должно быть доступно клиенту в любом случае. – Snickers3192

ответ

1

Мне удалось решить это, в конце концов, обняв весеннюю безопасность, а не пытаться обойти ее.

Я реализовал эту утилиту:

import org.springframework.security.authentication.AnonymousAuthenticationToken; 
import org.springframework.security.core.authority.AuthorityUtils; 
import org.springframework.security.core.context.SecurityContext; 
import org.springframework.security.core.context.SecurityContextHolder; 

public class AsInternalUser implements AutoCloseable { 

    private final SecurityContext previousContext; 

    public AsInternalUser() { 
     previousContext = SecurityContextHolder.getContext(); 
     SecurityContext context = SecurityContextHolder.createEmptyContext(); 
     context.setAuthentication(
       new AnonymousAuthenticationToken("INTERNAL","INTERNAL_USERNAME", AuthorityUtils.createAuthorityList("ROLE_INTERNAL")) 
     ); 
     SecurityContextHolder.setContext(
       context 
     ); 
    } 

    @Override 
    public void close() { 
     if (previousContext == null) { 
      SecurityContextHolder.clearContext(); 
     } else { 
      SecurityContextHolder.setContext(previousContext); 
     } 
    } 
} 

Мой первоначальный создание пользователей, таким образом, становится:

try (AsInternalUser __ = new AsInternalUser()) { 
      if (!users.exists(DEFAULT_ADMIN_NAME)) { 
       users.save(new User(DEFAULT_ADMIN_NAME, passwordEncoder.encode(DEFAULT_ADMIN_PASSWORD), Arrays.asList(Roles.values()))); 
      } 
     } 

И, конечно, хранилище должно предоставить доступ к новому ROLE_INTERNAL

@PreAuthorize("hasAnyRole('ROLE_USER_MANAGER', 'ROLE_INTERNAL')") 
public interface UserRepository extends CrudRepository<User, String>, UserSignUpExtension { 
} 

Другие места, такие как регистрация пользователей, также должны перерасти в внутреннюю роль.

Я думаю, что это даже лучший подход, чем обход модели безопасности, поскольку он позволяет контролировать более мелкие зерна и снижает вероятность случайного вызова необеспеченного хранилища и угрозы безопасности.

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