From dca46bcee352f9fb7d60b49bcc6b175963c0b0ad Mon Sep 17 00:00:00 2001 From: maibin Date: Mon, 22 Aug 2016 22:33:53 -0700 Subject: [PATCH] Changing Spring MVC Model Parameters (#629) * Expression-Based Access Control PermitAll, hasRole, hasAnyRole etc. I modified classes regards to Security * Added test cases for Spring Security Expressions * Handler Interceptor - logging example * Test for logger interceptor * Removed conflicted part * UserInterceptor (adding user information to model) --- .../java/org/baeldung/spring/WebConfig.java | 10 ++- .../web/interceptor/UserInterceptor.java | 87 +++++++++++++++++++ .../web/interceptor/UserInterceptorTest.java | 53 +++++++++++ 3 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/UserInterceptor.java create mode 100644 spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/UserInterceptorTest.java diff --git a/spring-security-rest-full/src/main/java/org/baeldung/spring/WebConfig.java b/spring-security-rest-full/src/main/java/org/baeldung/spring/WebConfig.java index 5718a827c9..fa8bdddb4e 100644 --- a/spring-security-rest-full/src/main/java/org/baeldung/spring/WebConfig.java +++ b/spring-security-rest-full/src/main/java/org/baeldung/spring/WebConfig.java @@ -1,6 +1,7 @@ package org.baeldung.spring; import org.baeldung.web.interceptor.LoggerInterceptor; +import org.baeldung.web.interceptor.UserInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -37,8 +38,9 @@ public class WebConfig extends WebMvcConfigurerAdapter { registry.addViewController("/homepage.html"); } - @Override - public void addInterceptors(final InterceptorRegistry registry) { - registry.addInterceptor(new LoggerInterceptor()); - } + @Override + public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(new LoggerInterceptor()); + registry.addInterceptor(new UserInterceptor()); + } } \ No newline at end of file diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/UserInterceptor.java b/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/UserInterceptor.java new file mode 100644 index 0000000000..eb9769e646 --- /dev/null +++ b/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/UserInterceptor.java @@ -0,0 +1,87 @@ +package org.baeldung.web.interceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.SmartView; +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +public class UserInterceptor extends HandlerInterceptorAdapter { + + private static Logger log = LoggerFactory.getLogger(UserInterceptor.class); + + /** + * Executed before actual handler is executed + **/ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception { + if (isUserLogged()) { + addToModelUserDetails(request.getSession()); + } + return true; + } + + /** + * Executed before after handler is executed. If view is a redirect view, we don't need to execute postHandle + **/ + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) + throws Exception { + if (model != null && !isRedirectView(model)) { + if (isUserLogged()) { + addToModelUserDetails(model); + } + } + } + + /** + * Used before model is generated, based on session + * @param session + */ + private void addToModelUserDetails(HttpSession session) { + log.info("================= addToModelUserDetails ============================"); + String loggedUsername = SecurityContextHolder.getContext().getAuthentication().getName(); + session.setAttribute("username", loggedUsername); + log.info("user(" + loggedUsername + ") session : " + session); + log.info("================= addToModelUserDetails ============================"); + + } + + /** + * Used when model is available + * @param model + */ + private void addToModelUserDetails(ModelAndView model) { + log.info("================= addToModelUserDetails ============================"); + String loggedUsername = SecurityContextHolder.getContext().getAuthentication().getName(); + model.addObject("loggedUsername", loggedUsername); + log.trace("session : " + model.getModel()); + log.info("================= addToModelUserDetails ============================"); + + } + + public static boolean isRedirectView(ModelAndView mv) { + + String viewName = mv.getViewName(); + if (viewName.startsWith("redirect:/")) { + return true; + } + + View view = mv.getView(); + return (view != null && view instanceof SmartView && ((SmartView) view).isRedirectView()); + } + + public static boolean isUserLogged() { + try { + return !SecurityContextHolder.getContext().getAuthentication().getName().equals("anonymousUser"); + } catch (Exception e) { + return false; + } + } +} diff --git a/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/UserInterceptorTest.java b/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/UserInterceptorTest.java new file mode 100644 index 0000000000..9c27d80750 --- /dev/null +++ b/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/UserInterceptorTest.java @@ -0,0 +1,53 @@ +package org.baeldung.web.interceptor; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.baeldung.spring.PersistenceConfig; +import org.baeldung.spring.SecurityWithoutCsrfConfig; +import org.baeldung.spring.WebConfig; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.WebApplicationContext; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@Transactional +@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.class }) +@WithMockUser(username="admin",roles={"USER","ADMIN"}) +public class UserInterceptorTest { + + @Autowired + WebApplicationContext wac; + @Autowired + MockHttpSession session; + + private MockMvc mockMvc; + + @Before + public void setup() { + mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); + } + + /** + * After execution of HTTP GET logs from interceptor will be displayed in + * the console + * + * @throws Exception + */ + @Test + public void testInterceptors() throws Exception { + mockMvc.perform(get("/auth/admin")).andExpect(status().is2xxSuccessful()); + } + +}