Browse Source

Update to Latest MFA Authorization responses

Josh Cummings 1 month ago
parent
commit
694a70ab36

+ 5 - 6
servlet/spring-boot/java/authentication/mfa/formLogin+ott/src/test/java/example/CustomPagesConfigTests.java

@@ -25,9 +25,7 @@ class CustomPagesConfigTests {
 
 
 	@Test
 	@Test
 	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
 	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
-		this.mvc.perform(get("/"))
-			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/auth/password"));
+		this.mvc.perform(get("/")).andExpect(status().is3xxRedirection()).andExpect(redirectedUrl("/auth/password"));
 	}
 	}
 
 
 	@Test
 	@Test
@@ -35,7 +33,8 @@ class CustomPagesConfigTests {
 	void indexWhenAuthenticatedButNoFactorsThenRedirectsToLogin() throws Exception {
 	void indexWhenAuthenticatedButNoFactorsThenRedirectsToLogin() throws Exception {
 		this.mvc.perform(get("/"))
 		this.mvc.perform(get("/"))
 			.andExpect(status().is3xxRedirection())
 			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/auth/password?factor=password"));
+			.andExpect(redirectedUrl(
+					"/auth/password?factor.type=password&factor.type=ott&factor.reason=missing&factor.reason=missing"));
 	}
 	}
 
 
 	@Test
 	@Test
@@ -43,7 +42,7 @@ class CustomPagesConfigTests {
 	void indexWhenAuthenticatedWithX509ThenRedirectsToLogin() throws Exception {
 	void indexWhenAuthenticatedWithX509ThenRedirectsToLogin() throws Exception {
 		this.mvc.perform(get("/"))
 		this.mvc.perform(get("/"))
 			.andExpect(status().is3xxRedirection())
 			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/auth/password?factor=password"));
+			.andExpect(redirectedUrl("/auth/password?factor.type=password&factor.reason=missing"));
 	}
 	}
 
 
 	@Test
 	@Test
@@ -51,7 +50,7 @@ class CustomPagesConfigTests {
 	void indexWhenAuthenticatedWithPasswordThenRedirectsToOtt() throws Exception {
 	void indexWhenAuthenticatedWithPasswordThenRedirectsToOtt() throws Exception {
 		this.mvc.perform(get("/"))
 		this.mvc.perform(get("/"))
 			.andExpect(status().is3xxRedirection())
 			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/auth/ott?factor=ott"));
+			.andExpect(redirectedUrl("/auth/ott?factor.type=ott&factor.reason=missing"));
 	}
 	}
 
 
 }
 }

+ 52 - 6
servlet/spring-boot/java/authentication/mfa/formLogin+ott/src/test/java/example/DefaultConfigTests.java

@@ -1,16 +1,22 @@
 package example;
 package example;
 
 
+import java.time.Instant;
+
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
 import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
+import org.springframework.security.core.authority.FactorGrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MockMvc;
 
 
 import static org.springframework.security.core.authority.FactorGrantedAuthority.OTT_AUTHORITY;
 import static org.springframework.security.core.authority.FactorGrantedAuthority.OTT_AUTHORITY;
 import static org.springframework.security.core.authority.FactorGrantedAuthority.PASSWORD_AUTHORITY;
 import static org.springframework.security.core.authority.FactorGrantedAuthority.PASSWORD_AUTHORITY;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -25,9 +31,7 @@ class DefaultConfigTests {
 
 
 	@Test
 	@Test
 	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
 	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
-		this.mvc.perform(get("/"))
-			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/login"));
+		this.mvc.perform(get("/")).andExpect(status().is3xxRedirection()).andExpect(redirectedUrl("/login"));
 	}
 	}
 
 
 	@Test
 	@Test
