当前位置:  开发笔记 > 编程语言 > 正文

AuthenticationCredentialsNotFoundException:在安全上下文中找不到Authentication对象

如何解决《AuthenticationCredentialsNotFoundException:在安全上下文中找不到Authentication对象》经验,为你挑选了1个好方法。

当我尝试将Chrome浏览器的POSTMAN插件中的JSON有效负载发送到作为REST URL公开的控制器时,我收到以下错误 - http:// 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()
    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作为授权类型,并在POSTMAN中将JSON有效负载发送到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)Spring安全依赖性


    org.springframework.security
        spring-security-config
        3.2.3.RELEASE
   
   
    org.springframework.security
    spring-security-web
    3.2.3.RELEASE

我在POSTMAN中发送身份验证凭据.但仍然为什么我得到上述例外.



1> dur..:

您创建了一个springSecurityFilterChainwith WebSecurityConfigurerAdapter,请参见Spring Security Reference:

第一步是创建我们的Spring Security Java配置。该配置将创建一个Servlet过滤器,称为Servlet过滤器,该过滤器springSecurityFilterChain负责应用程序中的所有安全性(保护应用程序URL,验证提交的用户名和密码,重定向到登录表单等)。

但是您没有使用它(它不在您的堆栈跟踪中)。

您必须注册springSecurityFilterChain。如果您具有Servlet 3.0+环境,请参阅Spring Security Reference:

带有Spring MVC的AbstractSecurityWebApplicationInitializer

如果我们在应用程序的其他地方使用Spring,则可能已经有一个WebApplicationInitializer正在加载Spring Configuration的代码。如果我们使用以前的配置,将会得到一个错误。相反,我们应该在现有上注册Spring Security 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 ...
}

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有