2014-02-09 63 views
3

我有一個Spring MVC的休息Web應用程序爲我在加入春季安全的層的過程很。添加Spring Security以現有的Spring Web應用程序(使用JavaConfig)

雖然我經歷了Spring documentation,我無法皮卡第3.1.3節的含義。我複製/粘貼以下部分的內容。

If we were using Spring elsewhere in our application we probably already had a WebApplicationInitializer that is loading our Spring Configuration. If we use the previous configuration we would get an error. Instead, we should register Spring Security with the existing ApplicationContext. For example, if we were using Spring MVC our SecurityWebApplicationInitializer would look something like the following: 

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

public class SecurityWebApplicationInitializer 
     extends AbstractSecurityWebApplicationInitializer { 

} 

This would simply only register the springSecurityFilterChain Filter for every URL in your application. After that we would ensure that SecurityConfig was loaded in our existing ApplicationInitializer. For example, if we were using Spring MVC it would be added in the getRootConfigClasses() 

public class MvcWebApplicationInitializer extends 
     AbstractAnnotationConfigDispatcherServletInitializer { 

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

    // ... other overrides ... 
} 

所以,我已經有以下

an Initializer.java (replacement of web.xml) 
Config.java - Root Context 
RestServlet.java - Servlet Context 

這裏是我的Initializer.java

public class Initializer implements WebApplicationInitializer { 

    public void onStartup(ServletContext container) throws ServletException { 

     // Create the 'root' Spring application context 
     AnnotationConfigWebApplicationContext rootContext = 
     new AnnotationConfigWebApplicationContext(); 
     rootContext.register(Config.class); 

     // Manage the lifecycle of the root application context 
     container.addListener(new ContextLoaderListener(rootContext)); 
//  container.addListener(new ContextLoaderListener(rootContext)); 

     // Create the dispatcher servlet's Spring application context 
     AnnotationConfigWebApplicationContext dispatcherContext = 
     new AnnotationConfigWebApplicationContext(); 
     dispatcherContext.register(RestServlet.class); 

     // Register and map the dispatcher servlet 
     ServletRegistration.Dynamic dispatcher = 
     container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext)); 
     dispatcher.setLoadOnStartup(1); 
     dispatcher.addMapping("/"); 


    } 
} 

要添加Spring Security的層,我增加了以下

SecurityConfig.java 
SecurityInitializer.java 

SecurityConfig.java(這是爲了測試在內存中使用auth的細節)。

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

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

SecurityInitializer.java

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer 
       { 


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

現在的問題是,我不知道如何執行這些步驟。我不知道(基於文檔的3.2.3節),如果我要延長AbstractSecurityWebApplicationInitializer或AbstractAnnotationConfigDispatcherServletInitializer。

的另一個問題是,這是一個REST的應用程序。我沒有任何控制器返回jsps(我不想!)。我的最終目標是使用OAuth2,生成並向前端Web應用發佈令牌(基於Angular),並以這種方式保護REST API。在此之上添加Facebook和Google+登錄。但我在春季安全方面正在採取寶貝步驟,我被困在這裏。想知道是否有誰已經採取這條道路已經可以分享他們的智慧。

+0

你用這個成功了嗎? –

+0

@最終用戶這已經有一段時間了,所以我不記得我確實做了什麼來解決它,但這裏是當前工作配置作爲參考https://github.com/billrive/billrive/tree/master/billrive- app/src/main/java/com/uhsarp/billrive/spring – user6123723

回答

1

一個你需要做下面的步驟完成「3.4。授權要求」一節。您需要創建控制器才能創建RESTful服務。您可以返回JSON或XML,而不是返回一個JSP頁面。要創建一個RESTful Web服務,請參閱Spring.io文檔(http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch18s02.html),這是春天3.0的鏈接,有可能是可用的新版本爲Spring 4.0,但這個環節應該給你足夠的信息讓你開始對REST事物的一面。一旦你有你的REST請求設置例如@RequestMapping("https://stackoverflow.com/users/{userid}", method=RequestMethod.GET)

那麼你現在可以按照3.4節即.antMatchers("https://stackoverflow.com/users/**").hasRole("USER")

下一個步驟將是看看認證和設置保存你的用戶/密碼,您的數據源,你有2個選項,在這裏我會使用內存建議配置首先請參閱「3.5.1。在內存認證」以獲取更多信息。

+0

謝謝。但我無法通過第3.2.3節。我不確定如何擴展AbstractSecurityWebApplicationInitializer和/或AbstractAnnotationConfigDispatcherServletInitializer以及如何與現有的Config/Initializer類集成。 – user6123723

+0

如果您已經有一個實現WebApplicationInitializer並實現onStartup方法(加載您的Spring應用程序配置)的類「WebAppInitializer」,那麼您將使用「AbstractSecurityWebApplicationInitializer」。否則,您會希望使用AbstractSecurityWebApplicationInitializer方法。 – ebell

4

可以按如下方式注入這是一個正常的@Configuration類:

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    FooUserDetailsService fooUserDetailsService; 

    @Autowired 
    PasswordEncoder passwordEncoder; 

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

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

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http 
      .authorizeRequests() 
       .antMatchers("/signup").anonymous() 
       .antMatchers("/public/**").permitAll() 
       .antMatchers("/auth/**").permitAll() 
       .antMatchers("/api/**").hasRole("USER") 
       .antMatchers("/**").hasAnyRole("USER", "ADMIN") 
      .and() 
       .csrf().disable() 
       .formLogin() 
       .loginProcessingUrl("/j_spring_security_check") 
       .loginPage("/auth").failureUrl("/auth") 
       .usernameParameter("j_username").passwordParameter("j_password") 
       .defaultSuccessUrl("/") 
      .and() 
       .logout() 
       .logoutUrl("/j_spring_security_logout") 
       .logoutSuccessUrl("/auth"); 
    } 
} 

的路徑,在這裏只是例子,你將有可能改寫這個適合你有需求,比如移除表單登錄的東西,如果這是一個純粹的REST API你正在做。

爲了有這個加載,你可以做如下:

public class WebApplicationInitialiser implements WebApplicationInitializer { 

    private static Class<?>[] configurationClasses = new Class<?>[] { 
     WebSecurityConfiguration.class 
    }; 
} 

添加類(如我假設你有一個以上的)的情況下與createContext(configurationClasses);

我希望這是有幫助的。

0

實際上有兩個註冊的上下文加載器監聽器會觸發一個框架相關的異常。這兩個上下文加載器偵聽器註冊場景發生在一個已經通過java-config裝入DispatcherServlet配置時,通過擴展AbstractAnnotationConfigDispatcherServletInitializer - > root-config類將在ContextLoaderListener上下文中註冊;現在通過擴展AbstractSecurityWebApplicationInitializer啓用安全性方面將嘗試創建另一個ContextLoaderListener如果給出任何根配置類。所以建議如果已經有一個ContextLoaderListener和root-related-config bean,以避免通過AbstractSecurityWebApplicationInitializer註冊其他root-related-config bean。

相關問題