Skip to content

@Security Decorator

Thiago Bustamante edited this page Jun 10, 2019 · 5 revisions

@Security Decorator

The @Security decorator allow us to define an authorisation control for a given endpoint.

Some examples:

@Path('hello')
class HelloService {
    @GET
    @Path('admin')
    @Security("ROLE_ADMIN")
    public adminOnlyMethod() {
      // Only user with ROLE_ADMIN role can access
    }

    @GET
    public publicMethod() {}
}
@Path('hello')
@Security("ROLE_USER")
class TestService {
}
@Security(["ROLE_ADMIN", "ROLE_USER"])
class AuthService {
    // Only user with ROLE_ADMIN or ROLE_USER role can access
}

To inform typescript-rest server how to authenticate and validate user roles, you need to register an authentication service, using Server.registerAuthenticator method.

We provide a passport authentication service included in the library distribution:

Examples:

Server.registerAuthenticator(new PassportAuthenticator(strategy));

or

const JWT_SECRET: string = 'some-jwt-secret';

const jwtConfig: StrategyOptions = {
    jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
    secretOrKey: Buffer.from(JWT_SECRET, 'base64'),
};
const strategy = new Strategy(jwtConfig, (payload: JwtUserPayload, done: (a: null, b: JwtUser) => void) => {
    const user: JwtUser = {
        roles: payload.auth.split(','),
        username: payload.sub
    };
    done(null, user);
});

Server.registerAuthenticator(new PassportAuthenticator(strategy, {
    deserializeUser: (user: string) => JSON.parse(user),
    serializeUser: (user: JwtUser) => {
        return JSON.stringify(user);
    }
}));

or

const strategy = new Strategy(jwtConfig, (payload: JwtUserPayload, done: (a: null, b: JwtUser) => void) => {
    const user: JwtUser = {
        roles: payload.auth.split(','),
        username: payload.sub
    };
    done(null, user);
});

Server.registerAuthenticator(new PassportAuthenticator(strategy, {
  authOptions: {
    session: false,
    failWithError: false
  },
  rolesKey: 'security.roles' // change the name of the property used to access the user role(s)
}));

If you don't want to use passport, it is possible to use other authentication service. Just implement the ServiceAuthenticator interface and register it with Server.registerAuthenticator method.

Multiple Authenticators

Starting from version 2.2.0, it is possible to use multiple authenticators.

It is possible to inform an optional name to an authenticator when registering it:

Server.registerAuthenticator(new PassportAuthenticator(strategy), 'MyAuth');

And then, inform in the Security decorator the name of the authenticator to use:

@Path('hello')
@Security("ROLE_USER", "MyAuth")
class TestService {
}

When no name is provider, the 'default' authenticator is used.

Server.registerAuthenticator(new PassportAuthenticator(strategy)); // 'default' authenticator
Server.registerAuthenticator(new PassportAuthenticator(strategy), 'MyAuth');
@Path('hello')
class HelloService {
    @GET
    @Path('admin')
    @Security("ROLE_ADMIN")
    public useDefaultAuthenticator() {
      // Only user with ROLE_ADMIN role can access
    }

    @GET
    @Security("ROLE_READ", "MyAuth")
    public useMyAuth() {}
}