【问题标题】:Serve Angular 2 project from static folder with Spring Security使用 Spring Security 从静态文件夹服务 Angular 2 项目
【发布时间】:2017-07-10 03:48:26
【问题描述】:

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

这里是我的安全配置:

@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();

}
}

WebMvc 配置:

@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);
}
}

【问题讨论】:

    标签: spring spring-mvc angular spring-security


    【解决方案1】:

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

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

    您在web.ignoring() 方法中放入的任何蚂蚁匹配器都应该被spring security 忽略。

    默认情况下,静态内容应放置在src/main/resources(来自spring boot - static content)下的以下目录之一:

    /META-INF/resources/
    /resources/
    /static/
    /public/
    

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

    例如,如果您的静态内容位于 src/main/resources/static/front 中,则蚂蚁匹配器 /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.ignoring().antMatchers("/*", "/front/**", "index.html");

    /* 不会允许所有,/** 会这样做。确保将 API 放在安全端点上,例如 /api 或类似的东西,并将静态内容放在被忽略的路径上。

    【讨论】:

    • 直接在static还是在文件夹前面,src/main/resources/static/front?
    • 我都试过了,现在我有它在 src/main/resources/static/front
    • 您能否尝试访问特定资源以查看问题是出在 ant matcher 上还是暴露了您的 index.html?如果您在公开 index.html 时遇到问题(假设它位于最前面的文件夹中),我可以添加相关代码以在我的答案中公开它。
    • 所以我终于可以使用以下 atMatchers 使其工作:web.ignoring().antMatchers("/", "/front/**", "index.html");如果我使用不带星号的“/”,则会提供 html,并且不会忽略其他路由。我认为该主题已关闭:) 感谢您的时间和精力,只是一件小事太麻烦了。 xD
    【解决方案2】:

    问题可能是 angular-cli 将所有资源放在应用程序的根目录下。 (虽然我不确定你使用的是 angular-cli)

    但让我们接受这个概念。

    angular-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 的建议忽略路径。

    【讨论】:

    • 我没有使用 Angular cli
    猜你喜欢
    • 2015-09-12
    • 2015-12-09
    • 2018-02-09
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 2022-10-06
    • 2017-03-08
    • 1970-01-01
    相关资源
    最近更新 更多