anchor.diff:  <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.
   
  +
  +## Authorization of Web Endpoints using configuration
  +
  +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.
  +
  +### Matching on paths, methods
  +
  +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:
  +
  +[source,properties]
  +--
  +quarkus.http.auth.permission.permit1.paths=/public/*,/css/*,/js/*,/robots.txt
  +quarkus.http.auth.permission.permit1.policy=permit
  +quarkus.http.auth.permission.permit1.methods=GET,HEAD
  +--
  +
  +### Matching path but not method
  +
  +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.
  +
  +TIP: Given the above permission set, `GET /public/foo` would match both the path and method and thus be allowed,
  +whereas `POST /public/foo` would match the path but not the method and would thus be rejected.
  +
  +### Matching multiple paths: longest wins
  +
  +Matching is always done on a longest path basis, less specific permission sets are not considered if a more specific one
  +has been matched:
  +
  +[source,properties]
  +--
  +quarkus.http.auth.permission.permit1.paths=/public/*
  +quarkus.http.auth.permission.permit1.policy=permit
  +quarkus.http.auth.permission.permit1.methods=GET,HEAD
  +
  +quarkus.http.auth.permission.deny1.paths=/public/forbidden-folder/*
  +quarkus.http.auth.permission.deny1.policy=deny
  +--
  +
  +TIP: Given the above permission set, `GET /public/forbidden-folder/foo` would match both permission sets' paths,
  +but because it matches the `deny1` permission set's path on a longer match, `deny1` will be chosen and the request will
  +be rejected.
  +
  +### Matching multiple paths: most specific method wins
  +
  +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, the permission sets without methods will only come into effect if the request method does not match any of the
  +sets with method permissions.
  +
  +[source,properties]
  +--
  +quarkus.http.auth.permission.permit1.paths=/public/*
  +quarkus.http.auth.permission.permit1.policy=permit
  +quarkus.http.auth.permission.permit1.methods=GET,HEAD
  +
  +quarkus.http.auth.permission.deny1.paths=/public/*
  +quarkus.http.auth.permission.deny1.policy=deny
  +--
  +
  +TIP: Given the above permission set, `GET /public/foo` would match both permission sets' paths,
  +but because it matches the `permit1` permission set's explicit method, `permit1` will be chosen and the request will
  +be accepted. `PUT /public/foo` on the other hand, will not match the method permissions of `permit1` and so
  +`deny1` will be activated and reject the request.
  +
  +### Matching multiple paths and methods: both win
  +
  +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:
  +
  +[source,properties]
  +--
  +
  +quarkus.http.auth.policy.user-policy1.roles-allowed=user
  +quarkus.http.auth.policy.admin-policy1.roles-allowed=admin
  +
  +quarkus.http.auth.permission.roles1.paths=/api/*,/restricted/*
  +quarkus.http.auth.permission.roles1.policy=user-policy1
  +
  +quarkus.http.auth.permission.roles2.paths=/api/*,/admin/*
  +quarkus.http.auth.permission.roles2.policy=admin-policy1
  +--
  +
  +TIP: Given the above permission set, `GET /api/foo` would match both permission sets' paths,
  +so would require both the `user` and `admin` roles.
  +
   ## Configuration
   
   There are two configuration settings that alter the RBAC behavior:
  
positive.code: and JAX-RS endpoints that do not have security annotations but are defined in classes that contain methods with
  security annotations. Defaults to `false`.
  
  ## 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:security-jdbc-guide.html[quarkus-elytron-security-jdbc]
  |Provides support for authenticating via JDBC.
  
  |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.
  
  |link:keycloak-authorization-guide.html[quarkus-keycloak-authorization]
  |Provides support for a policy enforcer using Keycloak Authorization Services.
  
  
  |===
  
  Please see the linked documents above for details on how to setup the various extensions.
  
  ### Authenticating Via HTTP
  
  Quarkus has two built in authentication mechanisms for HTTP based FORM and BASIC auth. This mechanism is pluggable
  however so extensions can add additional mechanisms (most notably OpenID Connect for Keycloak based auth).
  
  #### Basic Authentication
  
  To enable basic authentication set `quarkus.http.auth.basic=true`. You must also have at least one extension installed
  that provides a username/password based `IdentityProvider`, such as link:security-jdbc-guide.html[Elytron JDBC].
  
  #### Form Based Authentication
  
  Quarkus provides form based authentication that works in a similar manner to traditional Servlet form based auth. Unlike
  traditional form authentication the authenticated user is not stored in a HTTP session, as Quarkus does not provide
  clustered HTTP session support. Instead the authentication information is stored in an encrypted cookie, which can
  be read by all members of the cluster (provided they all share the same encryption key).
  
  The encryption key can be set using the `quarkus.http.auth.session.encryption-key` property, and it must be at least 16 characters
  long. This key is hashed using SHA-256 and the resulting digest is used as a key for AES-256 encryption of the cookie
  value. This cookie contains a expiry time as part of the encrypted value, so all nodes in the cluster must have their
  clocks synchronised. At one minute intervals a new cookie will be generated with an updated expiry time if the session
  is in use.
  
  The following properties can be used to configure form based auth:
  
  include::{generated-dir}/config/quarkus-http-auth-form.adoc[opts=optional, leveloffset=+1]
  
  
  ### 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.
  
  ### Matching on paths, methods
  
  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:
  
  [source,properties]
  --
  quarkus.http.auth.permission.permit1.paths=/public/*,/css/*,/js/*,/robots.txt
  quarkus.http.auth.permission.permit1.policy=permit
  quarkus.http.auth.permission.permit1.methods=GET,HEAD
  --
  
  ### Matching path but not method
  
  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.
  
  TIP: Given the above permission set, `GET /public/foo` would match both the path and method and thus be allowed,
  whereas `POST /public/foo` would match the path but not the method and would thus be rejected.
  
  ### Matching multiple paths: longest wins
  
  Matching is always done on a longest path basis, less specific permission sets are not considered if a more specific one
  has been matched:
  
  [source,properties]
  --
  quarkus.http.auth.permission.permit1.paths=/public/*
  quarkus.http.auth.permission.permit1.policy=permit
  quarkus.http.auth.permission.permit1.methods=GET,HEAD
  
  quarkus.http.auth.permission.deny1.paths=/public/forbidden-folder/*
  quarkus.http.auth.permission.deny1.policy=deny
  --
  
  TIP: Given the above permission set, `GET /public/forbidden-folder/foo` would match both permission sets' paths,
  but because it matches the `deny1` permission set's path on a longer match, `deny1` will be chosen and the request will
  be rejected.
  
  ### Matching multiple paths: most specific method wins
  
  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, the permission sets without methods will only come into effect if the request method does not match any of the
  sets with method permissions.
  
  [source,properties]
  --
  quarkus.http.auth.permission.permit1.paths=/public/*
  quarkus.http.auth.permission.permit1.policy=permit
  quarkus.http.auth.permission.permit1.methods=GET,HEAD
  
  quarkus.http.auth.permission.deny1.paths=/public/*
  quarkus.http.auth.permission.deny1.policy=deny
  --
  
  TIP: Given the above permission set, `GET /public/foo` would match both permission sets' paths,
  but because it matches the `permit1` permission set's explicit method, `permit1` will be chosen and the request will
  be accepted. `PUT /public/foo` on the other hand, will not match the method permissions of `permit1` and so
  `deny1` will be activated and reject the request.
  
  ### Matching multiple paths and methods: both win
  
  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:
  
  [source,properties]
  --
  
  quarkus.http.auth.policy.user-policy1.roles-allowed=user
  quarkus.http.auth.policy.admin-policy1.roles-allowed=admin
  
  quarkus.http.auth.permission.roles1.paths=/api/*,/restricted/*
  quarkus.http.auth.permission.roles1.policy=user-policy1
  
  quarkus.http.auth.permission.roles2.paths=/api/*,/admin/*
  quarkus.http.auth.permission.roles2.policy=admin-policy1
  --
  
  TIP: Given the above permission set, `GET /api/foo` would match both permission sets' paths,
  so would require both the `user` and `admin` roles.
  
  ### 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
  
negative.code: 
  include::./attributes.adoc[]
  
  Quarkus security allows you to define security authorization requirements for your code using annotations and/or configuration, and provides
  several ways to load security authentication information using Quarkus extensions.
  
  ## Authentication sources
  
  Quarkus supports several sources to load authentication information from. You need to import at least one of the following extensions
  in order for Quarkus to know how to find the authentication information to check for authorizations:
  
  .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:security-jdbc-guide.html[quarkus-elytron-security-jdbc]
  |Provides support for authenticating via JDBC.
  
  |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.
  
  |link:keycloak-authorization-guide.html[quarkus-keycloak-authorization]
  |Provides support for a policy enforcer using Keycloak Authorization Services.
  
  |===
  
  Please see the linked documents above for details on how to setup the various extensions.
  
  ## Authenticating via HTTP
  
  Quarkus has two built in authentication mechanisms for HTTP based FORM and BASIC auth. This mechanism is pluggable
  however so extensions can add additional mechanisms (most notably OpenID Connect for Keycloak based auth).
  
  ### Basic Authentication
  
  To enable basic authentication set `quarkus.http.auth.basic=true`. You must also have at least one extension installed
  that provides a username/password based `IdentityProvider`, such as link:security-jdbc-guide.html[Elytron JDBC].
  
  ### Form Based Authentication
  
  Quarkus provides form based authentication that works in a similar manner to traditional Servlet form based auth. Unlike
  traditional form authentication the authenticated user is not stored in a HTTP session, as Quarkus does not provide
  clustered HTTP session support. Instead the authentication information is stored in an encrypted cookie, which can
  be read by all members of the cluster (provided they all share the same encryption key).
  
  The encryption key can be set using the `quarkus.http.auth.session.encryption-key` property, and it must be at least 16 characters
  long. This key is hashed using SHA-256 and the resulting digest is used as a key for AES-256 encryption of the cookie
  value. This cookie contains a expiry time as part of the encrypted value, so all nodes in the cluster must have their
  clocks synchronised. At one minute intervals a new cookie will be generated with an updated expiry time if the session
  is in use.
  
  The following properties can be used to configure form based auth:
  
  include::{generated-dir}/config/quarkus-http-auth-form.adoc[opts=optional, leveloffset=+1]
  
  ## Authorization in REST endpoints and CDI beans using annotations
  
  Quarkus comes with build in security to allow for Role-Based Access Control (link:https://en.wikipedia.org/wiki/Role-based_access_control[RBAC])
  based on the common security annotations `@RolesAllowed`, `@DenyAll`, `@PermitAll` on REST endpoints and CDI beans.
  