@@ -35,7 +39,8 @@ class DefaultConfigTests {
 	void indexWhenAuthenticatedButNoFactorsThenRedirectsToLogin() throws Exception {
 	void indexWhenAuthenticatedButNoFactorsThenRedirectsToLogin() throws Exception {
 		this.mvc.perform(get("/"))
 		this.mvc.perform(get("/"))
 			.andExpect(status().is3xxRedirection())
 			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/login?factor=password"));
+			.andExpect(redirectedUrl(
+					"/login?factor.type=password&factor.type=ott&factor.reason=missing&factor.reason=missing"));
 	}
 	}
 
 
 	@Test
 	@Test
@@ -43,7 +48,7 @@ class DefaultConfigTests {
 	void indexWhenAuthenticatedWithX509ThenRedirectsToLogin() throws Exception {
 	void indexWhenAuthenticatedWithX509ThenRedirectsToLogin() throws Exception {
 		this.mvc.perform(get("/"))
 		this.mvc.perform(get("/"))
 			.andExpect(status().is3xxRedirection())
 			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/login?factor=password"));
+			.andExpect(redirectedUrl("/login?factor.type=password&factor.reason=missing"));
 	}
 	}
 
 
 	@Test
 	@Test
@@ -51,7 +56,48 @@ class DefaultConfigTests {
 	void indexWhenAuthenticatedWithPasswordThenRedirectsToOtt() throws Exception {
 	void indexWhenAuthenticatedWithPasswordThenRedirectsToOtt() throws Exception {
 		this.mvc.perform(get("/"))
 		this.mvc.perform(get("/"))
 			.andExpect(status().is3xxRedirection())
 			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/login?factor=ott"));
+			.andExpect(redirectedUrl("/login?factor.type=ott&factor.reason=missing"));
+	}
+
+	@Test
+	void profileWhenAuthenticatedWithPasswordThenRedirectsToOtt() throws Exception {
+		UserDetails user = User.withDefaultPasswordEncoder()
+			.username("user")
+			.authorities(FactorGrantedAuthority.fromAuthority(PASSWORD_AUTHORITY))
+			.build();
+		this.mvc.perform(get("/profile").with(user(user)))
+			.andExpect(status().is3xxRedirection())
+			.andExpect(redirectedUrl("/login?factor.type=ott&factor.reason=missing"));
+	}
+
+	@Test
+	void profileWhenAuthenticatedWithOttThenRedirectsToPassword() throws Exception {
+		UserDetails user = User.withDefaultPasswordEncoder()
+			.username("user")
+			.authorities(FactorGrantedAuthority.fromAuthority(OTT_AUTHORITY))
+			.build();
+		this.mvc.perform(get("/profile").with(user(user)))
+			.andExpect(status().is3xxRedirection())
+			.andExpect(redirectedUrl("/login?factor.type=password&factor.reason=missing"));
+	}
+
+	@Test
+	void profileWhenExpiredPasswordAuthorityThenRedirectsToPassword() throws Exception {
+		FactorGrantedAuthority expiredPassword = FactorGrantedAuthority.withAuthority(PASSWORD_AUTHORITY)
+			.issuedAt(Instant.now().minusSeconds(600))
+			.build();
+		FactorGrantedAuthority ott = FactorGrantedAuthority.fromAuthority(OTT_AUTHORITY);
+		UserDetails user = User.withDefaultPasswordEncoder().username("user").authorities(expiredPassword, ott).build();
+		this.mvc.perform(get("/profile").with(user(user)))
+			.andExpect(redirectedUrl("/login?factor.type=password&factor.reason=expired"));
+	}
+
+	@Test
+	void profileWhenAuthenticatedWithPasswordAndOttThenAllows() throws Exception {
+		FactorGrantedAuthority password = FactorGrantedAuthority.fromAuthority(PASSWORD_AUTHORITY);
+		FactorGrantedAuthority ott = FactorGrantedAuthority.fromAuthority(OTT_AUTHORITY);
+		UserDetails user = User.withDefaultPasswordEncoder().username("user").authorities(password, ott).build();
+		this.mvc.perform(get("/profile").with(user(user))).andExpect(status().isOk());
 	}
 	}
 
 
 }
 }

+ 0 - 65
servlet/spring-boot/java/authentication/mfa/formLogin+ott/src/test/java/example/ElevatedSecurityPageConfigTests.java

@@ -1,65 +0,0 @@
-package example;
-
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
-import org.springframework.security.test.context.support.WithMockUser;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.web.servlet.MockMvc;
-
-import static org.springframework.security.core.authority.FactorGrantedAuthority.OTT_AUTHORITY;
-import static org.springframework.security.core.authority.FactorGrantedAuthority.PASSWORD_AUTHORITY;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@SpringBootTest
-@AutoConfigureMockMvc
-@ActiveProfiles("elevated-security")
-class ElevatedSecurityPageConfigTests {
-
-	@Autowired
-	private MockMvc mvc;
-
-	@Test
-	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
-		this.mvc.perform(get("/"))
-			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/auth/password"));
-	}
-
-	@Test
-	@WithMockUser
-	void indexWhenAuthenticatedButNoFactorsThenAllows() throws Exception {
-		this.mvc.perform(get("/")).andExpect(status().isOk());
-	}
-
-	@Test
-	@WithMockUser(authorities = OTT_AUTHORITY)
-	void indexWhenAuthenticatedWithOttThenAllows() throws Exception {
-		this.mvc.perform(get("/")).andExpect(status().isOk());
-	}
-
-	@Test
-	@WithMockUser(authorities = PASSWORD_AUTHORITY)
-	void indexWhenAuthenticatedWithPasswordThenAllows() throws Exception {
-		this.mvc.perform(get("/")).andExpect(status().isOk());
-	}
-
-	@Test
-	@WithMockUser(authorities = PASSWORD_AUTHORITY)
-	void profileWhenAuthenticatedWithPasswordThenRedirectsToOtt() throws Exception {
-		this.mvc.perform(get("/profile"))
-			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/auth/ott?factor=ott"));
-	}
-
-	@Test
-	@WithMockUser(authorities = OTT_AUTHORITY)
-	void profileWhenAuthenticatedWithOttThenAllows() throws Exception {
-		this.mvc.perform(get("/profile")).andExpect(status().isOk());
-	}
-
-}

