2016-11-01 16 views
1

スプリングデータレスト生成APIを公開して、認証とアクセス制御にスプリングセキュリティで使用されているのと同じユーザーを管理できますか?spring data rest:ユーザー管理apiを公開する方法

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

春のセキュリティで使用されています:

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

は、私が今追加したい:

@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; 
    } 

} 

それは、次の春データリポジトリを使用しています

は、エンティティを考えてみましょう管理APIを使用してユーザーを管理します。春のデータの休憩は私のためにこれを行うことができ、私は春のセキュリティを使用してそれを保護することができます。

@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); 

} 

問題は、1つのセキュアなレポを使用して、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

これは本当に面白いheheです。アクセス権のない別のリポジトリを持っているか、休止状態であるか、起動時にユーザアカウントを作成するために実行されるものがあるだけです。このレポは、とにかくクライアントには使用できません。 – 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 { 
} 

へのアクセスを許可する必要がありますユーザー登録のような他の場所も内部の役割にエスカレーションする必要があります。

これは、より細かい粒度制御を可能にし、誤ってセキュリティ保護されていないリポジトリを呼び出してセキュリティを侵害する機会を減らすので、セキュリティモデルを迂回するよりも優れたアプローチだと思います。

関連する問題