move security content from spring-security-rest-full (#2731)
* move security content from spring-security-rest-full * swagger update
This commit is contained in:
committed by
Grzegorz Piwowarek
parent
e7252f61aa
commit
3ed7609758
@@ -8,7 +8,10 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com
|
||||
### Relevant Articles:
|
||||
- [Spring Security Remember Me](http://www.baeldung.com/spring-security-remember-me)
|
||||
- [Redirect to different pages after Login with Spring Security](http://www.baeldung.com/spring_redirect_after_login)
|
||||
|
||||
- [Changing Spring Model Parameters with Handler Interceptor](http://www.baeldung.com/spring-model-parameters-with-handler-interceptor)
|
||||
- [Introduction to Spring MVC HandlerInterceptor](http://www.baeldung.com/spring-mvc-handlerinterceptor)
|
||||
- [Using a Custom Spring MVC’s Handler Interceptor to Manage Sessions](http://www.baeldung.com/spring-mvc-custom-handler-interceptor)
|
||||
- [A Guide to CSRF Protection in Spring Security](http://www.baeldung.com/spring-security-csrf)
|
||||
|
||||
### Build the Project
|
||||
```
|
||||
|
||||
@@ -113,6 +113,40 @@
|
||||
<!-- <version>3.0.1</version> -->
|
||||
<!-- </dependency> -->
|
||||
|
||||
<!-- util -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson-databind.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -174,7 +208,8 @@
|
||||
<!-- util -->
|
||||
<guava.version>19.0</guava.version>
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
|
||||
<jackson-databind.version>2.9.1</jackson-databind.version>
|
||||
|
||||
<httpclient.version>4.5.2</httpclient.version>
|
||||
<httpcore.version>4.4.5</httpcore.version>
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package org.baeldung.spring;
|
||||
|
||||
import org.baeldung.web.interceptor.LoggerInterceptor;
|
||||
import org.baeldung.web.interceptor.SessionTimerInterceptor;
|
||||
import org.baeldung.web.interceptor.UserInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
@@ -11,6 +16,7 @@ import org.springframework.web.servlet.view.JstlView;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
@ComponentScan("org.baeldung.web.controller")
|
||||
public class MvcConfig extends WebMvcConfigurerAdapter {
|
||||
|
||||
public MvcConfig() {
|
||||
@@ -28,6 +34,7 @@ public class MvcConfig extends WebMvcConfigurerAdapter {
|
||||
registry.addViewController("/login.html");
|
||||
registry.addViewController("/homepage.html");
|
||||
registry.addViewController("/console.html");
|
||||
registry.addViewController("/csrfHome.html");
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -40,4 +47,11 @@ public class MvcConfig extends WebMvcConfigurerAdapter {
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(final InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new LoggerInterceptor());
|
||||
registry.addInterceptor(new UserInterceptor());
|
||||
registry.addInterceptor(new SessionTimerInterceptor());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.baeldung.web.controller;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
// to test csrf
|
||||
@Controller
|
||||
public class BankController {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@RequestMapping(value = "/transfer", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public int transfer(@RequestParam("accountNo") final int accountNo, @RequestParam("amount") final int amount) {
|
||||
logger.info("Transfer to {}", accountNo);
|
||||
return amount;
|
||||
}
|
||||
|
||||
// write - just for test
|
||||
@RequestMapping(value = "/transfer", method = RequestMethod.POST)
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public void create(@RequestParam("accountNo") final int accountNo, @RequestParam("amount") final int amount) {
|
||||
logger.info("Transfer to {}", accountNo);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.baeldung.web.controller;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.baeldung.web.dto.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value = "/auth/foos")
|
||||
public class FooController {
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public FooController() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
// read - single
|
||||
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public Foo findById(@PathVariable("id") final Long id, final UriComponentsBuilder uriBuilder, final HttpServletResponse response) {
|
||||
return new Foo(randomAlphabetic(6));
|
||||
}
|
||||
|
||||
// read - multiple
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public List<Foo> findAll() {
|
||||
return Arrays.asList(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
// write - just for test
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@ResponseBody
|
||||
public Foo create(@RequestBody final Foo foo) {
|
||||
return foo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.baeldung.web.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Foo implements Serializable {
|
||||
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public Foo() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Foo(final String name) {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Foo other = (Foo) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!name.equals(other.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("Foo [name=")
|
||||
.append(name)
|
||||
.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.baeldung.web.interceptor;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class LoggerInterceptor extends HandlerInterceptorAdapter {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(LoggerInterceptor.class);
|
||||
|
||||
/**
|
||||
* Executed before actual handler is executed
|
||||
**/
|
||||
@Override
|
||||
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception {
|
||||
log.info("[preHandle][" + request + "]" + "[" + request.getMethod() + "]" + request.getRequestURI() + getParameters(request));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed before after handler is executed
|
||||
**/
|
||||
@Override
|
||||
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView modelAndView) throws Exception {
|
||||
log.info("[postHandle][" + request + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed after complete request is finished
|
||||
**/
|
||||
@Override
|
||||
public void afterCompletion(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex) throws Exception {
|
||||
if (ex != null)
|
||||
ex.printStackTrace();
|
||||
log.info("[afterCompletion][" + request + "][exception: " + ex + "]");
|
||||
}
|
||||
|
||||
private String getParameters(final HttpServletRequest request) {
|
||||
final StringBuffer posted = new StringBuffer();
|
||||
final Enumeration<?> e = request.getParameterNames();
|
||||
if (e != null)
|
||||
posted.append("?");
|
||||
while (e != null && e.hasMoreElements()) {
|
||||
if (posted.length() > 1)
|
||||
posted.append("&");
|
||||
final String curr = (String) e.nextElement();
|
||||
posted.append(curr).append("=");
|
||||
if (curr.contains("password") || curr.contains("answer") || curr.contains("pwd")) {
|
||||
posted.append("*****");
|
||||
} else {
|
||||
posted.append(request.getParameter(curr));
|
||||
}
|
||||
}
|
||||
|
||||
final String ip = request.getHeader("X-FORWARDED-FOR");
|
||||
final String ipAddr = (ip == null) ? getRemoteAddr(request) : ip;
|
||||
if (!Strings.isNullOrEmpty(ipAddr))
|
||||
posted.append("&_psip=" + ipAddr);
|
||||
return posted.toString();
|
||||
}
|
||||
|
||||
private String getRemoteAddr(final HttpServletRequest request) {
|
||||
final String ipFromHeader = request.getHeader("X-FORWARDED-FOR");
|
||||
if (ipFromHeader != null && ipFromHeader.length() > 0) {
|
||||
log.debug("ip from proxy - X-FORWARDED-FOR : " + ipFromHeader);
|
||||
return ipFromHeader;
|
||||
}
|
||||
return request.getRemoteAddr();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
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.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
public class SessionTimerInterceptor extends HandlerInterceptorAdapter {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(SessionTimerInterceptor.class);
|
||||
|
||||
private static final long MAX_INACTIVE_SESSION_TIME = 5 * 10000;
|
||||
|
||||
@Autowired
|
||||
private HttpSession session;
|
||||
|
||||
/**
|
||||
* Executed before actual handler is executed
|
||||
**/
|
||||
@Override
|
||||
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception {
|
||||
log.info("Pre handle method - check handling start time");
|
||||
long startTime = System.currentTimeMillis();
|
||||
request.setAttribute("executionTime", startTime);
|
||||
if (UserInterceptor.isUserLogged()) {
|
||||
session = request.getSession();
|
||||
log.info("Time since last request in this session: {} ms", System.currentTimeMillis() - request.getSession().getLastAccessedTime());
|
||||
if (System.currentTimeMillis() - session.getLastAccessedTime() > MAX_INACTIVE_SESSION_TIME) {
|
||||
log.warn("Logging out, due to inactive session");
|
||||
SecurityContextHolder.clearContext();
|
||||
request.logout();
|
||||
response.sendRedirect("/spring-security-rest-full/logout");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed before after handler is executed
|
||||
**/
|
||||
@Override
|
||||
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView model) throws Exception {
|
||||
log.info("Post handle method - check execution time of handling");
|
||||
long startTime = (Long) request.getAttribute("executionTime");
|
||||
log.info("Execution time for handling the request was: {} ms", System.currentTimeMillis() - startTime);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.baeldung.web.interceptor;
|
||||
|
||||
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;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,4 +33,8 @@
|
||||
</authentication-provider>
|
||||
</authentication-manager>
|
||||
|
||||
<!-- <mvc:interceptors>
|
||||
<bean id="loggerInterceptor" class="org.baeldung.web.interceptor.LoggerInterceptor" />
|
||||
</mvc:interceptors> -->
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,15 @@
|
||||
<html>
|
||||
<head></head>
|
||||
|
||||
<body>
|
||||
<h1>CSRF test on Origin</h1>
|
||||
<a href="transfer?accountNo=1234&amount=100">Transfer Money to John</a>
|
||||
|
||||
<form action="transfer" method="POST">
|
||||
<label>Account Number</label> <input name="accountNo" type="number"/>
|
||||
<label>Amount</label> <input name="amount" type="number"/>
|
||||
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
|
||||
<input type="submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.baeldung.security.csrf;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import org.baeldung.web.dto.Foo;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.request.RequestPostProcessor;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
public abstract class CsrfAbstractIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private Filter springSecurityFilterChain;
|
||||
|
||||
MockMvc mvc;
|
||||
|
||||
//
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mvc = MockMvcBuilders.webAppContextSetup(context).addFilters(springSecurityFilterChain).build();
|
||||
}
|
||||
|
||||
RequestPostProcessor testUser() {
|
||||
return user("user1").password("user1Pass").roles("USER");
|
||||
}
|
||||
|
||||
RequestPostProcessor testAdmin() {
|
||||
return user("admin").password("adminPass").roles("USER", "ADMIN");
|
||||
}
|
||||
|
||||
String createFoo() throws JsonProcessingException {
|
||||
return new ObjectMapper().writeValueAsString(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.baeldung.security.csrf;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.baeldung.security.spring.SecurityWithoutCsrfConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class })
|
||||
public class CsrfDisabledIntegrationTest extends CsrfAbstractIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void givenNotAuth_whenAddFoo_thenUnauthorized() throws Exception {
|
||||
mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo())).andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAuth_whenAddFoo_thenCreated() throws Exception {
|
||||
mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo()).with(testUser())).andExpect(status().isCreated());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.baeldung.security.csrf;
|
||||
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.baeldung.security.spring.SecurityWithCsrfConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, MvcConfig.class })
|
||||
public class CsrfEnabledIntegrationTest extends CsrfAbstractIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void givenNoCsrf_whenAddFoo_thenForbidden() throws Exception {
|
||||
mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo()).with(testUser())).andExpect(status().isForbidden());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCsrf_whenAddFoo_thenCreated() throws Exception {
|
||||
mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo()).with(testUser()).with(csrf())).andExpect(status().isCreated());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.baeldung.security.spring;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
public SecurityWithCsrfConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
// java config
|
||||
|
||||
@Override
|
||||
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(final WebSecurity web) throws Exception {
|
||||
web.ignoring().antMatchers("/resources/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/auth/admin/*").hasAnyRole("ROLE_ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.httpBasic()
|
||||
.and()
|
||||
.headers().cacheControl().disable()
|
||||
;
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.baeldung.security.spring;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
public SecurityWithoutCsrfConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
// java config
|
||||
|
||||
@Override
|
||||
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(final WebSecurity web) throws Exception {
|
||||
web.ignoring().antMatchers("/resources/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/auth/admin/*").hasAnyRole("ROLE_ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.httpBasic()
|
||||
.and()
|
||||
.headers().cacheControl().disable()
|
||||
.and()
|
||||
.csrf().disable()
|
||||
;
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
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.security.spring.SecurityWithoutCsrfConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
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.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.web.context.WebApplicationContext;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class })
|
||||
public class LoggerInterceptorIntegrationTest {
|
||||
|
||||
@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("/login.html"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
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 javax.servlet.http.HttpSession;
|
||||
|
||||
import org.baeldung.security.spring.SecurityWithoutCsrfConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
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.web.context.WebApplicationContext;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class })
|
||||
@WithMockUser(username = "admin", roles = { "USER", "ADMIN" })
|
||||
public class SessionTimerInterceptorIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
WebApplicationContext wac;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* After execution of HTTP GET logs from interceptor will be displayed in
|
||||
* the console
|
||||
*/
|
||||
@Test
|
||||
public void testInterceptors() throws Exception {
|
||||
HttpSession session = mockMvc.perform(get("/auth/foos"))
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andReturn()
|
||||
.getRequest()
|
||||
.getSession();
|
||||
Thread.sleep(51000);
|
||||
mockMvc.perform(get("/auth/foos").session((MockHttpSession) session))
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
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.security.spring.SecurityWithoutCsrfConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
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.web.context.WebApplicationContext;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class })
|
||||
@WithMockUser(username = "admin", roles = { "USER", "ADMIN" })
|
||||
public class UserInterceptorIntegrationTest {
|
||||
|
||||
@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
|
||||
*/
|
||||
@Test
|
||||
public void testInterceptors() throws Exception {
|
||||
mockMvc.perform(get("/auth/foos"))
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user