Malagu 框架提供给了一个默认策略:EL 表达式策略,当 EL 表达式计算结果为 true,表示允许,否则表示拒绝。用户可以在方法上通过相关的权限装饰器配置策略,也可以通过组件属性配置策略。

定义

  1. export interface Policy {
  2. type: PolicyType
  3. authorizeType: AuthorizeType;
  4. }
  5. export interface ElPolicy extends Policy {
  6. context: any;
  7. el: string;
  8. }

权限装饰器

为了用户方便地配置 EL 表达式策略,框架提供了一些列权限装饰器 @Authorize@PreAuthorize@PostAuthorize@Anonymous@Authenticated

其中,@PreAuthorize@PostAuthorize@Anonymous@Authenticated是对 @Authorize 的扩展。

@Authorize

装饰器的配置属性:

  1. export interface AuthorizeOption {
  2. el: string;
  3. authorizeType: AuthorizeType; // 授权类型包括前置授权和后置授权
  4. }

@PreAuthorize

扩展 @Authorize 装饰器,等价于将 @AuthorizeauthorizeType 属性固定为前置授权。具体实现如下:

  1. export const PreAuthorize = function (el: string) {
  2. return Authorize({ el, authorizeType: AuthorizeType.Pre });
  3. };

@PostAuthorize

扩展 @Authorize 装饰器,等价于将 @AuthorizeauthorizeType 属性固定为后置授权。具体实现如下:

  1. export const PostAuthorize = function (el: string) {
  2. return Authorize({ el, authorizeType: AuthorizeType.Post });
  3. };

@Anonymous

扩展 @Authorize 装饰器,等价于将 @Authorizeel 属性固定为 trueauthorizeType 属性固定为前置授权 。具体实现如下:

  1. export const Anonymous = function (): any {
  2. return Authorize({ el: 'true', authorizeType: AuthorizeType.Pre });
  3. };

@Authenticated

扩展 @Authorize 装饰器,等价于将 @Authorizeel 属性固定为 authenticatedauthorizeType 属性固定为前置授权 。具体实现如下:

  1. export const Authenticated = function () {
  2. return Authorize({ el: 'authenticated', authorizeType: AuthorizeType.Pre });
  3. };

其中,authenticated 是内置的 EL 上下文变量,当为 true 时,表示当前登录用户认证通过;当为 false 时,表认证失败。

EL 表达式上下文

我们往往需要一些变量或者方法参与到 EL 表达式的计算中,框架通过 EL 表达式上下文来提供这些变量或者方法,默认提供的 EL 表达式上下文如下:

  1. export interface ElContext {
  2. authorizeType: AuthorizeType
  3. method: string;
  4. args: any[];
  5. target: any;
  6. returnValue?: any;
  7. policies: Policy[];
  8. credentials: any;
  9. details?: any;
  10. principal: any;
  11. authenticated: boolean;
  12. }

扩展 EL 表达式上下文

框架提供了一个扩展接口 SecurityExpressionContextHandler 用于扩展 EL 表达式上下文。

定义

  1. export interface SecurityExpressionContextHandler {
  2. handle(context: any): Promise<void>
  3. }

实现

  1. @Component(SecurityExpressionContextHandler)
  2. export class SecurityExpressionContextHandlerImpl implements SecurityExpressionContextHandler {
  3. handle(context: any): Promise<void> {
  4. context.foo = 'bar';
  5. context.hasRole = () => { ... };
  6. }
  7. }