当前位置: 首页 > 知识库问答 >
问题:

如何设置Spring Security以允许来自特定应用程序的REST调用?

澹台华采
2023-03-14

Spring Boot应用程序使用Spring Security来保护其API的元素免受未经授权的用户的侵害。但是该应用程序具有公共url模式,需要可从未经身份验证的用户调用,只要这些用户来自某些应用程序。需要对下面的代码进行哪些具体更改,以便可以从特定调用位置的未经身份验证的用户成功调用/thing-test-service终端?

例如,我知道终端命令是从运行Spring Boot应用程序的同一个本地主机上运行的。我还将知道前端AngularJS/Node.js调用应用程序运行在特定端口上,如< code>port 9000。

以下是当我从运行Spring Boot应用程序的devbox中的CentOS终端输入以下POST测试时会发生什么:

[user@localhost controllers]$ curl -i -X POST -H "Content-Type:application/json" -d '{  "wleadid" : "1" }' http://localhost:8001/some-test-service
HTTP/1.1 403 Forbidden
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=530A75F962CCFB95EEDF43051BC71573; Path=/; HttpOnly
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 06 Apr 2016 09:11:09 GMT
{"timestamp":1459933869769,"status":403,"error":"Forbidden","message":"Expected CSRF token not found. Has your session expired?","path":"/some-test-service"}  
[user@localhost controllers]$ 

这是完整的<code>UiApplication中的Spring Security配置。java这是Spring Boot应用程序的主要类:

@SpringBootApplication
@Controller
@EnableJpaRepositories(basePackages = "demo", considerNestedRepositories = true)
public class UiApplication extends WebMvcConfigurerAdapter {

    @Autowired
    private Users users;

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

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

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver slr = new SessionLocaleResolver();
        slr.setDefaultLocale(Locale.US);
        return slr;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        lci.setParamName("lang");
        return lci;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }

    @Order(Ordered.HIGHEST_PRECEDENCE)
    @Configuration
    protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {

        @Autowired
        private Users users;

        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(users);
        }
    }

    @SuppressWarnings("deprecation")
    @Configuration
    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    @EnableWebMvcSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .formLogin()
                    .successHandler(new MyAuthenticationSuccessHandler())
                    .and()
                .httpBasic().and()
                .authorizeRequests()
                    .antMatchers("/some-test-service").permitAll()
                    .antMatchers("/", "/url1", "/url2", "/url3*", "/url4*", "/url5*").permitAll()
                    .anyRequest().authenticated()
                    .and()
                .csrf()
                    .csrfTokenRepository(csrfTokenRepository())
                    .and()
                .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
        }

        private Filter csrfHeaderFilter() {
            return new OncePerRequestFilter() {
                @Override
                protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                        throws ServletException, IOException {
                    System.out.println("----- INSIDE new OncePerRequestFilter().doFilterInternal(...) ");
                    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
                    if (csrf != null) {
                        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                        String token = csrf.getToken();
                        if (cookie == null || token != null && !token.equals(cookie.getValue())) {
                            cookie = new Cookie("XSRF-TOKEN", token);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                    filterChain.doFilter(request, response);
                    System.out.println("csrf.getToken() is: "+csrf.getToken());
                }
            };
        }

        private CsrfTokenRepository csrfTokenRepository() {
            HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
            repository.setHeaderName("X-XSRF-TOKEN");
            System.out.println("repository.toString() is: "+repository.toString());
            return repository;
        }

    }

    @Repository
    interface UserRepository extends CrudRepository<User, Long> {
        User findByName(String name);
    }

}

共有1个答案

裴学
2023-03-14

我也有类似的问题。但是我的配置没有csrf也能工作。具有公共访问权限的链接:“localhost:8080/somesturl/”,但其他引用需要授权。

我的充血:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
MongoDBAuthenticationProviderService authenticationProvider;

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

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();

    http
            .anonymous()
            .and()
            .authorizeRequests().antMatchers("/someTestUrl").permitAll()
            .and()
            .formLogin().permitAll().loginPage("/login").usernameParameter("username").passwordParameter("password")
            .and()
            .logout().permitAll()
            .and()
            .authorizeRequests().anyRequest().fullyAuthenticated()
            .and()
            .httpBasic().disable()
            .exceptionHandling().accessDeniedPage("/403")
            .and()
            .headers()
            .contentTypeOptions()
            .disable();
}
}

和资源配置:

@EnableResourceServer
@Configuration
public class ResourseConfig extends ResourceServerConfigurerAdapter {

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

    http
            .anonymous()   
            .and()
            .authorizeRequests().antMatchers("/someTestUrl/**").permitAll()
            .and()
            .formLogin().permitAll().loginPage("/login").usernameParameter("username").passwordParameter("password")
            .and()
            .logout().permitAll()
            .and()
            .authorizeRequests().anyRequest().fullyAuthenticated() 
            .and()
            .httpBasic().disable()
            .exceptionHandling().accessDeniedPage("/403")
            .and()
            .headers().contentTypeOptions()
            .disable();
}
}

也许它会帮助你。

 类似资料:
  • 我最近在Android Studio中为我的Android项目添加了一个自定义字体(遵循这些说明)。这不是一个显示文本的常规字体,而是一个包含大量图标的自定义字体,在我的应用程序中使用。 这个很管用。然而,现在一些用户报告了这个问题,他们的设备上只有一些图标可以使用,而许多其他图标显示为字符。所有用户的共同点是,他们在设备设置中配置了一个自定义的FONT/主题,这似乎覆盖了应用程序的样式。因此,应

  • 我正在尝试创建一个脚本来使用powershell在Azure Web应用程序插槽中设置/更新应用程序设置。使用使用Azure Power Shell将应用程序设置添加到现有Azure Web应用程序中的示例,它可以工作。 我的问题是我希望“槽位设置”为真。在我发现的所有例子中以及在resources.azure.com,设置总是名称/值对,没有属性将值指定为“插槽设置”。 这甚至可能是脚本吗? 谢

  • 我想启用浮动通知使用Android代码。通常用户不知道有关的设置.所以我需要启用这作为默认。

  • 我有几个Spring Boot应用程序JAR,它们是通过运行启动的: 我想要停止一个特定的Spring Boot应用程序(例如),但当我列出所有正在运行的进程时,我会有一个列表,如下所示: 我如何停止特定的Spring Boot过程?

  • 问题内容: 是否有可能通过cron在终端或任何其他GUI中显示结果。 例如,我只编写了一个脚本来显示每分钟在终端的时间。但它什么也没做。因此cron可以在GUI中显示结果。 问题答案: 您可以通过将变量设置为来执行此操作。例如: 此crontab行将每分钟打开gui软件gedit。

  • 我正在创建一个应用程序,它在开发中使用webpack-dev-server和react-router。 似乎webpack-dev-server是基于这样一个假设构建的,即在一个地方(即“/”)有一个公共入口点,而react-router允许无限数量的入口点。