web-dev-qa-db-ja.com

Spring Security + Spring data + MongoDBによる認証

MongoDBでSpringセキュリティを使用し(Springデータを使用)、Springセキュリティのために自分のデータベースからユーザーを取得したいと考えています。しかし、私のuserserviceタイプはサポートされていないようなので、私はそれを行うことができません。

これは私のUserServiceクラスです:

public class UserService {
    private ApplicationContext applicationContext;
    private MongoOperations mongoOperations;

    public UserService() {
        applicationContext = new AnnotationConfigApplicationContext(MongoConfig.class);
        mongoOperations = (MongoOperations) applicationContext.getBean("mongoTemplate");
    }

    public User find(String username) {
        return mongoOperations.findOne(Query.query(Criteria.where("username").is(username)), User.class);
    }
}

そして私のSecurityConfigクラス:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserService userService;

    @Autowired
    public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception {
        builder.userDetailsService(userService); //THIS DOES NOT WORK
        builder.inMemoryAuthentication().withUser("username").password("password").roles("USER");
    }

}

私がコメントした行は言う:

The inferred type UserService is not a valid substitute for the bounded parameter <T extends UserDetailsService>.

自分のデータベースからユーザーを取得できるように、どうすれば修正できますか?

18
Moody

サービス層

別のservice実装org.springframework.security.core.userdetails.UserDetailsServiceを作成し、AuthenticationManagerBuilder内に挿入する必要があります。

@Component
public class SecUserDetailsService implements UserDetailsService{

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        /*Here add user data layer fetching from the MongoDB.
          I have used userRepository*/
        User user = userRepository.findByUsername(username);
        if(user == null){
            throw new UsernameNotFoundException(username);
        }else{
            UserDetails details = new SecUserDetails(user);
            return details;
        }
    }
}

モデル

UserDetailsも実装する必要があります。これは、Springによってユーザー認証された詳細を保持するPOJOです。私が行ったように、その中にラップされたエンティティデータオブジェクトを含めることができます。

public class SecUserDetails implements UserDetails {

    private User user;

    public SecUserDetails(User user) {
        this.user = user;
    }
    ......
    ......
    ......
}

セキュリティ構成

前に作成したサービスを自動配線し、AuthenticationManagerBuilder内に設定します

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    SecUserDetailsService userDetailsService ;

    @Autowired
    public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception {
        builder.userDetailsService(userDetailsService); 
    }
}
35
Faraj Farook

UserDetailserviceを拡張するクラスを提供する独自の認証プロバイダーを作成します。 Springコンテキストxmlファイルでコンテンツスキャンが有効になっていることを確認します。

    <authentication-provider user-service-ref="userModelService">
        <password-encoder hash="sha" />
    </authentication-provider>
@Service
public class UserModelService implements UserDetailsService
{
@Autowired
private UserModelRepositoryImpl repository;



public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
    UserModel user = repository.findByUsername(username);

     if( user == null )
        throw new UsernameNotFoundException( "Name not found!" );

      List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority( user.getRole()));

      return new User(user.getUsername(), user.getSHA1Password(), authorities );
 }

public void saveUserDetails(UserModel userModel)
{
    repository.save(userModel);
}

}

このクラスは、認証に必要なユーザー名とパスワードのSpring Query Mongoを有効にします。次に、ユーザーモデルクラスを作成します。

public class UserModel
{

private String id;
@Indexed(unique=true)
private String username;
private String password;
 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;
}

DAOを拡張するユーザー実装クラスを作成します。

@Service
public class UserModelService implements UserDetailsService
{
@Autowired
private UserModelRepositoryImpl repository;



public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
    UserModel user = repository.findByUsername(username);

     if( user == null )
        throw new UsernameNotFoundException( "Oops!" );

      List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority( user.getRole()));

      return new User(user.getUsername(), user.getSHA1Password(), authorities );
 }

最後にmongoを設定すれば完了です。

4
obi