【问题标题】:Modify Spring Security Config at Runtime在运行时修改 Spring Security Config
【发布时间】:2016-12-29 14:13:47
【问题描述】:

我正在为一个简单的代理应用程序使用最新的 Spring Boot + Spring Boot Starter Security。目标是使用单一路由/方法启动应用程序:

@RequestMapping(value = "/api/register",
    method = RequestMethod.POST,
    produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public ResponseEntity<?> register(Registration registration) {

安全配置为:

@Override
protected void configure(HttpSecurity http) throws Exception {
    this.http = http
        .authorizeRequests()
        .antMatchers("/api/register").hasAuthority(AuthorityConstants.ADMIN)
    .and();
}

public HttpSecurity getHttpSecurity() {
    return http;
}

应用程序的目标是接受以下形式的注册请求:

{
    "route":"/api/foo/bar",
    "proxy_location": "http://back-end-server/path/to/resource",
    "role": "some-authority"
}

然后应用程序将使用预定义的方法添加一个/api/foo/bar 路由,该方法将代理(转发)未来的请求到后端服务。

我知道这有点傻,真正的用例涉及 websockets 和主题的动态创建。

我面临的问题是,在 SecurityConfigurer 完成后,我似乎无法更新安全配置。

在上面的代码示例中,我缓存了给我的SecurityConfigurerHttpSecurity 对象,然后尝试再次使用该对象来配置新路由:

@Inject
private SecurityConfigurer security;

@RequestMapping(value = "/api/register",
    method = RequestMethod.POST,
    produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public ResponseEntity<?> allowGetAccounts(Registration registration) {
    try {
        security.getHttpSecurity()
            .authorizeRequests()
            .antMatchers(registration.getRoute()).hasAuthority(registration.getRole());

        ...

    } catch (Exception e) {
        log.error("Updating security failed!", e);
    }

    return new ResponseEntity<>(null, HttpStatus.OK);
}

有没有办法在运行时动态更新安全配置?

另外,如果有人对动态创建 websocket 主题有任何注释,也将不胜感激!

【问题讨论】:

  • 最终目标是在用户的权限列表中添加一个角色,对吗?
  • 最终目标是为安全配置添加一个路由,基本上为具有定义角色的用户打开另一条路径。
  • 您是否真的遇到了异常,或者您根本没有看到应用的安全性有任何变化?
  • 没有例外,我没有看到应用的更改
  • 您可能更想看看通过 HttpSecurity.addFilter 添加它,然后看看 performBuild... 不知道还能提供什么。这有点不正统。祝你好运,我期待看到你是否找到解决方案:)

标签: spring spring-security spring-websocket


【解决方案1】:

您有多种选择:

  • 使用 antchMatcher("/some/path").access("@someBean.hasAccess(authentication)") 。这允许您基本上在应用程序上下文中使用任何 bean 来应用您需要的验证。

  • 在你的RequestMapping 注释方法上使用@PreAuthorize("@someBean.hasAccess(authentication)")。与以前相同的想法,但作为端点本身的拦截器。

  • 实现您自己的SecurityExpressionHandler 并将其插入http.authorizeRequests().expressionHandler(...)

  • 实现您自己的安全过滤器来处理您需要的任何内容。

【讨论】:

    猜你喜欢
    • 2016-10-24
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 2023-03-14
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    相关资源
    最近更新 更多