By default, Spring Security requires that every request be authenticated.
That said, any time you use xref:servlet/configuration/java.adoc#jc-httpsecurity[an `HttpSecurity` instance], it's necessary to declare your authorization rules.
This tells Spring Security that any endpoint in your application requires that the security context at a minimum be authenticated in order to allow it.
== Understanding How Request Authorization Components Work
[NOTE]
This section builds on xref:servlet/architecture.adoc#servlet-architecture[Servlet Architecture and Implementation] by digging deeper into how xref:servlet/authorization/index.adoc#servlet-authorization[authorization] works at the request level in Servlet-based applications.
* image:{icondir}/number_1.png[] First, the `AuthorizationFilter` constructs a `Supplier` that retrieves an xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] from the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder].
* image:{icondir}/number_2.png[] Second, it passes the `Supplier<Authentication>` and the `HttpServletRequest` to the xref:servlet/architecture.adoc#authz-authorization-manager[`AuthorizationManager`].
The `AuthorizationManager` matches the request to the patterns in `authorizeHttpRequests`, and runs the corresponding rule.
** image:{icondir}/number_3.png[] If authorization is denied, xref:servlet/authorization/events.adoc[an `AuthorizationDeniedEvent` is published], and an `AccessDeniedException` is thrown.
** image:{icondir}/number_4.png[] If access is granted, xref:servlet/authorization/events.adoc[an `AuthorizationGrantedEvent` is published] and `AuthorizationFilter` continues with the xref:servlet/architecture.adoc#servlet-filters-review[FilterChain] which allows the application to process normally.
The `AuthorizationFilter` is last in xref:servlet/architecture.adoc#servlet-filterchain-figure[the Spring Security filter chain] by default.
This means that Spring Security's xref:servlet/authentication/index.adoc[authentication filters], xref:servlet/exploits/index.adoc[exploit protections], and other filter integrations do not require authorization.
If you add filters of your own before the `AuthorizationFilter`, they will also not require authorization; otherwise, they will.
A place where this typically becomes important is when you are adding {spring-framework-reference-url}web.html#spring-web[Spring MVC] endpoints.
Because they are executed by the {spring-framework-reference-url}web.html#mvc-servlet[`DispatcherServlet`] and this comes after the `AuthorizationFilter`, your endpoints need to be <<authorizing-endpoints,included in `authorizeHttpRequests` to be permitted>>.
The `AuthorizationFilter` runs not just on every request, but on every dispatch.
This means that the `REQUEST` dispatch needs authorization, but also ``FORWARD``s, ``ERROR``s, and ``INCLUDE``s.
For example, {spring-framework-reference-url}web.html#spring-web[Spring MVC] can `FORWARD` the request to a view resolver that renders a Thymeleaf template, like so:
Another example of this principle is {spring-boot-reference-url}reference/web/servlet.html#web.servlet.spring-mvc.error-handling[how Spring Boot handles errors].
then Boot will dispatch it to the `ERROR` dispatch.
In that case, authorization also happens twice; once for authorizing `/endpoint` and once for dispatching the error.
For that reason, you may want to <<match-by-dispatcher-type, permit all `ERROR` dispatches>>.
=== `Authentication` Lookup is Deferred
Remember that xref:servlet/authorization/architecture.adoc#_the_authorizationmanager[the `AuthorizationManager` API uses a `Supplier<Authentication>`].
This matters with `authorizeHttpRequests` when requests are <<authorize-requests,always permitted or always denied>>.
In those cases, xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[the `Authentication`] is not queried, making for a faster request.
[[authorizing-endpoints]]
== Authorizing an Endpoint
You can configure Spring Security to have different rules by adding more rules in order of precedence.
If you want to require that `/endpoint` only be accessible by end users with the `USER` authority, then you can do:
These authorization rules should read as: "if the request is a GET, then require `read` permission; else, if the request is a POST, then require `write` permission; else, deny the request"
[TIP]
Denying the request by default is a healthy security practice since it turns the set of rules into an allow list.
Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way:
As stated earlier, Spring Security <<_all_dispatches_are_authorized, authorizes all dispatcher types by default>>.
And even though xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontext[the security context] established on the `REQUEST` dispatch carries over to subsequent dispatches, subtle mismatches can sometimes cause an unexpected `AccessDeniedException`.
To address that, you can configure Spring Security Java configuration to allow dispatcher types like `FORWARD` and `ERROR`, like so:
There are several other components that create request matchers for you like {spring-boot-api-url}org/springframework/boot/autoconfigure/security/servlet/PathRequest.html[`PathRequest#toStaticResources#atCommonLocations`]
In Java configuration, you can create your own javadoc:org.springframework.security.web.util.matcher.RequestMatcher[] and supply it to the DSL like so:
Once a request is matched, you can authorize it in several ways <<match-requests, already seen>> like `permitAll`, `denyAll`, and `hasAuthority`.
As a quick summary, here are the authorization rules built into the DSL:
* `permitAll` - The request requires no authorization and is a public endpoint; note that in this case, xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[the `Authentication`] is never retrieved from the session
* `denyAll` - The request is not allowed under any circumstances; note that in this case, the `Authentication` is never retrieved from the session
* `hasAuthority` - The request requires that the `Authentication` have xref:servlet/authorization/architecture.adoc#authz-authorities[a `GrantedAuthority`] that matches the given value
* `hasRole` - A shortcut for `hasAuthority` that prefixes `ROLE_` or whatever is configured as the default prefix
* `hasAnyAuthority` - The request requires that the `Authentication` have a `GrantedAuthority` that matches any of the given values
* `hasAnyRole` - A shortcut for `hasAnyAuthority` that prefixes `ROLE_` or whatever is configured as the default prefix
* `access` - The request uses this custom `AuthorizationManager` to determine access
Having now learned the patterns, rules, and how they can be paired together, you should be able to understand what is going on in this more complex example:
<1> There are multiple authorization rules specified.
Each rule is considered in the order they were declared.
<2> Dispatches `FORWARD` and `ERROR` are permitted to allow {spring-framework-reference-url}web.html#spring-web[Spring MVC] to render views and Spring Boot to render errors
<3> We specified multiple URL patterns that any user can access.
While using a concrete `AuthorizationManager` is recommended, there are some cases where an expression is necessary, like with `<intercept-url>` or with JSP Taglibs.
For that reason, this section will focus on examples from those domains.
Given that, let's cover Spring Security's Web Security Authorization SpEL API a bit more in depth.
Spring Security encapsulates all of its authorization fields and methods in a set of root objects.
The most generic root object is called `SecurityExpressionRoot` and it forms the basis for `WebSecurityExpressionRoot`.
Spring Security supplies this root object to `StandardEvaluationContext` when preparing to evaluate an authorization expression.
=== Using Authorization Expression Fields and Methods
The first thing this provides is an enhanced set of authorization fields and methods to your SpEL expressions.
What follows is a quick overview of the most common methods:
* `permitAll` - The request requires no authorization to be invoked; note that in this case, xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[the `Authentication`] is never retrieved from the session
* `denyAll` - The request is not allowed under any circumstances; note that in this case, the `Authentication` is never retrieved from the session
* `hasAuthority` - The request requires that the `Authentication` have xref:servlet/authorization/architecture.adoc#authz-authorities[a `GrantedAuthority`] that matches the given value
* `hasRole` - A shortcut for `hasAuthority` that prefixes `ROLE_` or whatever is configured as the default prefix
* `hasAnyAuthority` - The request requires that the `Authentication` have a `GrantedAuthority` that matches any of the given values
* `hasAnyRole` - A shortcut for `hasAnyAuthority` that prefixes `ROLE_` or whatever is configured as the default prefix
* `hasPermission` - A hook into your `PermissionEvaluator` instance for doing object-level authorization
And here is a brief look at the most common fields:
* `authentication` - The `Authentication` instance associated with this method invocation
* `principal` - The `Authentication#getPrincipal` associated with this method invocation
Having now learned the patterns, rules, and how they can be paired together, you should be able to understand what is going on in this more complex example:
=== Use an Authorization Database, Policy Agent, or Other Service
If you want to configure Spring Security to use a separate service for authorization, you can create your own `AuthorizationManager` and match it to `anyRequest`.
First, your `AuthorizationManager` may look something like this:
The javadoc:org.springframework.security.web.access.intercept.AuthorizationFilter[] provides xref:servlet/authorization/index.adoc#servlet-authorization[authorization] for ``HttpServletRequest``s.
It is inserted into the xref:servlet/architecture.adoc#servlet-filterchainproxy[FilterChainProxy] as one of the xref:servlet/architecture.adoc#servlet-security-filters[Security Filters].
You can override the default when you declare a `SecurityFilterChain`.
Instead of using javadoc:org.springframework.security.config.annotation.web.builders.HttpSecurity#authorizeRequests()[authorizeRequests], use `authorizeHttpRequests`, like so:
This improves on `authorizeRequests` in a number of ways:
1. Uses the simplified `AuthorizationManager` API instead of metadata sources, config attributes, decision managers, and voters.
This simplifies reuse and customization.
2. Delays `Authentication` lookup.
Instead of the authentication needing to be looked up for every request, it will only look it up in requests where an authorization decision requires authentication.
When `authorizeHttpRequests` is used instead of `authorizeRequests`, then javadoc:org.springframework.security.web.access.intercept.AuthorizationFilter[] is used instead of javadoc:org.springframework.security.web.access.intercept.FilterSecurityInterceptor[].
For Java configuration, javadoc:org.springframework.security.web.access.expression.WebExpressionAuthorizationManager[] is available to help migrate legacy SpEL.
If you are referring to a bean in your expression like so: `@webSecurity.check(authentication, request)`, it's recommended that you instead call the bean directly, which will look something like the following:
For complex instructions that include bean references as well as other expressions, it is recommended that you change those to implement `AuthorizationManager` and refer to them by calling `.access(AuthorizationManager)`.
If you are not able to do that, you can configure a javadoc:org.springframework.security.web.access.expression.DefaultHttpSecurityExpressionHandler[] with a bean resolver and supply that to `WebExpressionAuthorizationManager#setExpressionhandler`.
We use `securityMatchers` to determine if xref:servlet/configuration/java.adoc#jc-httpsecurity[a given `HttpSecurity`] should be applied to a given request.
The `securityMatcher(s)` and `requestMatcher(s)` methods will decide which `RequestMatcher` implementation fits best for your application: If {spring-framework-reference-url}web.html#spring-web[Spring MVC] is in the classpath, then javadoc:org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher[] will be used, otherwise, javadoc:org.springframework.security.web.util.matcher.AntPathRequestMatcher[] will be used.
Now that you have secured your application's requests, consider xref:servlet/authorization/method-security.adoc[securing its methods].
You can also read further on xref:servlet/test/index.adoc[testing your application] or on integrating Spring Security with other aspects of you application like xref:servlet/integrations/data.adoc[the data layer] or xref:servlet/integrations/observability.adoc[tracing and metrics].