[urls]
/api/secured/** = authcBasic
|
Handy Hint
|
Shiro v1 version notice
As of February 28, 2024, Shiro v1 was superseded by v2.
|
Apache Shiro’s JAX-RS support is built on top of the more general Servlet support, and requires Shiro’s Servlet Filter to be setup. The Servlet Filter can be setup by using Shiro’s Servlet fragment, web.xml configuration, or programmatically.
Include the shiro-servlet-plugin and shiro-jaxrs dependencies in you application classpath (we recommend using a tool such as Apache Maven or Gradle to manage this).
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-servlet-plugin</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-jaxrs</artifactId>
<version>2.0.5</version>
</dependency>
compile 'org.apache.shiro:shiro-servlet-plugin:2.0.5'
compile 'org.apache.shiro:shiro-jaxrs:2.0.5'
libraryDependencies += "org.apache.shiro" % "shiro-servlet-plugin" % "2.0.5"
libraryDependencies += "org.apache.shiro" % "shiro-jaxrs" % "2.0.5"
<dependency org="org.apache.shiro" name="shiro-servlet-plugin" rev="2.0.5"/>
<dependency org="org.apache.shiro" name="shiro-jaxrs" rev="2.0.5"/>
[org.apache.shiro/shiro-servlet-plugin "2.0.5"]
[org.apache.shiro/shiro-jaxrs "2.0.5"]
'org.apache.shiro:shiro-servlet-plugin:jar:2.0.5'
'org.apache.shiro:shiro-jaxrs:jar:2.0.5'
| This is not required if using Jakarta EE module |
For information on other ways to set up the Apache Shiro Filter see the web documentation.
There are two basic approaches used to define the authentication and authorization for your JAX-RS resources: paths defined statically in configuration, or via annotations on your resource.
shiro.iniJust like any other web application, your resources paths can be defined in a shiro.ini file. For example, to require resources under /api/secured to use basic authentication, your [urls] section would look like:
[urls]
/api/secured/** = authcBasic
See the web documentation for more details.
The other, probably more popular, option is to use Shiro’s annotations alongside other JAX-RS annotations on your resources. However, you MUST still define at least one path in your shiro.ini file.
The below code block will allow for basic authentication but NOT require it (via the permissive flag). This way all the resources under /api can optional require authentication and authorization based on annotations.
[urls]
/api/** = authcBasic[permissive]
In addition to all Shiro annotations, Jax-RS module allows to specify Jakarta EE security annotations such as @RolesAllowed, @DenyAll and @PermitAll on your Jax-RS Endpoints.
If calling remote EJBs, for example, the container security mechanism might interpret java.security.Principal and will error the remote EJB call as unauthenticated.
If Jax-RS is used in conjunction with the Jakarta EE module, the principal propagation is configured by Jakarta EE. However, if Jax-RS module is used standalone, principal propagation can be disabled by adding a configuration property to the map as illustrated below:
@ApplicationPath("/api")
public class JaxRsApplication extends Application {
@Override
public Map<String, Object> getProperties() {
return Map.of(SHIRO_WEB_JAXRS_DISABLE_PRINCIPAL_PARAM, Boolean.TRUE);
}
}
To create a simple example we can define a JAX-RS resource HelloShiro:
@Path("/shiro")
public class HelloShiro {
@GET
@RequiresUser
public String sayHelloShiro() {
return "Hello!";
}
@GET
@Path("define")
@RequiresPermissions("hello:define")
public String defineShiro() {
return "Shiro is the Japanese term for a castle";
}
}
This resource has two end points, the first allows access by any logged-in user, the second any user with the permission hello:define.
The corresponding JAX-RS Application class:
@ApplicationPath("/api")
public class ExampleApp extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
// register the Shiro Feature
classes.add(ShiroFeature.class);
// register resources:
classes.add(HelloShiro.class);
return classes;
}
}
The ShiroFeature does three things:
configures exception mapping from Shiro’s AuthorizationException to HTTP status codes (401 and 403)
exposes Shiro’s Subject as a java.security.Principal (Principal Propagation)
Configures processing of Shiro’s annotations
In the above example, requests to either /api/shiro or /api/shiro/define will return an HTTP status of 401 if a user is not currently logged in. A request to /api/shiro/define made by a user without the hello:define will return a 403.
You can find portable JAX-RS application that runs with Jersey, RestEasy or Apache CXF in the samples directory on GitHub.