+ 2 - 4
servlet/spring-boot/java/authentication/mfa/x509+formLogin/src/test/java/example/MfaApplicationTests.java

@@ -42,9 +42,7 @@ class MfaApplicationTests {
 
 
 	@Test
 	@Test
 	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
 	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
-		this.mvc.perform(get("/"))
-			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/login"));
+		this.mvc.perform(get("/")).andExpect(status().is3xxRedirection()).andExpect(redirectedUrl("/login"));
 	}
 	}
 
 
 	@Test
 	@Test
@@ -58,7 +56,7 @@ class MfaApplicationTests {
 	void indexWhenAuthenticatedWithX509ThenRedirectsToLogin() throws Exception {
 	void indexWhenAuthenticatedWithX509ThenRedirectsToLogin() throws Exception {
 		this.mvc.perform(get("/"))
 		this.mvc.perform(get("/"))
 			.andExpect(status().is3xxRedirection())
 			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/login?factor=password"));
+			.andExpect(redirectedUrl("/login?factor.type=password&factor.reason=missing"));
 	}
 	}
 
 
 	@Test
 	@Test

+ 2 - 4
servlet/spring-boot/java/authentication/mfa/x509+webauthn/src/test/java/example/X509WebAuthnMfaApplicationTests.java

@@ -42,9 +42,7 @@ public class X509WebAuthnMfaApplicationTests {
 
 
 	@Test
 	@Test
 	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
 	void indexWhenUnauthenticatedThenRedirectsToLogin() throws Exception {
-		this.mvc.perform(get("/"))
-			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/login"));
+		this.mvc.perform(get("/")).andExpect(status().is3xxRedirection()).andExpect(redirectedUrl("/login"));
 	}
 	}
 
 
 	@Test
 	@Test
@@ -64,7 +62,7 @@ public class X509WebAuthnMfaApplicationTests {
 	void indexWhenAuthenticatedWithX509ThenRedirectsToWebAuthn() throws Exception {
 	void indexWhenAuthenticatedWithX509ThenRedirectsToWebAuthn() throws Exception {
 		this.mvc.perform(get("/"))
 		this.mvc.perform(get("/"))
 			.andExpect(status().is3xxRedirection())
 			.andExpect(status().is3xxRedirection())
-			.andExpect(redirectedUrl("http://localhost/login?factor=webauthn"));
+			.andExpect(redirectedUrl("/login?factor.type=webauthn&factor.reason=missing"));
 	}
 	}
 
 
 }
 }