Repository navigation
Securing your plugin
"I love writing authentication and authorization code." ~ No Developer Ever.
Creating authorization/permission checking code is really boring, to make it easier, this starter implements the @Authorize
annotation, which allows you to define rules to prevent some method to be ran by some players. This annotation can be placed in a method or in a class (applying the rule for all methods inside it).
The annotation expects a expression in Spring Expression Language (SpEL)
which will be evaluated over the player in the current context. If the expression evaluates to false or there's
no player in the context, the method will automatically throw a PermissionDeniedException and PlayerNotFoundException, respectively.
Example:
@Authorize("hasPermission('myplugin.dosomething') or getHealth() > 10")
public void doSomething() {
}With the @Authorize annotation you can also create rules based in the method arguments, just using the # identifier followed by arg0, arg1, etc.
Example:
@Authorize("hasPermission('myplugin.buy.' + #arg0)")
public void buy(String itemName) {
}Acessing the session
Another functionality provided by this annotation is to create rules based in the player session, acessing it's properties and verifying it's values, to do that, you should use the #session variable and treat it like a map.
Example:
@Authorize("#session['myplugin.loggedin'] == true")
public void changePassword(String newPassword) {
}If you have repeated rules across your plugin, you can centralize the expression in a meta-annotation, this allows you to easily modify and make it less verbose. Example:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Authorize("hasPermission('admin')")
public @interface AdminOnly {
@AliasFor(annotation = Authorize.class, attribute = "message")
String message() default "";
}After that, every method annotated with @AdminOnly will also run the expression as if annotated directly with @Authorize and will also support a custom message if necessary.
The @Authorize annotation accepts a params array which will be available in the expression context, using it you can extend even more by adding custom parameters, let's look into an already available example:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Authorize("#params.?[!#root.hasPermission(#this)].length == 0")
public @interface HasPermission {
@AliasFor(annotation = Authorize.class, attribute = "params")
String[] value();
@AliasFor(annotation = Authorize.class, attribute = "message")
String message() default "";
}The @HasPermission annotation accepts an array of permissions that will be checked over the current sender in the context, if the sender don't have any of those, the method call will not be allowed.
- Getting started
- Commands
- Utilities
- Context
- RxJava support
- Known issues
- Testing