Spring Boot セキュリティのテストを試すために、非常に単純なデモ アプリを作成しました。
これは私のアプリ構成です
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@SpringBootApplication
public class DemoApplication extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityService securityService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(securityService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().fullyAuthenticated();
http.httpBasic();
http.csrf().disable();
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
私の UserDetailsService 実装は、「admin」ユーザーに管理者ロールを付与されたパスワード「password」を持つすべてのユーザーを受け入れます。
@Service
public class SecurityService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Collection<GrantedAuthority> authorities;
if (username.equals("admin")) {
authorities = Arrays.asList(() -> "ROLE_ADMIN", () -> "ROLE_BASIC");
} else {
authorities = Arrays.asList(() -> "ROLE_BASIC");
}
return new User(username, "password", authorities);
}
}
最後に、それを確認するための簡単なテストを作成しました。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class)
@WebAppConfiguration
public class DemoApplicationTests {
@Autowired
private AuthenticationManager authenticationManager;
@Test
public void thatAuthManagerUsesMyService() {
Authentication auth = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken("admin", "password")
);
assertTrue(auth.isAuthenticated());
}
}
テストに合格することを期待していましたが、代わりに BadCredentialsException が発生しました。デバッグ後、テストで Spring によって注入された AuthenticationManager が、私が構成したものではないことに気付きました。Eclipse デバッガーでオブジェクトを掘り下げているときに、UserDetailsServer が InMemoryUserDetailsManager であることがわかりました。
また、DemoApplication の configure() メソッドが呼び出されることも確認しました。私は何を間違っていますか?