Spring Security practice questions

From Spring Certified Professional (Develop) (2V0-72.22) · 24 questions on this topic

Spring Security practice questions from Spring Certified Professional (Develop) (2V0-72.22). This pack has 24 questions tagged Spring Security, drawn from its timed mock exams. 8 of them are worked through in full below — the question, every option, why each is right or wrong, and the explanation.

Worked examples for Spring Security

  1. Question 1

    When is @PostAuthorize evaluated relative to the method it guards?

    1. A. Before the method executes, like @PreAuthorize

      Running the check before the method describes @PreAuthorize; @PostAuthorize is the opposite, evaluating after invocation.

    2. B. Only during application startup

      @PostAuthorize is a per-call runtime check on each invocation, not something that runs only at application startup.

    3. C. After the method executes — typically to authorize based on the returned object (referenced via returnObject)Correct answer

      @PostAuthorize is evaluated after the method executes so the rule can authorize based on the returned object (referenced via returnObject), throwing if access is denied.

    4. D. It never runs unless @PreAuthorize is also present

      @PostAuthorize works independently and does not require @PreAuthorize to be present.

    Explanation

    @PostAuthorize runs after the guarded method returns so its expression can inspect the result — for example comparing returnObject.owner to the authenticated name — and deny access by throwing if the rule fails. It is a per-invocation runtime check that stands on its own, in contrast to the before-invocation check performed by @PreAuthorize.

  2. Question 2

    In security terms, what is the difference between authentication and authorization?

    1. A. Authentication applies only to URLs and authorization only to methods

      Wrong: it falsely ties each concept to a single layer. Both authentication and authorization apply at the web (URL) level and the method level; neither is restricted to one.

    2. B. Authentication decides permissions; authorization verifies identity

      This reverses the two concepts. Authentication verifies identity and authorization decides permissions, not the other way around.

    3. C. Authentication establishes WHO the principal is; authorization decides WHAT that authenticated principal is allowed to doCorrect answer

      Correct: authentication answers 'who are you?' (identity), while authorization answers 'are you allowed?' (access control), matching the Spring Security servlet authentication/authorization architecture.

    4. D. They are interchangeable terms in Spring Security

      Wrong: authentication and authorization are distinct concepts handled by separate parts of the framework and cannot be used interchangeably.

    Explanation

    Authentication and authorization are two distinct security concerns: authentication answers 'who are you?' by establishing the principal's identity, while authorization answers 'are you allowed?' by deciding what that authenticated principal may do. They are not interchangeable, and each applies at both the web (URL) and method levels rather than being confined to one.

  3. Question 3

    You are upgrading an application to Spring Boot 2.7 / Spring Security 5.7 and want to migrate an existing security class that extends WebSecurityConfigurerAdapter and overrides configure(HttpSecurity http). What is the idiomatic 5.7 replacement for that override?

    1. A. Keep extending WebSecurityConfigurerAdapter but move the body into a method annotated @PostConstruct so it runs after the context starts.

      The whole point of the 5.7 migration is to stop subclassing WebSecurityConfigurerAdapter, which is deprecated; relocating the logic to @PostConstruct still leaves the class extending the deprecated adapter and does not register the HttpSecurity configuration the framework expects.

    2. B. Annotate the configure(HttpSecurity) method with @Bean so the container publishes the adapter instance as a bean.

      Putting @Bean on an override of a deprecated adapter method does not produce the component-based configuration; the framework consumes a SecurityFilterChain bean, not a bean made out of the old callback, and the class is still tied to the adapter being removed.

    3. C. Remove the adapter and declare a SecurityFilterChain @Bean on an @EnableWebSecurity class that configures the injected HttpSecurity and returns http.build().Correct answer

      In Security 5.7 the configure(HttpSecurity) override becomes a SecurityFilterChain bean: the method receives HttpSecurity, applies the DSL (authorizeHttpRequests, form login, and so on), and ends by returning http.build(). Multiple such beans compose without adapter-ordering hacks, which is the idiomatic component-based style.

    4. D. Delete the class entirely and rely on the spring.security.filter-chain property to describe the rules in application.properties.

      There is no property that expresses an HttpSecurity DSL configuration; URL authorization rules, form login, and the like are declared programmatically through a SecurityFilterChain bean, not via a properties key.

    Explanation

    Spring Security 5.7 deprecates WebSecurityConfigurerAdapter and moves to a component-based model: the former configure(HttpSecurity) override becomes a SecurityFilterChain @Bean on an @EnableWebSecurity class that configures the injected HttpSecurity and returns http.build(). Keeping or re-annotating the deprecated adapter does not produce that bean, and no application property can substitute for the programmatic HttpSecurity DSL.

  4. Question 4

    Within FilterChainProxy, a particular SecurityFilterChain is configured with a RequestMatcher but an empty (zero-filter) list of security filters. What does registering such a chain achieve for requests it matches?

    1. A. It rejects every matching request with an access-denied response because a chain without an authorization filter can never grant access.

      An empty chain does not deny requests; because it contains no filters at all, there is no authorization filter to reject anything — the matching request simply proceeds without security processing.

    2. B. It fails application startup, since every SecurityFilterChain must declare at least one filter.

      A SecurityFilterChain is explicitly permitted to have zero filters; an empty chain is a valid, intentional configuration rather than a startup error.

    3. C. It causes Spring Security to fall back to the default filter set for those requests.

      An empty chain does not trigger a default filter set; FilterChainProxy runs exactly the (zero) filters the matched chain declares, so no security filters apply to those requests.

    4. D. It tells Spring Security to ignore those requests entirely — they pass through with no security filters applied.Correct answer

      A chain with zero filters is the documented way to have Security ignore certain requests: FilterChainProxy still selects it as the first matching chain, but since it holds no filters, the request passes through untouched by any security processing.

    Explanation

    FilterChainProxy selects the first SecurityFilterChain whose RequestMatcher matches and runs only that chain's filters. When that chain has zero filters, there is nothing to run, so matching requests pass through with no security processing at all — the documented way to tell Security to ignore certain requests. It neither denies them, nor fails startup, nor falls back to a default filter set.

  5. Question 5

    A `@Service` bean has a public method `checkout()` annotated with `@PreAuthorize("hasRole('ADMIN')")`. Method security is correctly enabled on the configuration class. A second public method on the same bean, `processOrder()`, is invoked by a controller and internally calls `this.checkout()`. At runtime the `hasRole('ADMIN')` rule is never enforced for that internal call, even when the caller is anonymous. What is the reason?

    1. A. @PreAuthorize is only honoured on beans invoked directly by the web layer; service-to-service calls are considered trusted and are skipped by design.

      Assumes method security has a notion of a 'trusted internal caller'. It has none — the rule is enforced on every invocation that passes through the proxy, no matter who the caller is; the problem here is that this particular call never reaches the proxy.

    2. B. Method security is implemented with Spring AOP proxies, and a self-invocation through `this` does not pass through the proxy, so the security interceptor is never applied.Correct answer

      Correct. Method security is applied by an AOP advice on the proxy that wraps the bean. Only calls made against the injected proxy reference are intercepted; once execution is inside the target object, `this.checkout()` is a plain Java call and no advice runs.

    3. C. The SecurityContext is bound to the outermost invocation only, so nested method calls run with an empty context and every expression silently evaluates to true.

      Confuses proxy mechanics with SecurityContextHolder propagation. The context is thread-bound and remains fully available to nested calls on the same thread; and an empty context would cause access to be denied, not silently granted.

    4. D. Pre-invocation authorization is evaluated once per request, and the outer method's invocation has already satisfied it for the remainder of that request.

      Treats authorization as a per-request gate like a URL filter. Method security is evaluated per method invocation, not once per request; the inner call is skipped because it never hits the proxy, not because a check was already 'spent'.

    Explanation

    Method-level security in Spring Security is delivered through Spring AOP: the container hands collaborators a proxy, and the security interceptor is advice on that proxy. Only invocations that cross the proxy boundary are authorized, so a call made from inside the target object on `this` bypasses the check entirely — the usual fixes are to move the secured method onto a separate bean or to invoke it through an injected reference to the proxy. There is no trusted-caller exemption for internal calls, the SecurityContextHolder is thread-bound and remains populated for nested calls (and an empty context would deny rather than grant access), and pre-invocation rules are evaluated on every intercepted invocation rather than once per request.

  6. Question 6

    A configuration class is annotated `@EnableGlobalMethodSecurity(prePostEnabled = true)`. The team is deciding whether to express a rule with `@Secured` or with `@PreAuthorize`. Which TWO statements are correct?

    1. A. As configured, `@Secured` annotations are ignored; enabling them requires `securedEnabled = true` on @EnableGlobalMethodSecurity.Correct answer

      Correct. Each annotation family has its own switch — prePostEnabled, securedEnabled, jsr250Enabled — and all default to false. Turning on the pre/post family leaves @Secured inactive.

    2. B. `@PreAuthorize` takes a SpEL expression and can therefore reference method arguments (for example `#accountId`) and the authenticated principal, while `@Secured` accepts only a plain list of security attribute (role) strings.Correct answer

      Correct. Expression support is exactly what distinguishes the pre/post annotations from @Secured: @PreAuthorize is evaluated as SpEL against a context exposing the authentication and the invocation arguments, whereas @Secured values are compared as literal authorities.

    3. C. `@Secured` also accepts SpEL, so `@Secured("hasRole('ADMIN') and #id == principal.id")` is an equivalent way to write an argument-aware rule.

      The classic misconception that @Secured and @PreAuthorize differ only in name. @Secured predates expression-based access control and treats its values as literal security attributes, so such a string would be looked for as an authority, not evaluated.

    4. D. Setting `prePostEnabled = true` implicitly activates `@Secured` and the JSR-250 annotations as well, since they share one method-security interceptor.

      Assumes the three switches are cumulative. They are independent booleans; sharing an interceptor infrastructure does not mean enabling one family registers the metadata source for the others.

    5. E. `@Secured` is evaluated after the target method returns, which lets it inspect the returned value before deciding whether access is allowed.

      Confuses @Secured with @PostAuthorize. @Secured is a pre-invocation check; only the post-invocation annotations can consult the returned object.

    Explanation

    @EnableGlobalMethodSecurity exposes one independent switch per annotation family — prePostEnabled for @PreAuthorize/@PostAuthorize/@PreFilter/@PostFilter, securedEnabled for @Secured, and jsr250Enabled for @RolesAllowed and friends — and each defaults to false, so enabling the pre/post family alone leaves @Secured annotations silently inert rather than implicitly switching them on. The substantive difference between the two styles is expression support: @PreAuthorize is evaluated as SpEL with access to the authentication and the invocation arguments, whereas @Secured compares its values as literal security attributes and cannot express an argument-aware condition. Both @Secured and @PreAuthorize are pre-invocation checks; consulting a returned value is the job of the post-invocation annotations.

  7. Question 7

    In Spring Boot 2.7 / Spring Security 5.7, the component-based configuration style replaces subclassing WebSecurityConfigurerAdapter. Which TWO beans express this idiomatic style for HTTP security and web-level ignores? Select TWO.

    1. A. A SecurityFilterChain @Bean on an @EnableWebSecurity class that configures HttpSecurity (authorizeHttpRequests, form login) and returns http.build()Correct answer

      In Security 5.7 the former configure(HttpSecurity) override becomes a SecurityFilterChain bean: it configures HttpSecurity and ends in http.build(), and multiple such beans compose cleanly. This is the idiomatic replacement for subclassing the adapter.

    2. B. A @Configuration class that extends WebSecurityConfigurerAdapter and overrides configure(HttpSecurity http)

      This is the pre-5.7 style being replaced: WebSecurityConfigurerAdapter is deprecated as of Spring Security 5.7 (shipped with Boot 2.7). It still compiles for backward compatibility but is exactly the adapter subclassing the component-based model moves away from.

    3. C. A WebSecurityCustomizer @Bean that declares web-level ignores (replacing the former configure(WebSecurity) override)Correct answer

      The former configure(WebSecurity) override becomes a WebSecurityCustomizer bean — for example web -> web.ignoring().`antMatchers("/css/**")` — so web-level ignores are expressed as a bean, the counterpart to the SecurityFilterChain bean in the component-based model.

    4. D. A @DisableSecurity annotation on the application that re-adds rules through properties

      @DisableSecurity is not a real annotation and URL authorization rules are not re-added through properties, so this describes a mechanism that does not exist in Spring Security.

    Explanation

    In Spring Security 5.7 (Boot 2.7) WebSecurityConfigurerAdapter is deprecated, and its two override methods each become a bean in the component-based style: configure(HttpSecurity) becomes a SecurityFilterChain @Bean on an @EnableWebSecurity class that configures HttpSecurity and returns http.build(), while configure(WebSecurity) becomes a WebSecurityCustomizer @Bean for web-level ignores. Subclassing the deprecated adapter is precisely the old approach being replaced, and there is no @DisableSecurity annotation that re-adds rules through properties.

  8. Question 8

    With method security enabled, a service method accepts a List<Order> argument and returns a List<Order>, and the team wants to drop, from both the incoming list and the returned list, any element the current user is not permitted to see — without throwing an exception. Which pair of annotations is designed for this element-level filtering?

    1. A. @PreAuthorize on the argument and @PostAuthorize on the result, since both evaluate a SpEL rule.

      @PreAuthorize and @PostAuthorize make a single allow-or-deny decision about the whole invocation and throw AccessDeniedException on failure; they do not remove individual elements from a collection, which is what the requirement asks for.

    2. B. @RolesAllowed on the method plus @Secured on the return type.

      @RolesAllowed and @Secured are coarse pre-invocation role checks over the whole call; neither inspects or removes individual collection elements, and @Secured cannot be applied to a return type in this way.

    3. C. @PreFilter to filter the collection argument before the method runs, and @PostFilter to filter the returned collection afterwards.Correct answer

      @PreFilter filters the elements of a collection argument before the method executes, and @PostFilter filters the elements of the returned collection afterwards — each removes the entries whose SpEL expression is false rather than throwing, which is exactly element-level filtering.

    4. D. @PreFilter for both, applied once on the argument and once on the return value.

      @PreFilter only filters an inbound collection argument before invocation; filtering the returned collection is the job of @PostFilter, so a single @PreFilter cannot cover the result.

    Explanation

    Element-level filtering of collections is the purpose of @PreFilter and @PostFilter: @PreFilter removes non-matching elements from a collection argument before the method runs, and @PostFilter removes non-matching elements from the returned collection afterwards, dropping entries silently rather than throwing. The authorization annotations @PreAuthorize/@PostAuthorize and the role-based @Secured/@RolesAllowed instead make a single allow-or-deny decision for the whole invocation and cannot strip individual elements.

Practise all 24 Spring Security questions

Spring Certified Professional (Develop) has the full set, inside timed mock exams that mirror real exam conditions — every question with a worked explanation.

Open Spring Certified Professional (Develop)

Other topics in this pack