Skip to content

Commit 884cf0d

Browse files
committed
EnableGlobalMultiFactorAuthentication->EnableMultiFactorAuthentication
Closes gh-18127
1 parent aaf738f commit 884cf0d

File tree

12 files changed

+72
-54
lines changed

12 files changed

+72
-54
lines changed

config/src/main/java/org/springframework/security/config/annotation/authorization/AuthorizationManagerFactoryConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
import org.springframework.security.authorization.DefaultAuthorizationManagerFactory;
2828

2929
/**
30-
* Uses {@link EnableGlobalMultiFactorAuthentication} to configure a
30+
* Uses {@link EnableMultiFactorAuthentication} to configure a
3131
* {@link DefaultAuthorizationManagerFactory}.
3232
*
3333
* @author Rob Winch
3434
* @since 7.0
35-
* @see EnableGlobalMultiFactorAuthentication
35+
* @see EnableMultiFactorAuthentication
3636
*/
3737
class AuthorizationManagerFactoryConfiguration implements ImportAware {
3838

@@ -49,7 +49,7 @@ DefaultAuthorizationManagerFactory authorizationManagerFactory(ObjectProvider<Ro
4949
@Override
5050
public void setImportMetadata(AnnotationMetadata importMetadata) {
5151
Map<String, Object> multiFactorAuthenticationAttrs = importMetadata
52-
.getAnnotationAttributes(EnableGlobalMultiFactorAuthentication.class.getName());
52+
.getAnnotationAttributes(EnableMultiFactorAuthentication.class.getName());
5353

5454
this.authorities = (String[]) multiFactorAuthenticationAttrs.getOrDefault("authorities", new String[0]);
5555
}
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,20 @@
2626
import org.springframework.security.authorization.DefaultAuthorizationManagerFactory;
2727

2828
/**
29-
* Exposes a {@link DefaultAuthorizationManagerFactory} as a Bean with the
30-
* {@link #authorities()} specified as additional required authorities. The configuration
31-
* will be picked up by both
29+
* Enables Multi-Factor Authentication (MFA) support within Spring Security.
30+
*
31+
* When {@link #authorities()} is specified creates a
32+
* {@link DefaultAuthorizationManagerFactory} as a Bean with the {@link #authorities()}
33+
* specified as additional required authorities. The configuration will be picked up by
34+
* both
3235
* {@link org.springframework.security.config.annotation.web.configuration.EnableWebSecurity}
3336
* and
3437
* {@link org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity}.
3538
*
3639
* <pre>
3740
3841
* &#64;Configuration
39-
* &#64;EnableGlobalMultiFactorAuthentication(authorities = { GrantedAuthorities.FACTOR_OTT, GrantedAuthorities.FACTOR_PASSWORD })
42+
* &#64;EnableMultiFactorAuthentication(authorities = { GrantedAuthorities.FACTOR_OTT, GrantedAuthorities.FACTOR_PASSWORD })
4043
* public class MyConfiguration {
4144
* // ...
4245
* }
@@ -51,8 +54,8 @@
5154
@Retention(RetentionPolicy.RUNTIME)
5255
@Target(ElementType.TYPE)
5356
@Documented
54-
@Import(GlobalMultiFactorAuthenticationSelector.class)
55-
public @interface EnableGlobalMultiFactorAuthentication {
57+
@Import(MultiFactorAuthenticationSelector.class)
58+
public @interface EnableMultiFactorAuthentication {
5659

5760
/**
5861
* The additional authorities that are required.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@
2525
import org.springframework.security.authorization.DefaultAuthorizationManagerFactory;
2626

2727
/**
28-
* Uses {@link EnableGlobalMultiFactorAuthentication} to configure a
28+
* Uses {@link EnableMultiFactorAuthentication} to configure a
2929
* {@link DefaultAuthorizationManagerFactory}.
3030
*
3131
* @author Rob Winch
3232
* @since 7.0
33-
* @see EnableGlobalMultiFactorAuthentication
33+
* @see EnableMultiFactorAuthentication
3434
*/
35-
class GlobalMultiFactorAuthenticationSelector implements ImportSelector {
35+
class MultiFactorAuthenticationSelector implements ImportSelector {
3636

3737
@Override
3838
public String[] selectImports(AnnotationMetadata metadata) {
3939
Map<String, Object> multiFactorAuthenticationAttrs = metadata
40-
.getAnnotationAttributes(EnableGlobalMultiFactorAuthentication.class.getName());
40+
.getAnnotationAttributes(EnableMultiFactorAuthentication.class.getName());
4141
String[] authorities = (String[]) multiFactorAuthenticationAttrs.getOrDefault("authorities", new String[0]);
4242
List<String> imports = new ArrayList<>(2);
4343
if (authorities.length > 0) {
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@
5353
import static org.mockito.Mockito.mock;
5454

5555
/**
56-
* Tests for {@link EnableGlobalMultiFactorAuthentication}.
56+
* Tests for {@link EnableMultiFactorAuthentication}.
5757
*
5858
* @author Rob Winch
5959
*/
6060
@ExtendWith(SpringExtension.class)
6161
@WebAppConfiguration
6262
@WithMockUser(authorities = FactorGrantedAuthority.PASSWORD_AUTHORITY)
63-
public class EnableGlobalMultiFactorAuthenticationFiltersSetTests {
63+
public class EnableMultiFactorAuthenticationFiltersSetTests {
6464

6565
@Autowired
6666
private AuthenticationManager manager;
@@ -105,7 +105,7 @@ private void assertMfaEnabled(Filter filter) throws Exception {
105105

106106
@EnableWebSecurity
107107
@Configuration
108-
@EnableGlobalMultiFactorAuthentication(
108+
@EnableMultiFactorAuthentication(
109109
authorities = { FactorGrantedAuthority.OTT_AUTHORITY, FactorGrantedAuthority.PASSWORD_AUTHORITY })
110110
static class Config {
111111

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@
5959
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
6060

6161
/**
62-
* Tests for {@link EnableGlobalMultiFactorAuthentication}.
62+
* Tests for {@link EnableMultiFactorAuthentication}.
6363
*
6464
* @author Rob Winch
6565
*/
6666
@ExtendWith(SpringExtension.class)
6767
@WebAppConfiguration
68-
public class EnableGlobalMultiFactorAuthenticationTests {
68+
public class EnableMultiFactorAuthenticationTests {
6969

7070
private static final String ATTR_NAME = "org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors$SecurityContextRequestPostProcessorSupport$TestSecurityContextRepository.REPO";
7171

@@ -111,7 +111,7 @@ void methodWhenNotAuthorized() throws Exception {
111111
@EnableWebSecurity
112112
@EnableMethodSecurity
113113
@Configuration
114-
@EnableGlobalMultiFactorAuthentication(
114+
@EnableMultiFactorAuthentication(
115115
authorities = { FactorGrantedAuthority.OTT_AUTHORITY, FactorGrantedAuthority.PASSWORD_AUTHORITY })
116116
static class Config {
117117

docs/modules/ROOT/pages/servlet/authentication/mfa.adoc

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ In order to require MFA with Spring Security you must:
1818
- Specify an authorization rule that requires multiple factors
1919
- Setup authentication for each of those factors
2020

21-
[[egmfa]]
22-
== @EnableGlobalMultiFactorAuthentication
21+
[[emfa]]
22+
== @EnableMultiFactorAuthentication
2323

24-
javadoc:org.springframework.security.config.annotation.authorization.EnableGlobalMultiFactorAuthentication[format=annotation] simplifies Global MFA (the entire application requires MFA).
24+
javadoc:org.springframework.security.config.annotation.authorization.EnableMultiFactorAuthentication[format=annotation] makes it easy to enable multifactor authentication.
2525
Below you can find a configuration that adds the requirement for both passwords and OTT to every authorization rule.
2626

27-
include-code::./EnableGlobalMultiFactorAuthenticationConfiguration[tag=enable-global-mfa,indent=0]
27+
include-code::./EnableMultiFactorAuthenticationConfiguration[tag=enable-mfa,indent=0]
2828

2929
We are now able to concisely create a configuration that always requires multiple factors.
3030

31-
include-code::./EnableGlobalMultiFactorAuthenticationConfiguration[tag=httpSecurity,indent=0]
31+
include-code::./EnableMultiFactorAuthenticationConfiguration[tag=httpSecurity,indent=0]
3232
<1> URLs that begin with `/admin/**` require the authorities `FACTOR_OTT`, `FACTOR_PASSWORD`, `ROLE_ADMIN`.
3333
<2> Every other URL requires the authorities `FACTOR_OTT`, `FACTOR_PASSWORD`
3434
<3> Set up the authentication mechanisms that can provide the required factors.
@@ -40,18 +40,18 @@ If the user logged in initially with a token, then Spring Security redirects to
4040
[[authorization-manager-factory]]
4141
== AuthorizationManagerFactory
4242

43-
The `@EnableGlobalMultiFactorAuthentication` annotation is just a shortcut for publishing an javadoc:org.springframework.security.authorization.AuthorizationManagerFactory[] Bean.
43+
The `@EnableMultiFactorAuthentication` `authorities` property is just a shortcut for publishing an javadoc:org.springframework.security.authorization.AuthorizationManagerFactory[] Bean.
4444
When an `AuthorizationManagerFactory` Bean is available, it is used by Spring Security to create authorization rules, like `hasAnyRole(String)`, that are defined on the `AuthorizationManagerFactory` Bean interface.
45-
The implementation published by `@EnableGlobalMultiFactorAuthentication` will ensure that each authorization is combined with the requirement of having the specified factors.
45+
The implementation published by `@EnableMultiFactorAuthentication` will ensure that each authorization is combined with the requirement of having the specified factors.
4646

47-
The `AuthorizationManagerFactory` Bean below is what is published in the previously discussed xref:./mfa.adoc#using-egmfa[`@EnableGlobalMultiFactorAuthentication` example].
47+
The `AuthorizationManagerFactory` Bean below is what is published in the previously discussed xref:./mfa.adoc#emfa[`@EnableMultiFactorAuthentication` example].
4848

4949
include-code::./UseAuthorizationManagerFactoryConfiguration[tag=authorizationManagerFactoryBean,indent=0]
5050

5151
[[selective-mfa]]
5252
== Selectively Requiring MFA
5353

54-
We have demonstrated how to configure an entire application to require MFA (Global MFA) by using xref:./mfa.adoc#egmfa[`@EnableGlobalMultiFactorAuthentication`].
54+
We have demonstrated how to configure an entire application to require MFA by using xref:./mfa.adoc#emfa[`@EnableMultiFactorAuthentication`]s `authorities` property.
5555
However, there are times that an application only wants parts of the application to require MFA.
5656
Consider the following requirements:
5757

@@ -63,6 +63,13 @@ In this case, some URLs require MFA while others do not.
6363
This means that the global approach that we saw before does not work.
6464
Fortunately, we can use what we learned in xref:./mfa.adoc#authorization-manager-factory[] to solve this in a concise manner.
6565

66+
Start by specifying `@EnableMultiFactorAuthentication` without any authorities.
67+
By doing so we enable MFA support, but no `AuthorizationManagerFactory` Bean is published.
68+
69+
include-code::./SelectiveMfaConfiguration[tag=enable-mfa,indent=0]
70+
71+
Next create an `AuthorizationManagerFactory` instance, but do not publish it as a Bean.
72+
6673
include-code::./SelectiveMfaConfiguration[tag=httpSecurity,indent=0]
6774
<1> Create a `DefaultAuthorizationManagerFactory` as we did previously, but do not publish it as a Bean.
6875
By not publishing it as a Bean, we are able to selectively use the `AuthorizationManagerFactory` instead of using it for every authorization rule.
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
package org.springframework.security.docs.servlet.authentication.egmfa;
1+
package org.springframework.security.docs.servlet.authentication.emfa;
22

33
import org.springframework.context.annotation.Bean;
44
import org.springframework.context.annotation.Configuration;
55
import org.springframework.security.config.Customizer;
6-
import org.springframework.security.config.annotation.authorization.EnableGlobalMultiFactorAuthentication;
6+
import org.springframework.security.config.annotation.authorization.EnableMultiFactorAuthentication;
77
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
88
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
99
import org.springframework.security.core.authority.FactorGrantedAuthority;
@@ -16,12 +16,12 @@
1616

1717
@EnableWebSecurity
1818
@Configuration(proxyBeanMethods = false)
19-
// tag::enable-global-mfa[]
20-
@EnableGlobalMultiFactorAuthentication(authorities = {
19+
// tag::enable-mfa[]
20+
@EnableMultiFactorAuthentication(authorities = {
2121
FactorGrantedAuthority.PASSWORD_AUTHORITY,
2222
FactorGrantedAuthority.OTT_AUTHORITY })
23-
// end::enable-global-mfa[]
24-
public class EnableGlobalMultiFactorAuthenticationConfiguration {
23+
// end::enable-mfa[]
24+
public class EnableMultiFactorAuthenticationConfiguration {
2525

2626
// tag::httpSecurity[]
2727
@Bean
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.security.docs.servlet.authentication.egmfa;
17+
package org.springframework.security.docs.servlet.authentication.emfa;
1818

1919
import org.junit.jupiter.api.Test;
2020
import org.junit.jupiter.api.extension.ExtendWith;
@@ -44,7 +44,7 @@
4444
*/
4545
@ExtendWith({ SpringExtension.class, SpringTestContextExtension.class })
4646
@TestExecutionListeners(WithSecurityContextTestExecutionListener.class)
47-
public class EnableGlobalMultiFactorAuthenticationTests {
47+
public class EnableMultiFactorAuthenticationTests {
4848

4949
public final SpringTestContext spring = new SpringTestContext(this);
5050

@@ -54,7 +54,7 @@ public class EnableGlobalMultiFactorAuthenticationTests {
5454
@Test
5555
@WithMockUser(authorities = { FactorGrantedAuthority.PASSWORD_AUTHORITY, FactorGrantedAuthority.OTT_AUTHORITY, "ROLE_USER" })
5656
void getWhenAuthenticatedWithPasswordAndOttThenPermits() throws Exception {
57-
this.spring.register(EnableGlobalMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
57+
this.spring.register(EnableMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
5858
// @formatter:off
5959
this.mockMvc.perform(get("/"))
6060
.andExpect(status().isOk())
@@ -65,7 +65,7 @@ void getWhenAuthenticatedWithPasswordAndOttThenPermits() throws Exception {
6565
@Test
6666
@WithMockUser(authorities = FactorGrantedAuthority.PASSWORD_AUTHORITY)
6767
void getWhenAuthenticatedWithPasswordThenRedirectsToOtt() throws Exception {
68-
this.spring.register(EnableGlobalMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
68+
this.spring.register(EnableMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
6969
// @formatter:off
7070
this.mockMvc.perform(get("/"))
7171
.andExpect(status().is3xxRedirection())
@@ -76,7 +76,7 @@ void getWhenAuthenticatedWithPasswordThenRedirectsToOtt() throws Exception {
7676
@Test
7777
@WithMockUser(authorities = FactorGrantedAuthority.OTT_AUTHORITY)
7878
void getWhenAuthenticatedWithOttThenRedirectsToPassword() throws Exception {
79-
this.spring.register(EnableGlobalMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
79+
this.spring.register(EnableMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
8080
// @formatter:off
8181
this.mockMvc.perform(get("/"))
8282
.andExpect(status().is3xxRedirection())
@@ -87,7 +87,7 @@ void getWhenAuthenticatedWithOttThenRedirectsToPassword() throws Exception {
8787
@Test
8888
@WithMockUser
8989
void getWhenAuthenticatedThenRedirectsToPassword() throws Exception {
90-
this.spring.register(EnableGlobalMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
90+
this.spring.register(EnableMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
9191
// @formatter:off
9292
this.mockMvc.perform(get("/"))
9393
.andExpect(status().is3xxRedirection())
@@ -97,7 +97,7 @@ void getWhenAuthenticatedThenRedirectsToPassword() throws Exception {
9797

9898
@Test
9999
void getWhenUnauthenticatedThenRedirectsToBoth() throws Exception {
100-
this.spring.register(EnableGlobalMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
100+
this.spring.register(EnableMultiFactorAuthenticationConfiguration.class, Http200Controller.class).autowire();
101101
// @formatter:off
102102
this.mockMvc.perform(get("/"))
103103
.andExpect(status().is3xxRedirection())

docs/src/test/java/org/springframework/security/docs/servlet/authentication/selectivemfa/SelectiveMfaConfiguration.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.springframework.security.authorization.AuthorizationManagerFactories;
66
import org.springframework.security.authorization.AuthorizationManagerFactory;
77
import org.springframework.security.config.Customizer;
8+
import org.springframework.security.config.annotation.authorization.EnableMultiFactorAuthentication;
89
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
910
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
1011
import org.springframework.security.core.authority.FactorGrantedAuthority;
@@ -16,6 +17,9 @@
1617
import org.springframework.security.web.authentication.ott.RedirectOneTimeTokenGenerationSuccessHandler;
1718

1819
@EnableWebSecurity
20+
// tag::enable-mfa[]
21+
@EnableMultiFactorAuthentication(authorities = {})
22+
// end::enable-mfa[]
1923
@Configuration(proxyBeanMethods = false)
2024
class SelectiveMfaConfiguration {
2125

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
package org.springframework.security.kt.docs.servlet.authentication.egmfa
1+
package org.springframework.security.kt.docs.servlet.authentication.emfa
22

33
import org.springframework.context.annotation.Bean
44
import org.springframework.context.annotation.Configuration
5-
import org.springframework.security.config.annotation.authorization.EnableGlobalMultiFactorAuthentication
5+
import org.springframework.security.config.annotation.authorization.EnableMultiFactorAuthentication
66
import org.springframework.security.config.annotation.web.builders.HttpSecurity
77
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
88
import org.springframework.security.config.annotation.web.invoke
@@ -17,12 +17,12 @@ import org.springframework.security.web.authentication.ott.RedirectOneTimeTokenG
1717
@EnableWebSecurity
1818
@Configuration(proxyBeanMethods = false)
1919

20-
// tag::enable-global-mfa[]
21-
@EnableGlobalMultiFactorAuthentication( authorities = [
20+
// tag::enable-mfa[]
21+
@EnableMultiFactorAuthentication( authorities = [
2222
FactorGrantedAuthority.PASSWORD_AUTHORITY,
2323
FactorGrantedAuthority.OTT_AUTHORITY])
24-
// end::enable-global-mfa[]
25-
internal class EnableGlobalMultiFactorAuthenticationConfiguration {
24+
// end::enable-mfa[]
25+
internal class EnableMultiFactorAuthenticationConfiguration {
2626

2727
// tag::httpSecurity[]
2828
@Bean

0 commit comments

Comments
 (0)