⛔Authorization

When building a service or any other application it is crucial to make it secure, besides token validation, there might be the need to limit access to certain fields, types or even endpoints. We can help you do this too.

To implement restriction rules we use graphql-shield. If you answered with true to the "Implement authorization" question prompted at the beginning, there will be an example of permission checking included in this sample. (See src/middleware/permissions)

In addition, we will include two constant files: src/contants/identityUserRoles.js containing the default roles that comes from the Identity server and src/contants/permissions.js that contains your defined application roles.

To define a new role, assuming it was already added in the database, you should export it from src/constants/permissions file.

By default the permission check is made by checking the UserRight table (This function can me replace and changes as desired):

const checkForPermission = async (permissions, { dbInstance, externalUser }) => {
    try {
        const { id } = await dbInstance.select("Id").from("User").where("ExternalId", externalUser.id).first()
        const rights = await dbInstance.select("Name as Right").from("UserRight")
            .join('[Right]', { 'Right.Id': 'RightId' })
            .where("UserRight.UserId", id)

        return intersection(permissions, rights.map(x => x.right)).length > 0
    }
    catch (error) {
        throw new ForbiddenError(`Authorization check failed! The following error was encountered: ${error}`)
    }
}

To implement restrictions you first have to define your rules and them apply them in the "shield" defined on top of your GraphQL schema. e.g.:

const isAuthenticated = rule({ cache: 'contextual' })(
    (_parent, _args, context) => !!context.externalUser.id
)

const isAdmin = rule({ cache: 'contextual' })(
    (_parent, _args, { externalUser }, _info) => includes(admin, externalUser.role) || includes(globalAdmin, externalUser.role)
)

shield({
    User: {
        rights: isAuthenticated
    },
    Query: {
        userList: isAuthenticated
    },
    Mutation: {
        updateUser: and(isAuthenticated, isAdmin)
    }
})

Last updated