【问题标题】:How to add security to spring based rest api's and static content如何为基于 spring 的 rest api 和静态内容添加安全性
【发布时间】:2016-05-07 15:01:37
【问题描述】:

我有一个 web 应用程序 + 一组用 spring 创建的 rest API。它本质上是一些向其余服务器发送 ajax 请求的 html 页面。结构有点像这样:

myWebapp -> src/main/webapp/public(公共页面)
myWebapp -> src/main/webapp/resources(非公开页面,登录后可用)

我需要保护一些静态内容(以上非公开)和其余 API(最好使用 LDAP,但这并不重要)。如何配置过滤器和/或弹簧安全拦截,以便:

  1. 相同的凭据适用于静态内容和休息调用。
  2. 用户可以通过登录页面登录,为了进一步的休息调用使用一些令牌或从服务器返回的东西。

我已经检查了其余 API 的 spring 安全方案,还发现了一些关于保护静态内容的资源,但无法弄清楚如何将它们组合在一起。

【问题讨论】:

  • 你的 RESTful 服务的 URL 路径是什么?
  • @AnanthaSharma Rest 资源在 /rest/api/ 提供。而静态页面,css,js等通常是/public/js/blah.js等(公共)和/resources/user/myhome.html(非公共)

标签: java spring rest spring-mvc spring-security


【解决方案1】:

我猜你想拥有两组资源。其中一个对公众开放,可在/public context 中获取,另一个受保护,可在/protected 获取。

首先,您应该在您的Web Configuration 中创建一些Resource Handlers

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    // other stuffs

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/public/**").addResourceLocations("classpath:/public/");
        registry.addResourceHandler("/protected/**").addResourceLocations("classpath:/resources/");
    }
}

这样/public 目录中的所有静态内容将在/public/** 端点提供,/protected/** 端点将在/resources 目录中提供文件。

那么你应该配置 Spring Security 以保护 /protected/** 端点:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // other stuffs

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("/public/**").permitAll()
                    .antMatchers("/protected/**").authenticated()
                    .anyRequest().authenticated();
    }
}

更新对于 REST 端点,您可以使用相同的匹配器或使用Method Level Security 进行更精细的粒度控制。为了启用方法级别的安全性,请将@EnableGlobalMethodSecurity(prePostEnabled = true) 添加到您的SecurityConfig。然后您可以在处理方法上使用PrePost 注释,如下所示:

@RestController
@RequestMapping("/greet")
public class GreetingService {
    // it's a public rest endpoint
    @PreAuthorize("permitAll()")
    @RequestMapping("/public")
    public void doGreetToPublicUsers() {...}

    // it's a protected rest endpoint
    @PreAuthorize("isAuthenticated()")
    @RequestMapping("/protected")
    public void doGreetToProtectedUsers() {...}

    // it's a role protected rest endpoint
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping("/admin")
    public void justForAdmin() {...}
}

【讨论】:

  • 感谢您的意见。这告诉我如何有选择地对静态资源进行身份验证。但是你能不能告诉我如何为休息服务提供相同的身份验证工作。基本上就像用户通过表单或其他东西登录一次,然后通过 ajax 进入的所有其余调用都使用相同的身份验证。
  • 非常感谢。我最终使用了上面基于 xml 的版本和 jdbc 身份验证。
猜你喜欢
  • 2018-03-12
  • 2012-12-29
  • 1970-01-01
  • 2017-03-13
  • 1970-01-01
  • 2013-01-20
  • 2017-12-05
  • 2015-09-01
  • 2014-07-01
相关资源
最近更新 更多