Docs

Documentation versions (currently viewingVaadin 25 (prerelease))

Protect Services

In a Vaadin application using Hilla views, securing @BrowserCallable services is crucial to prevent unauthorized access. In this guide, you’ll learn how to control access to specific browser-callable services.

Caution
Browser-callable services don’t use Spring method security
Vaadin handles the protection of browser-callable services outside Spring Security. This means that if you inject a browser-callable service into another Java service or Flow view, it will not be protected by default.

Securing the Services

Vaadin protects browser-callable services in the same way as it protects Flow views — with annotations.

Important
All browser-callable services are inaccessible by default and require explicit annotations to grant access.

You can annotate both service classes and individual service methods. An annotation placed on the class applies to all public methods of the class. An annotation placed on a method overrides any annotation on the class.

The following annotations are supported:

  • @AnonymousAllowed allows access to unauthenticated users.

  • @PermitAll allows any authenticated user to call the service or method.

  • @RolesAllowed allows users having the roles specified in the annotation value to call the service or method.

  • @DenyAll prevents everyone from calling the service or method.

Note
The @AnonymousAllowed annotation is a Vaadin-specific annotation; the others are Jakarta annotations (JSR-250).

The following example uses @AnonymousAllowed to allow all users — both authenticated and unauthenticated — to call the service:

Source code
Java
@BrowserCallable
@AnonymousAllowed
public class PublicService {

    public void doSomething() {
        //...
    }
}

The following example combines @PermitAll and @RolesAllowed to allow all authenticated users to call the service, except for one method that can be called only by administrators:

Source code
Java
@BrowserCallable
@PermitAll
public class ProtectedService {

    public void callableByAllUsers() { 1
    }

    @RolesAllowed(Roles.ADMIN) 2
    public void callableByAdminsOnly() {
    }
}
  1. Inherits its access permissions from the @PermitAll annotation on the class.

  2. Overrides the @PermitAll annotation on the class, limiting the access.

You can also do the other way around. This example allows only administrators to call the service, except for one method that can be called by all authenticated users:

Source code
Java
@BrowserCallable
@RolesAllowed(Roles.ADMIN)
public class ProtectedService {

    @PermitAll
    public void callableByAllUsers() {
    }

    public void callableByAdminsOnly() {
    }
}

Using Spring Method Security for Browser-Callable Services

Flow services are protected by Spring method security. If you have a protected Flow service that you want to make available for Hilla views, you can do that with some tweaking.

Note
The following assumes you have already set up Spring method security. For details, see the Protect Flow Services guide.

By default, requests coming in from the browser are denied by Vaadin before the service is even called. This applies even when the service is proxied and protected by Spring Security.

To bypass Vaadin’s security check and rely on Spring Security instead, you have to add @AnonymousAllowed to the service, like this:

Source code
Java
@BrowserCallable
@AnonymousAllowed 1
@PreAuthorize("isAuthenticated()") 2
public class ProtectedService {

    public MyData callableByAllUsers() {
    }

    @PreAuthorize("hasRole('" + Roles.ADMIN + "')")
    public void callableByAdminsOnly(MyData data) {
    }
}
  1. Bypass Vaadin’s security check.

  2. Enable Spring method security instead.

Note
Better support for Spring Security is planned for a future version of Vaadin Hilla. See this ticket for more information.
Warning
Don’t configure Spring Security to use JSR-250 annotations
Spring method security has support for the JSR-250 annotations that Vaadin uses to protect browser-callable services. However, Vaadin treats @PermitAll differently than Spring Security. Whereas Vaadin allows access to authenticated users only, Spring Security allows access to all users.