2016-09-27 70 views
2

我對Spring很新,很抱歉,如果我的問題聽起來很愚蠢。Spring 4安全配置運行但不活躍

我想添加基本的HTTP身份驗證到我的基於Spring的REST API。

我一直在關注quite a fewtutorialsreference現在的文件,但他們似乎都表明同樣的事情,所以它似乎很明顯,我必須失去一些東西。

我要的是定義一個簡單的配置,其中每個請求的背後是HTTP驗證默認情況下,但隨後由於使用@PreAuthorize,或通過修改HttpSecurity配置需要,我們可以定義方法級別的安全性。

我已經定義了一個非常簡單的結構,例如:

@Configuration 
@EnableWebMvc 
@EnableWebSecurity 
@ComponentScan(basePackages = "com.app.rest") 
public class RESTConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests() 
       .anyRequest().hasAnyRole("USER") 
       .and() 
       .httpBasic(); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); 
    } 
} 

我然後有一個非常簡單的控制器(沒有服務,沒有什麼特別的)。

這是一個非常基本概述:

@RestController 
@RequestMapping("/images") 
public class ImagesController { 

    @JsonView(View.Basic.class) 
    @RequestMapping(value = "/{id}", method = RequestMethod.GET) 
    public ObjectXvo getImageByID(@PathVariable String id) throws IOException { 

     ObjectXvo result = doThings(); 
     return result; 
    } 
} 

相比,所有的在線教程,唯一明顯的區別是,我們加載該API的方式。因爲我們已經有一個Jetty容器運行其他事情,所以我們決定重複使用它,而不是像大多數在線一樣使用WebAppInitializer

這裏的REST API是如何定義的摘錄:

// Creating REST Servlet 
ServletContextHandler restHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); 
restHandler.setErrorHandler(null); 
restHandler.setContextPath("/rest"); 

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); 
context.setConfigLocation("com.app.test"); 
WebApplicationContext webAppContext = context; 

DispatcherServlet dispatcherServlet = new DispatcherServlet(webAppContext); 
ServletHolder springServletHolder = new ServletHolder("REST dispatcher", dispatcherServlet); 
restHandler.addServlet(springServletHolder, "/"); 
restHandler.addEventListener(new ContextLoaderListener(webAppContext)); 

// Creating handler collection 
ContextHandlerCollection handlerCollection = new ContextHandlerCollection(); 
handlerCollection.addHandler(anotherHandler); 
handlerCollection.addHandler(restHandler); 
handlerCollection.addHandler(yetAnotherHandler); 

// Setting server context 
server.setHandler(handlerCollection); 

的事情是,在運行應用程序時,是我仍然可以訪問一樣,如果我沒有設置任何安全方案的所有URL。 當調試應用程序時,我可以看到RESTConfiguration正在作爲我的配置方法中的斷點處理,肯定會被擊中。

我們很努力避免使用XML文件,因爲我們認爲註釋到目前爲止效果較好。

任何人都可以指出我正確的方向,爲什麼這個安全配置沒有被激活?

編輯:

不知道如何相關的是,是的,但如果我嘗試將@PreAuthorize添加到REST方法,我得到以下錯誤:

HTTP ERROR: 500 

Problem accessing /rest/images/I147. Reason: 

    An Authentication object was not found in the SecurityContext 

有大量信息的在互聯網上如何解決這個問題,但我想知道這是不是相關的。

回答

1

你需要註冊springSecurityFilterChain,看到Spring Security Reference

The next step is to register the springSecurityFilterChain with the war. This can be done in Java Configuration with Spring’s WebApplicationInitializer support in a Servlet 3.0+ environment. Not suprisingly, Spring Security provides a base class AbstractSecurityWebApplicationInitializer that will ensure the springSecurityFilterChain gets registered for you. The way in which we use AbstractSecurityWebApplicationInitializer differs depending on if we are already using Spring or if Spring Security is the only Spring component in our application.

如果你不使用AbstractSecurityWebApplicationInitializer你必須手動註冊springSecurityFilterChain

webAppContext.getServletContext() 
    .addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain")) 
    .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC), false, "/*"); 

參見:

+0

非常感謝!根據之前提供的樣本,我必須將過濾器添加到restHandler。 – jlengrand