////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Security Guide

include::./attributes.adoc[]

Quarkus comes with build in security to allow for RBAC based on the common security annotations `@RolesAllowed`,
`@DenyAll`, `@PermitAll` on REST endpoints. An example of an endpoint that makes use of both JAX-RS and Common
Security annotations to describe and secure its endpoints is given in <<subject-example>>. Quarkus also provides
the `io.quarkus.security.Authenticated` annotation that will permit any authenticated user to access the resource
(equivalent to `@RolesAllowed("*"))`.

[#subject-example]
.SubjectExposingResource Example
[source,java]
--
import java.security.Principal;

import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.SecurityContext;

@Path("subject")
public class SubjectExposingResource {

    @GET
    @Path("secured")
    @RolesAllowed("Tester") <1>
    public String getSubjectSecured(@Context SecurityContext sec) {
        Principal user = sec.getUserPrincipal(); <2>
        String name = user != null ? user.getName() : "anonymous";
        return name;
    }

    @GET
    @Path("unsecured")
    @PermitAll<3>
    public String getSubjectUnsecured(@Context SecurityContext sec) {
        Principal user = sec.getUserPrincipal(); <4>
        String name = user != null ? user.getName() : "anonymous";
        return name;
    }

    @GET
    @Path("denied")
    @DenyAll<5>
    public String getSubjectDenied(@Context SecurityContext sec) {
        Principal user = sec.getUserPrincipal();
        String name = user != null ? user.getName() : "anonymous";
        return name;
    }
}
--
<1> This `/subject/secured` endpoint requires an authenticated user that has been granted the role "Tester" through the use of the `@RolesAllowed("Tester")` annotation.
<2> The endpoint obtains the user principal from the JAX-RS SecurityContext. This will be non-null for a secured endpoint.
<3> The `/subject/unsecured` endpoint allows for unauthenticated access by specifying the `@PermitAll` annotation.
<4> This call to obtain the user principal will return null if the caller is unauthenticated, non-null if the caller is authenticated.
<5> The `/subject/denied` endpoint disallows any access regardless of whether the call is authenticated by specifying the `@DenyAll` annotation.

## Security implementations

Quarkus comes with several different Security extensions that provide different functionality. This functionality is
very much a work in progress, so this list will be expanded over the coming weeks.


.Security Extensions
|===
|Extension |Description

|link:elytron-properties-guide.html[quarkus-elytron-security-properties-file]
|Provides support for simples properties files that can be used for testing security. This supports both embedding user info in `application.properties` and standalone properties files.

|link:oauth2-guide.html[quarkus-elytron-security-oauth2]
|Provides support for OAuth2 flows using Elytron. This extension will likely be deprecated soon and replaced by a reactive Vert.x version.

|link:jwt-guide.html[quarkus-smallrye-jwt]
|A Microprofile JWT implementation that provides support for authenticating using Json Web Tokens. This also allows you to inject the token and claims into the application as per the MP JWT spec.

|link:oidc-guide.html[quarkus-oidc]
|Provides support for authenticating via an OpenID Connect provider such as Keycloak.

|===

Please see the linked documents above for details on how to setup the various extensions.

### Securing Web Endpoints

Quarkus has an integrated plugable web security layer. If security is enabled all HTTP requests will have a permission
check performed to make sure they are permitted to continue.

The default implementation allows you to define permissions using config in `application.properties`. An example
config is shown below:

[source,properties]
--

quarkus.http.auth.policy.role-policy1.roles-allowed=user,admin                      <1>

quarkus.http.auth.permission.roles1.paths=/roles-secured/*,/other/*,/api/*          <2>
quarkus.http.auth.permission.roles1.policy=role-policy1

quarkus.http.auth.permission.permit1.paths=/public/*                                <3>
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET

quarkus.http.auth.permission.deny1.paths=/forbidden                                 <4>
quarkus.http.auth.permission.deny1.policy=deny
--
<1> This defines a role based policy that allows users with the `user` and `admin` roles. This is referenced by later rules
<2> This is a permission set that references the previously defined policy. `roles1` is an arbitrary name, you can call the permission sets whatever you want.
<3> This permission references the default `permit` built in policy to allow `GET` methods to `/public`. This is actually a no-op in this example, as this request would have been allowed anyway.
<4> This permission references the built in `deny` build in policy `/forbidden`. This is an exact path match as it does not end with *.

Permissions are defined in config using permission sets. These are arbitrarily named permission grouping. Each permission
set must specify a policy that is used to control access. There are three built in policies: `deny`, `permit` and `authenticated`,
which permit all, deny all and only allow authenticated users respectively.

It is also possible to define role based policies, as shown in the example. These policies will only allow users with the
specified roles to access the resources.

Policies are pluggable so it is possible for other Quarkus extensions to provide additional policies.

Permission sets can also specify paths and methods as a comma separated list. If a path ends with '*' then it is considered
to be a wildcard match and will match all sub paths, otherwise it is an exact match and will only match that specific path.

If a request would match one or more permission sets based on the path, but does not match any due to method requirements
then the request is rejected.

Matching is always done on a longest path basis, less specific permission sets are not considered if a more specific one
has been matched.

If a path is registered with multiple permission sets then any permission sets that specify a HTTP method will take
precedence and permissions sets without a method will not be considered (assuming of course the method matches). In this
instance permission sets will only come into effect if the request method does not match any of the sets with method permissions.
If a request would have matched based on path, but does not match any permission sets because of method requirements
then this request is rejected.

If multiple permission sets specify the same path and method (or multiple have no method) then both permissions have to
allow access for the request to proceed. Note that for this to happen both have to either have specified the method, or
have no method, method specific matches take precedence as stated above.


### Registering Security Providers
When running in native mode the default behavior for Graal native image generation is to only include the main "SUN" provider
unless you have enabled SSL, in which case all security providers are registered. If you are not using SSL, then you can selectively
register security providers by name using the `quarkus.security.users.security-providers` property. The following example illustrates
configuration to register the "SunRsaSign" and "SunJCE" security providers:

.Example Security Providers Configuration
[source,properties]
----
quarkus.security.security-providers=SunRsaSign,SunJCE
...
----
