使用Spring Security从静态文件夹服务Angular 2项目

使用Spring Security从静态文件夹服务Angular 2项目,spring,spring-mvc,angular,spring-security,Spring,Spring Mvc,Angular,Spring Security,因此,我有一个使用Angular2的工作前端和一个使用Java的工作后端,我所做的是从静态文件夹中提供index.html,其中也包含我的所有前端资源。问题是,当我尝试将Spring安全性添加到后端时,由于@EnableWebSecurity注释,资源不再可访问。当我导航到本地主机时,不会提供index.html。但是,如果我访问它或手动写入路径的任何其他资源,它将加载。 我不想以不同的方式为我的前端服务,有什么方法可以从静态的角度做到这一点吗?我尝试了以下方法: @Override publi

因此,我有一个使用Angular2的工作前端和一个使用Java的工作后端,我所做的是从静态文件夹中提供index.html,其中也包含我的所有前端资源。问题是,当我尝试将Spring安全性添加到后端时,由于@EnableWebSecurity注释,资源不再可访问。当我导航到本地主机时,不会提供index.html。但是,如果我访问它或手动写入路径的任何其他资源,它将加载。 我不想以不同的方式为我的前端服务,有什么方法可以从静态的角度做到这一点吗?我尝试了以下方法:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/front/**");
}
这里是我的安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackages = {"com.ramso.restapi.security"})
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

public static final String REMEMBER_ME_KEY = "rememberme_key";

public SecurityConfig() {
    super();
    logger.info("loading SecurityConfig ................................................ ");
}

@Autowired
private UserDetailsService userDetailsService;

@Autowired
private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;


@Autowired
private AuthenticationSuccessHandler restAuthenticationSuccessHandler;

@Autowired
private AuthenticationFailureHandler restAuthenticationFailureHandler;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
}


@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/front/**","/index.html");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .headers().disable()
        .csrf().disable()
        .authorizeRequests()
            .antMatchers("/failure").permitAll()
            .anyRequest().authenticated()
            .and()
        .exceptionHandling()
            .authenticationEntryPoint(restAuthenticationEntryPoint)
            .and()
        .formLogin()
            .loginPage("/login")
            .loginProcessingUrl("/authenticate")
            .successHandler(restAuthenticationSuccessHandler)
            .failureHandler(restAuthenticationFailureHandler)
            .usernameParameter("username")
            .passwordParameter("password")
            .permitAll()
            .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
            .deleteCookies("JSESSIONID")
            .permitAll()
            .and();

}
}
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
//registry.addViewController("/").setViewName("front/index.html");
//registry.addViewController("/").setViewName("forward:/index.html");
    registry.addViewController("/").setViewName("redirect:/index.html");

registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}

}
WebMVC配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan(basePackages = {"com.ramso.restapi.security"})
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

public static final String REMEMBER_ME_KEY = "rememberme_key";

public SecurityConfig() {
    super();
    logger.info("loading SecurityConfig ................................................ ");
}

@Autowired
private UserDetailsService userDetailsService;

@Autowired
private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;


@Autowired
private AuthenticationSuccessHandler restAuthenticationSuccessHandler;

@Autowired
private AuthenticationFailureHandler restAuthenticationFailureHandler;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
}


@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/front/**","/index.html");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .headers().disable()
        .csrf().disable()
        .authorizeRequests()
            .antMatchers("/failure").permitAll()
            .anyRequest().authenticated()
            .and()
        .exceptionHandling()
            .authenticationEntryPoint(restAuthenticationEntryPoint)
            .and()
        .formLogin()
            .loginPage("/login")
            .loginProcessingUrl("/authenticate")
            .successHandler(restAuthenticationSuccessHandler)
            .failureHandler(restAuthenticationFailureHandler)
            .usernameParameter("username")
            .passwordParameter("password")
            .permitAll()
            .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
            .deleteCookies("JSESSIONID")
            .permitAll()
            .and();

}
}
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
//registry.addViewController("/").setViewName("front/index.html");
//registry.addViewController("/").setViewName("forward:/index.html");
    registry.addViewController("/").setViewName("redirect:/index.html");

registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}

}
Application.java:

@SpringBootApplication
public class Application {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}
}

在扩展
websecurityConfigureAdapter
的类中,可以添加以下内容:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/front/**");
}
spring security应该忽略您放入
web.ignering()
方法中的任何ant匹配器

默认情况下,静态内容应放在
src/main/resources
(from)下的以下目录之一:

然后在子文件夹前面检查任何ant匹配器

例如,如果您的静态内容位于
src/main/resources/static/front
中,那么ant matcher
/front/**
应该忽略该子文件夹中的所有资源

此外,为了公开
index.html
,您应该将它放在
src/main/resources/static
中,并添加类似于以下类的内容,以便在访问站点时将其公开为主要资源:

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index.html");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }

}
当然,将其添加为ant matcher:
web.ignering().antMatchers(“/*”、“/front/**”、“index.html”)


/*
将不允许所有操作,
/**
将允许所有操作。确保将API放在安全端点上,如
/API
或类似的位置,并将静态内容放在忽略的路径上。

问题可能是angular cli将所有资源放在应用程序的根目录下。(尽管我不确定您是否正在使用angular cli)

但让我们考虑一下这个想法

角度cli输出类似于

/inline.8faab088ca0e1cca9031.bundle.js
/main.c7b67df9d7c42383815c.bundle.js
/polyfills.c234d2c8820869e3c698.bundle.js
/styles.d41d8cd98f00b204e980.bundle.css
/vendor.f0f36dacdf3fba21c295.bundle.js
这使得您很难应用spring security antMatcher

angular cli有一个名为
--deploy url=/ui/
的配置,这意味着所有脚本文件都指向一个名为
/ui/
的目录

<script type="text/javascript" src="/ui/inline.4c30f42211c1d30d3dd3.bundle.js"></script>
<script type="text/javascript" src="/ui/polyfills.c234d2c8820869e3c698.bundle.js"></script>
<script type="text/javascript" src="/ui/vendor.f0f36dacdf3fba21c295.bundle.js"></script>
<script type="text/javascript" src="/ui/main.c7b67df9d7c42383815c.bundle.js"></script>


然后你应该可以像Tom建议的那样忽略路径。

直接在static或文件夹front中,src/main/resources/static/front?我两个都试过了,现在我在src/main/resources/static/front中找到了它。你能试着访问一个特定的资源,看看问题是出在ant matcher上还是暴露了你的index.html吗?如果您在公开index.html(假设它在前面的文件夹中)时遇到问题,我可以添加相关代码以在我的答案中公开它。让我们一起来。这样,我最终可以使用以下atmatcher使其工作:web.ignoreing().antMatchers(“/”,“/front/**”,“index.html”);如果我使用不带星号的“/”,则会提供html,并且不会忽略任何其他路由。我认为这个主题是封闭的:谢谢你的时间和努力,只是一件小事花费太多的麻烦。xDIm不使用angular cli