I have a setup such that end-points annotated with @RolesAllowed
require both authentication and authorization. However, those end-points without any particular annotation don't even demand authentication. How do I configure the server such that all URLs are protected by default, requiring at least a logged-in user?

- 1,106
- 3
- 17
- 27
3 Answers
UPDATE No easy solution so far. Still looking for easier approach.
You can do something like this but it requires modifying server.xml
and all jax-rs resource classes:
In the server.xml
provide role binding (similar could be done via ibm-web-bnd.xml
file):
<application-bnd>
<!-- role from JWT claim. The access-id must have your claim issuer. In my case it was mp.jwt.verify.issuer=http://openliberty.io -->
<security-role name="admin">
<group access-id="group:http://openliberty.io/admin" id="group1" name="admin" />
</security-role>
<!-- role for authenticated users -->
<security-role name="auth-user">
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
</application-bnd>
And in your resource class you need to define role for all authenticated. I defined it on top of the class like this, as this protects all methods without @RolesAllowed
defined explicitly:
@RolesAllowed({ "auth-user" })
public class SystemResource {

- 17,601
- 4
- 46
- 93
-
Thanks, @Gas. Could you explain a little what each bit does? I'm not sure whether it applies to my case, where I already have a separate system that defines the roles and all other login details (forms and whatnot). Through that system, a JWT token is acquired and sent to the OpenLiberty server, which understands it thanks to MicroProfile, and this is all OpenLiberty should concern itself with. I don't have a `web.xml` file either (I'm not familiar with it). – DanielM Nov 23 '22 at 13:59
-
@DanielM if you are just interested in protecting microservice with the JWT token then check out this tutorial [Securing microservices with JSON Web Tokens](https://openliberty.io/guides/microprofile-jwt.html#getting-started) and let me know if it is clear for you. – Gas Nov 23 '22 at 14:54
-
In that case you wouldn't need web.xml as all the data is taken from the JWT claim. And accessing service should be restricted without JWT, but make sure you have all required features like `appSecurity` and `mpJwt` and others. – Gas Nov 23 '22 at 14:58
-
I pretty much have that setup already, which is how I managed to make `@RolesAllowed` work. However, all end-points without `@RolesAllowed` (of which there are none in the guide you link) don't require authentication (they should require authentication, just not authorization). – DanielM Nov 23 '22 at 15:24
-
If you dont have `@RolesAllowed` then everyone is allowed, so there is no point of requiring authentication. Try to use `@RolesAllowed("**")` with 2* but I didnt test that. If that doesnt work, you could try web.xml example (I'd explain more how it works then) – Gas Nov 23 '22 at 16:02
-
Well, that's not correct, because not everybody can acquire a token, so there is a distinction to make between people that can (i.e. that have an account on our system, which they cannot create by themselves) and people that can't. Besides, it is a security best practice to forbid access to everyone except for those explicitly permitted. It is error prone to have to visit each and every controller to protect it. The two asterisks didn't do the trick anyways. – DanielM Nov 23 '22 at 16:36
-
1@DanielM I'll be making a few tests. I'll update when I'm done. – Gas Nov 24 '22 at 14:46
-
Sorry to bother @Gas, but any luck? – DanielM Dec 21 '22 at 16:00
-
Hi @DanielM, sorry for late response :-) . No good news unfortunately. 1st `@RolesAllowed("**")` will not work as it is not explicitly specified in JAX-RS spec, so it creates `**` role and since that role is not matched to anything it doesnt work. – Gas Dec 22 '22 at 14:37
-
2nd - The `security-constraint` somehow conflicts with the mpJwt, so it's not working as I expected. This was raised to the dev team, but I dont if/when it will be handled. – Gas Dec 22 '22 at 15:06
-
@DanielM I added working solution, but it's not very easy unfortunately.... – Gas Dec 22 '22 at 16:13
-
How about `@WebFilter`? Could it be used to ensure only authenticated users make it to controller methods, or does it have any limitations? I wonder in particular if the observability endpoints mentioned by Robert (`/health`, etc.) would be covered like this. – DanielM Jan 05 '23 at 13:15
Note: The following works when using Liberty's proprietary openIdConnectClient
feature, but not mpJWT
. For mpJWT, the security constraints conflict with mpJWT. There have been issues opened for it against OpenLiberty, but it's not likely to be resolved until mpJWT moves into Jakarta Security.
The easiest (but still not easy) way of requiring authentication for all endpoints is to set up security constraints in the web.xml
file:
<security-constraint>
<web-resource-collection>
<web-resource-name>ProtectAll</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<!-- repeat for PUT, POST, PATCH, etc -->
</web-resource-collection>
<auth-constraint>
<role-name>all-authenticated</role-name>
</auth-constraint>
</security-constraint>
and then as @Gas mentions, you would need to create a mapping from Liberty's ALL_AUTHENTICATED_USERS
special subject to the all-authenticated
role name:
<application ..[snip]..>
<application-bnd>
<security-role name="all-authenticated">
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
</application-bnd>
</application>
The combination of these two bits of configuration will tell Liberty to protect all URLs hosted in this web module.
One thing to be mindful of is that this will protect observability endpoints like /health
, /metrics
, etc. If your monitoring systems require unauthenticated access, you'd want to add an additional security constraint that assigns those resources to a role that maps to Liberty's EVERYONE
special subject.

- 685
- 5
- 16
-
Robert, this didnt work for me if the authentication was done via JWT. This was my initial idea also.... If you look at the history of my answer :-) – Gas Dec 31 '22 at 15:21
-
I just double-checked and found that when we used this solution, we were using Liberty's proprietary OIDC client feature instead of mpJWT. – Robert Dean Dec 31 '22 at 15:39
In the end I opted for the following filter, which I thought was simpler and more explicit than the alternatives proposed so far:
import jakarta.inject.Inject;
import jakarta.ws.rs.NotAuthorizedException;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.ext.Provider;
import org.eclipse.microprofile.jwt.JsonWebToken;
@Provider
public class AuthFilter implements ContainerRequestFilter {
@Inject
private JsonWebToken jwt;
@Override
public void filter(ContainerRequestContext req) {
var isAuthenticated = jwt != null && jwt.getName() != null && jwt.getGroups() != null;
if (!isAuthenticated) {
throw new NotAuthorizedException("Authentication required.");
}
}
}

- 1,106
- 3
- 17
- 27