Files
halo/docs/extension-points/authentication.md
John Niang 9cdd8a5301 Add before and after security web filters (#6297)
#### What type of PR is this?

/kind feature
/kind api-change
/area core
/area plugin

#### What this PR does / why we need it:

This PR adds `BeforeSecurityWebFilter` and `AfterSecurityWebFilter` extension points. See https://github.com/halo-sigs/plugin-page-cache/issues/4#issuecomment-2216677891 for more.

Now, we can do something before and after authenticating.

#### Does this PR introduce a user-facing change?

```release-note
添加认证授权的前置和后置处理器扩展点
```
2024-07-09 14:05:24 +00:00

3.5 KiB
Raw Permalink Blame History

Halo 认证扩展点

此前Halo 提供了 AdditionalWebFilter 作为扩展点供插件扩展认证相关的功能。但是近期我们明确了 AdditionalWebFilter 的使用用途,故不再作为认证的扩展点。

目前Halo 提供了三种认证扩展点:表单登录认证、普通认证和匿名认证。

表单登录FormLogin

示例如下:

import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import run.halo.app.security.FormLoginSecurityWebFilter;

@Component
public class MyFormLoginSecurityWebFilter implements FormLoginSecurityWebFilter {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    // Do your logic here
    return chain.filter(exchange);
  }
}

普通认证Authentication

示例如下:

import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import run.halo.app.security.AuthenticationSecurityWebFilter;

@Component
public class MyAuthenticationSecurityWebFilter implements AuthenticationSecurityWebFilter {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    // Do your logic here
    return chain.filter(exchange);
  }
}

匿名认证Anonymous Authentication

示例如下:

import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import run.halo.app.security.AnonymousAuthenticationSecurityWebFilter;

@Component
public class MyAnonymousAuthenticationSecurityWebFilter
        implements AnonymousAuthenticationSecurityWebFilter {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    // Do your logic here
    return chain.filter(exchange);
  }
}

前置过滤器BeforeSecurityWebFilter

主要用于在进行认证之前的一些处理。需要注意的是,当前过滤器中无法直接通过 ReactiveSecurityContextHolder 获取 SecurityContext。示例如下

public class MyBeforeSecurityWebFilter implements BeforeSecurityWebFilter {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    // Do your logic here
    return chain.filter(exchange);
  }
}

后置过滤器AfterSecurityWebFilter

主要用于进行认证之后的一些处理。在当前过滤器中,可以通过 ReactiveSecurityContextHolder 获取 SecurityContext。示例如下

public class MyAfterSecurityWebFilter implements AfterSecurityWebFilter {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    return ReactiveSecurityContextHolder.getContext()
            .switchIfEmpty(Mono.defer(() -> {
              // do something...
              return chain.filter(exchange).then(Mono.empty());
            }))
            .flatMap(securityContext -> {
              // do something...
              return chain.filter(exchange);
            });
  }
}

我们在实现扩展点的时候需要注意:如果当前请求不满足认证条件,请一定要调用 chain.filter(exchange),给其他 filter 留下机会。

后续会根据需求实现其他认证相关的扩展点。