web-dev-qa-db-ja.com

AuthenticationCredentialsNotFoundException:認証オブジェクトがセキュリティコンテキストで見つかりませんでした

chromeブラウザからREST URL -- http:/)として公開されているコントローラにJSONペイロードを送信しようとすると、以下のエラーが発生します/ localhost:8080/services/acc/create

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/services] threw exception [Request processing failed; nested exception is org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext] with root cause
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.Java:339)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.Java:198)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.Java:60)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.Java:655)
    at com.webadvisors.controller.HotelRestController$$EnhancerBySpringCGLIB$$e9f80d9.createHotel(<generated>)
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.Java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:114)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.Java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.Java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:650)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:731)

承認タイプとしてBasicAuthを選択し、JSONペイロードをPOSTMANのREST URLに送信するときにユーザー名とパスワードを入力しました。

1)コントローラークラス

@RestController
public class AccountRestController {

    @Autowired
    private AccountService accountService;

    @PreAuthorize("hasAnyRole('ADMINISTRATOR')")
    @RequestMapping(value= "/acc/create", method=RequestMethod.POST)
    public HotelDTO createHotel(@RequestBody AccountDTO accDTO) throws Exception{
        return accountService.create(accDTO);
    }
} 

2)セキュリティ構成クラス

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@ComponentScan(basePackages = "com.freelance", scopedProxy = ScopedProxyMode.INTERFACES)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationService")
    private UserDetailsService userDetailsService;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http
                .authorizeRequests()
                .antMatchers("/user/**").permitAll()
                .anyRequest().fullyAuthenticated();
        http.httpBasic();
        http.csrf().disable();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }
}

3)春のセキュリティ依存関係

<dependency>
    <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>3.2.3.RELEASE</version>
   </dependency>
   <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>

POSTMANで認証資格情報を送信しています。しかし、それでもなぜ私は上記の例外を取得しているのですか?.

6
JavaDeveloper

springSecurityFilterChainWebSecurityConfigurerAdapterを作成しました。 春のセキュリティリファレンス を参照してください。

最初のステップは、Spring Security Java構成を作成することです。構成は、すべてのセキュリティ(アプリケーションURLの保護、検証)を担当するspringSecurityFilterChainと呼ばれるサーブレットフィルターを作成します。アプリケーション内で送信されたユーザー名とパスワード、ログインフォームへのリダイレクトなど)。

しかし、あなたはそれを使用しませんでした(それはあなたのスタックトレースにありません)。

springSecurityFilterChainを登録する必要があります。サーブレット3.0以降の環境を使用している場合は、 Spring Security Reference を参照してください。

Spring MVCを使用したAbstractSecurityWebApplicationInitializer

アプリケーションの他の場所でSpringを使用していた場合、Spring構成をロードしているWebApplicationInitializerがすでに存在している可能性があります。以前の構成を使用すると、エラーが発生します。代わりに、SpringSecurityを既存のApplicationContextに登録する必要があります。たとえば、Spring MVCを使用している場合、SecurityWebApplicationInitializerは次のようになります。

_import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
  extends AbstractSecurityWebApplicationInitializer {

}
_

これは、アプリケーション内のすべてのURLに対してspringSecurityFilterChainフィルターを登録するだけです。その後、WebSecurityConfigが既存のApplicationInitializerにロードされていることを確認します。たとえば、Spring MVCを使用している場合は、getRootConfigClasses()に追加されます。

_public class MvcWebApplicationInitializer extends
      AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
      return new Class[] { WebSecurityConfig.class };
  }

  // ... other overrides ...
}
_
5
dur