|
1 |
| -[[jc-authorize-requests]] |
2 |
| -== Authorize Requests |
3 |
| -Our examples have only required users to be authenticated and have done so for every URL in our application. |
4 |
| -We can specify custom requirements for our URLs by adding multiple children to our `http.authorizeRequests()` method. |
5 |
| -For example: |
| 1 | +[[servlet-authorization-filtersecurityinterceptor]] |
| 2 | += Authorize HttpServletRequest with FilterSecurityInterceptor |
| 3 | +:figures: images/servlet/authorization |
| 4 | +:icondir: images/icons |
6 | 5 |
|
| 6 | +This section builds on <<servlet-architecture,Servlet Architecture and Implementation>> by digging deeper into how <<authorization>> works within Servlet based applications. |
7 | 7 |
|
8 |
| -[source,java] |
| 8 | +The {security-api-url}org/springframework/security/web/access/intercept/FilterSecurityInterceptor.html[`FilterSecurityInterceptor`] provides <<authorization>> for ``HttpServletRequest``s. |
| 9 | +It is inserted into the <<servlet-filterchainproxy>> as one of the <<servlet-security-filters>>. |
| 10 | + |
| 11 | +.Authorize HttpServletRequest |
| 12 | +image::{figures}/filtersecurityinterceptor.png[] |
| 13 | + |
| 14 | +* image:{icondir}/number_1.png[] First, the `FilterSecurityInterceptor` obtains an <<servlet-authentication-authentication>> from the <<servlet-authentication-securitycontextholder>>. |
| 15 | +* image:{icondir}/number_2.png[] Second, `FilterSecurityInterceptor` creates a {security-api-url}org/springframework/security/web/FilterInvocation.html[`FilterInvocation`] from the `HttpServletRequest`, `HttpServletResponse`, and `FilterChain` that are passed into the `FilterSecurityInterceptor`. |
| 16 | +// FIXME: link to FilterInvocation |
| 17 | +* image:{icondir}/number_3.png[] Next, it passes the `FilterInvocation` to `SecurityMetadataSource` to get the ``ConfigAttribute``s. |
| 18 | +* image:{icondir}/number_4.png[] Finally, it passes the `Authentication`, `FilterInvocation`, and ``ConfigAttribute``s to the `AccessDecisionManager`. |
| 19 | +** image:{icondir}/number_5.png[] If authorization is denied, an `AccessDeniedException` is thrown. |
| 20 | +In this case the <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>> handles the `AccessDeniedException`. |
| 21 | +** image:{icondir}/number_6.png[] If access is granted, `FilterSecurityInterceptor` continues with the <<servlet-filters-review,FilterChain>> which allows the application to process normally. |
| 22 | + |
| 23 | +// configuration (xml/java) |
| 24 | + |
| 25 | +By default, Spring Security's authorization will require all requests to be authenticated. |
| 26 | +The explicit configuration looks like: |
| 27 | + |
| 28 | +.Every Request Must be Authenticated |
| 29 | +==== |
| 30 | +.Java |
| 31 | +[source,java,role="primary"] |
| 32 | +---- |
| 33 | +protected void configure(HttpSecurity http) throws Exception { |
| 34 | + http |
| 35 | + // ... |
| 36 | + .authorizeRequests(authorize -> authorize |
| 37 | + .anyRequest().authenticated() |
| 38 | + ); |
| 39 | +} |
| 40 | +---- |
| 41 | +
|
| 42 | +.XML |
| 43 | +[source,xml,role="secondary"] |
| 44 | +---- |
| 45 | +<http> |
| 46 | + <!-- ... --> |
| 47 | + <intercept-url pattern="/**" access="authenticated"/> |
| 48 | +</http> |
| 49 | +---- |
| 50 | +==== |
| 51 | + |
| 52 | +We can configure Spring Security to have different rules by adding more rules in order of precedence. |
| 53 | + |
| 54 | +.Authorize Requests |
| 55 | +==== |
| 56 | +.Java |
| 57 | +[source,java,role="primary"] |
9 | 58 | ----
|
10 | 59 | protected void configure(HttpSecurity http) throws Exception {
|
11 | 60 | http
|
| 61 | + // ... |
12 | 62 | .authorizeRequests(authorize -> authorize // <1>
|
13 |
| - .antMatchers("/resources/**", "/signup", "/about").permitAll() // <2> |
14 |
| - .antMatchers("/admin/**").hasRole("ADMIN") // <3> |
15 |
| - .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // <4> |
16 |
| - .anyRequest().authenticated() // <5> |
17 |
| - ) |
18 |
| - .formLogin(withDefaults()); |
| 63 | + .mvcMatchers("/resources/**", "/signup", "/about").permitAll() // <2> |
| 64 | + .mvcMatchers("/admin/**").hasRole("ADMIN") // <3> |
| 65 | + .mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // <4> |
| 66 | + .anyRequest().denyAll() // <5> |
| 67 | + ); |
19 | 68 | }
|
20 | 69 | ----
|
21 | 70 |
|
22 |
| -<1> There are multiple children to the `http.authorizeRequests()` method each matcher is considered in the order they were declared. |
| 71 | +.XML |
| 72 | +[source,xml,role="secondary"] |
| 73 | +---- |
| 74 | +<http> <!--1--> |
| 75 | + <!-- ... --> |
| 76 | + <!--2--> |
| 77 | + <intercept-url pattern="/resources/**" access="permitAll"/> |
| 78 | + <intercept-url pattern="/signup" access="permitAll"/> |
| 79 | + <intercept-url pattern="/about" access="permitAll"/> |
| 80 | +
|
| 81 | + <intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/> <!--3--> |
| 82 | + <intercept-url pattern="/db/**" access="hasRole('ADMIN') and hasRole('DBA')"/> <!--4--> |
| 83 | + <intercept-url pattern="/**" access="denyAll"/> <!--5--> |
| 84 | +</http> |
| 85 | +---- |
| 86 | +==== |
| 87 | +<1> There are multiple authorization rules specified. |
| 88 | +Each rule is considered in the order they were declared. |
23 | 89 | <2> We specified multiple URL patterns that any user can access.
|
24 | 90 | Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about".
|
25 | 91 | <3> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN".
|
26 | 92 | You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix.
|
27 | 93 | <4> Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA".
|
28 | 94 | You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix.
|
29 |
| -<5> Any URL that has not already been matched on only requires that the user be authenticated |
| 95 | +<5> Any URL that has not already been matched on is denied access. |
| 96 | +This is a good strategy if you do not want to accidentally forget to update your authorization rules. |
0 commit comments