[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.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-jaxrs</artifactId>
<version>2.0.1</version>
</dependency>
compile 'org.apache.shiro:shiro-servlet-plugin:2.0.1'
compile 'org.apache.shiro:shiro-jaxrs:2.0.1'
libraryDependencies = "org.apache.shiro" % "shiro-servlet-plugin" % "2.0.1"
libraryDependencies = "org.apache.shiro" % "shiro-jaxrs" % "2.0.1"
<dependency org="org.apache.shiro" name="shiro-servlet-plugin" rev="2.0.1"/>
<dependency org="org.apache.shiro" name="shiro-jaxrs" rev="2.0.1"/>
[org.apache.shiro/shiro-servlet-plugin "2.0.1"]
[org.apache.shiro/shiro-jaxrs "2.0.1"]
'org.apache.shiro:shiro-servlet-plugin:jar:2.0.1'
'org.apache.shiro:shiro-jaxrs:jar:2.0.1'
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.ini
Just 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.