diff --git a/pom.xml b/pom.xml index 0aafb323cb7b221576e0902714c3e3431ead9963..29d6d30689126e1123c73d461491d654b645ce75 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>edu.wisc.uwss</groupId> <artifactId>uw-spring-security</artifactId> - <version>0.5.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <name>UW Spring Security Parent</name> <description>Parent project for module to integrate Spring Security with UW authentication mechanism.</description> @@ -74,6 +74,11 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>edu.wisc.uwss</groupId> + <artifactId>uw-spring-security-config</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>jsr250-api</artifactId> diff --git a/uw-spring-security-config/pom.xml b/uw-spring-security-config/pom.xml index 4305b7de33f9dc0a51985925a31d07540907f66d..179bc42a6e03249ec516d7c10edbf7b94f19ee32 100644 --- a/uw-spring-security-config/pom.xml +++ b/uw-spring-security-config/pom.xml @@ -3,7 +3,7 @@ <parent> <groupId>edu.wisc.uwss</groupId> <artifactId>uw-spring-security</artifactId> - <version>0.5.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>uw-spring-security-config</artifactId> <name>UW Spring Security Configuration</name> diff --git a/uw-spring-security-core/pom.xml b/uw-spring-security-core/pom.xml index 2a214bc8bba0fb51eaa26e8fe48f310682fdc754..a0a026b8e0b6c3a71b86560580a0a6ca3669ceb2 100644 --- a/uw-spring-security-core/pom.xml +++ b/uw-spring-security-core/pom.xml @@ -3,7 +3,7 @@ <parent> <groupId>edu.wisc.uwss</groupId> <artifactId>uw-spring-security</artifactId> - <version>0.5.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>uw-spring-security-core</artifactId> <name>UW Spring Security Core</name> diff --git a/uw-spring-security-sample-war/pom.xml b/uw-spring-security-sample-war/pom.xml index b37f951a8668be4060c089bc6179886af6b4a6b2..ba97a3e3e7efee8e5d9b31cfb5bac72b2449ba46 100644 --- a/uw-spring-security-sample-war/pom.xml +++ b/uw-spring-security-sample-war/pom.xml @@ -3,7 +3,7 @@ <parent> <groupId>edu.wisc.uwss</groupId> <artifactId>uw-spring-security</artifactId> - <version>0.5.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>uw-spring-security-sample-war</artifactId> <name>UW Spring Security Sample War</name> diff --git a/uw-spring-security-sample-war/src/main/java/edu/wisc/uwss/sample/configuration/SampleWebSecurityConfiguration.java b/uw-spring-security-sample-war/src/main/java/edu/wisc/uwss/sample/configuration/SampleWebSecurityConfiguration.java index 7d80575218125a815dfa387f0370b007437f31e9..55c950ef75534a56235dde4c3a8a8880c2b7098a 100644 --- a/uw-spring-security-sample-war/src/main/java/edu/wisc/uwss/sample/configuration/SampleWebSecurityConfiguration.java +++ b/uw-spring-security-sample-war/src/main/java/edu/wisc/uwss/sample/configuration/SampleWebSecurityConfiguration.java @@ -12,6 +12,7 @@ import org.springframework.context.annotation.Profile; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import edu.wisc.uwss.configuration.HttpSecurityAmender; +import edu.wisc.uwss.web.ProfileRequiresAuthenticationHttpSecurityAmender; /** * This {@link Configuration} class for the "local-users" {@link Profile} provides an example of how one would @@ -38,11 +39,18 @@ public class SampleWebSecurityConfiguration { .antMatchers("/favicon.ico").permitAll() .antMatchers("/index.html").permitAll() .antMatchers("/lazy").permitAll() - .antMatchers("/required").authenticated() - .antMatchers("/profile").authenticated(); + .antMatchers("/required").authenticated(); } }; } + /** + * + * @return {@link HttpSecurityAmender} that requires auth on /profile + */ + @Bean + public HttpSecurityAmender profileAuthentication() { + return new ProfileRequiresAuthenticationHttpSecurityAmender(); + } } diff --git a/uw-spring-security-sample-war/src/main/java/edu/wisc/uwss/sample/web/TestController.java b/uw-spring-security-sample-war/src/main/java/edu/wisc/uwss/sample/web/TestController.java new file mode 100644 index 0000000000000000000000000000000000000000..737ed4c2c11c56f6372ed319195638b3aecccfcd --- /dev/null +++ b/uw-spring-security-sample-war/src/main/java/edu/wisc/uwss/sample/web/TestController.java @@ -0,0 +1,51 @@ +package edu.wisc.uwss.sample.web; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * {@link Controller} providing test cases regarding required vs lazy authentication. + * + * @author Nicholas Blair + */ +@Controller +public class TestController { + private static final Logger logger = LoggerFactory.getLogger(TestController.class); + /** + * This method is bound to a URL that requires authentication. + * + * @return the {@link #currentPrincipal()} + */ + @RequestMapping(value="/required", method= RequestMethod.GET) + public @ResponseBody Object authenticationRequired() { + return currentPrincipal(); + } + /** + * This method is bound to a URL that does not require authentication. + * + * @return the {@link #currentPrincipal()} + */ + @RequestMapping(value="/lazy", method=RequestMethod.GET) + public @ResponseBody Object authenticationNotRequired() { + return currentPrincipal(); + } + /** + * + * @return the current value for {@link Authentication#getPrincipal()}, or null + */ + protected Object currentPrincipal() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if(authentication == null) { + return null; + } + Object principal = authentication.getPrincipal(); + logger.debug("Authentication#getPrincipal observed {}", principal); + return principal; + } +} diff --git a/uw-spring-security-web/pom.xml b/uw-spring-security-web/pom.xml index c654b21248bbe874b27b6dc455bf94e6936dfb7c..0bb5c3c01469810d366bc882a4c79a5865fb69b5 100644 --- a/uw-spring-security-web/pom.xml +++ b/uw-spring-security-web/pom.xml @@ -3,7 +3,7 @@ <parent> <groupId>edu.wisc.uwss</groupId> <artifactId>uw-spring-security</artifactId> - <version>0.5.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>uw-spring-security-web</artifactId> <name>UW Spring Security Web</name> @@ -34,5 +34,10 @@ <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> + <dependency> + <groupId>edu.wisc.uwss</groupId> + <artifactId>uw-spring-security-config</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> </dependencies> </project> \ No newline at end of file diff --git a/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/ProfileController.java b/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/ProfileController.java index 1cfe2b7377a5e3a794fdc95714b3e0564daee566..8ec82337b02012c2f1a2400394b4dd9c3e7a422f 100644 --- a/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/ProfileController.java +++ b/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/ProfileController.java @@ -6,6 +6,7 @@ package edu.wisc.uwss.web; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -14,50 +15,21 @@ import org.springframework.web.bind.annotation.ResponseBody; /** * {@link Controller} useful for returning the current authenticated principal. - * + * + * @see ProfileRequiresAuthenticationHttpSecurityAmender * @author Nicholas Blair */ @Controller public class ProfileController { - - private static final Logger logger = LoggerFactory.getLogger(ProfileController.class); - /** - * This method is bound to a URL that requires authentication. - * - * @return the {@link #currentPrincipal()} - */ - @RequestMapping(value="/required", method=RequestMethod.GET) - public @ResponseBody Object authenticationRequired() { - return currentPrincipal(); - } - /** - * This method is bound to a URL that does not require authentication. - * - * @return the {@link #currentPrincipal()} - */ - @RequestMapping(value="/lazy", method=RequestMethod.GET) - public @ResponseBody Object authenticationNotRequired() { - return currentPrincipal(); - } /** - * - * @return the {@link #currentPrincipal()} + * This method intentionally avoids using {@link edu.wisc.uwss.UWUserDetails} for the argument and + * return type. Configurations exist that may result authentication not being required for this URL. + * + * @return the current authenticated principal */ @RequestMapping(value="/profile", method=RequestMethod.GET) - public @ResponseBody Object profile() { - return authenticationRequired(); - } - /** - * - * @return the current value for {@link Authentication#getPrincipal()}, or null - */ - protected Object currentPrincipal() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if(authentication == null) { - return null; - } - Object principal = authentication.getPrincipal(); - logger.debug("Authentication#getPrincipal observed {}", principal); + public @ResponseBody Object profile(@AuthenticationPrincipal Object principal) { return principal; } + } diff --git a/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/ProfileRequiresAuthenticationHttpSecurityAmender.java b/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/ProfileRequiresAuthenticationHttpSecurityAmender.java new file mode 100644 index 0000000000000000000000000000000000000000..9cb31da38dbb73f10384a6f9e0f8d4fdec77d24d --- /dev/null +++ b/uw-spring-security-web/src/main/java/edu/wisc/uwss/web/ProfileRequiresAuthenticationHttpSecurityAmender.java @@ -0,0 +1,25 @@ +package edu.wisc.uwss.web; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.stereotype.Component; + +import edu.wisc.uwss.configuration.HttpSecurityAmender; + +/** + * {@link HttpSecurityAmender} to make sure requests to /profile are authenticated. + * + * @see ProfileController + * @author Nicholas Blair + */ +public class ProfileRequiresAuthenticationHttpSecurityAmender implements HttpSecurityAmender { + static final Logger logger = LoggerFactory.getLogger(ProfileRequiresAuthenticationHttpSecurityAmender.class); + @Override + public void amend(HttpSecurity httpSecurity) throws Exception { + httpSecurity + .authorizeRequests() + .antMatchers("/profile").authenticated(); + logger.info("url '/profile' requires authentication"); + } +}