move security content from spring-security-rest-full (#2731)
* move security content from spring-security-rest-full * swagger update
This commit is contained in:
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());
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.ResponseStatus;
|
|||
|
||||
// to test csrf
|
||||
@Controller
|
||||
@RequestMapping(value = "/auth/")
|
||||
public class BankController {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -33,4 +33,8 @@
|
|||
</authentication-provider>
|
||||
</authentication-manager>
|
||||
|
||||
<!-- <mvc:interceptors>
|
||||
<bean id="loggerInterceptor" class="org.baeldung.web.interceptor.LoggerInterceptor" />
|
||||
</mvc:interceptors> -->
|
||||
|
||||
</beans:beans>
|
|
@ -5,7 +5,7 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock
|
|||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import org.baeldung.persistence.model.Foo;
|
||||
import org.baeldung.web.dto.Foo;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -14,15 +14,15 @@ 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.transaction.annotation.Transactional;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@Transactional
|
||||
public abstract class CsrfAbstractIntegrationTest {
|
||||
|
||||
@Autowired
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -5,13 +5,12 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
|||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.baeldung.security.spring.SecurityWithCsrfConfig;
|
||||
import org.baeldung.spring.PersistenceConfig;
|
||||
import org.baeldung.spring.WebConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, PersistenceConfig.class, WebConfig.class })
|
||||
@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, MvcConfig.class })
|
||||
public class CsrfEnabledIntegrationTest extends CsrfAbstractIntegrationTest {
|
||||
|
||||
@Test
|
|
@ -1,8 +1,5 @@
|
|||
package org.baeldung.security.spring;
|
||||
|
||||
import org.baeldung.web.error.CustomAccessDeniedHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
|
@ -12,14 +9,10 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
|||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CustomAccessDeniedHandler accessDeniedHandler;
|
||||
|
||||
public SecurityWithCsrfConfig() {
|
||||
super();
|
||||
}
|
||||
|
@ -46,8 +39,6 @@ public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter {
|
|||
.and()
|
||||
.httpBasic()
|
||||
.and()
|
||||
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
|
||||
.and()
|
||||
.headers().cacheControl().disable()
|
||||
;
|
||||
// @formatter:on
|
|
@ -1,8 +1,5 @@
|
|||
package org.baeldung.security.spring;
|
||||
|
||||
import org.baeldung.web.error.CustomAccessDeniedHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
|
@ -12,16 +9,10 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
|||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
//
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
// @ImportResource({ "classpath:webSecurityConfig.xml" })
|
||||
public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CustomAccessDeniedHandler accessDeniedHandler;
|
||||
|
||||
public SecurityWithoutCsrfConfig() {
|
||||
super();
|
||||
}
|
||||
|
@ -42,18 +33,15 @@ public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter {
|
|||
protected void configure(final HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/auth/admin/*").hasRole("ADMIN")
|
||||
.antMatchers("/auth/*").hasAnyRole("ADMIN","USER")
|
||||
.antMatchers("/*").permitAll()
|
||||
.antMatchers("/auth/admin/*").hasAnyRole("ROLE_ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.httpBasic()
|
||||
.and()
|
||||
// .exceptionHandling().accessDeniedPage("/my-error-page")
|
||||
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
|
||||
.and()
|
||||
.headers().cacheControl().disable()
|
||||
.and()
|
||||
.csrf().disable()
|
||||
;
|
||||
// @formatter:on
|
||||
}
|
|
@ -4,8 +4,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
|||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.baeldung.security.spring.SecurityWithoutCsrfConfig;
|
||||
import org.baeldung.spring.PersistenceConfig;
|
||||
import org.baeldung.spring.WebConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -16,13 +15,11 @@ 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 })
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class })
|
||||
public class LoggerInterceptorIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
|
@ -46,7 +43,8 @@ public class LoggerInterceptorIntegrationTest {
|
|||
*/
|
||||
@Test
|
||||
public void testInterceptors() throws Exception {
|
||||
mockMvc.perform(get("/graph.html")).andExpect(status().isOk());
|
||||
mockMvc.perform(get("/login.html"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
}
|
|
@ -6,8 +6,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.baeldung.security.spring.SecurityWithoutCsrfConfig;
|
||||
import org.baeldung.spring.PersistenceConfig;
|
||||
import org.baeldung.spring.WebConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -20,13 +19,11 @@ 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 })
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class })
|
||||
@WithMockUser(username = "admin", roles = { "USER", "ADMIN" })
|
||||
public class SessionTimerInterceptorIntegrationTest {
|
||||
|
||||
|
@ -47,9 +44,14 @@ public class SessionTimerInterceptorIntegrationTest {
|
|||
*/
|
||||
@Test
|
||||
public void testInterceptors() throws Exception {
|
||||
HttpSession session = mockMvc.perform(get("/auth/admin")).andExpect(status().is2xxSuccessful()).andReturn().getRequest().getSession();
|
||||
HttpSession session = mockMvc.perform(get("/auth/foos"))
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andReturn()
|
||||
.getRequest()
|
||||
.getSession();
|
||||
Thread.sleep(51000);
|
||||
mockMvc.perform(get("/auth/admin").session((MockHttpSession) session)).andExpect(status().is2xxSuccessful());
|
||||
mockMvc.perform(get("/auth/foos").session((MockHttpSession) session))
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
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.PersistenceConfig;
|
||||
import org.baeldung.spring.WebConfig;
|
||||
import org.baeldung.spring.MvcConfig;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -14,16 +16,11 @@ 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;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@Transactional
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.class })
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class })
|
||||
@WithMockUser(username = "admin", roles = { "USER", "ADMIN" })
|
||||
public class UserInterceptorIntegrationTest {
|
||||
|
||||
|
@ -46,7 +43,8 @@ public class UserInterceptorIntegrationTest {
|
|||
*/
|
||||
@Test
|
||||
public void testInterceptors() throws Exception {
|
||||
mockMvc.perform(get("/auth/admin")).andExpect(status().is2xxSuccessful());
|
||||
mockMvc.perform(get("/auth/foos"))
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[3.8.2.201610040608-RELEASE]]></pluginVersion>
|
||||
<pluginVersion><![CDATA[3.6.3.201411271034-RELEASE]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
<config>java:org.baeldung.security.spring.SecurityWithoutCsrfConfig</config>
|
||||
</configs>
|
||||
<autoconfigs>
|
||||
<config>src/main/webapp/WEB-INF/api-servlet.xml</config>
|
||||
<config>java:org.baeldung.spring.Application</config>
|
||||
<config>java:org.baeldung.security.spring.SecurityWithCsrfConfig</config>
|
||||
</autoconfigs>
|
||||
<configSets>
|
||||
</configSets>
|
||||
|
|
|
@ -8,12 +8,10 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||
The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
|
||||
|
||||
### Relevant Articles:
|
||||
- [Spring Security Expressions - hasRole Example](http://www.baeldung.com/spring-security-expressions-basic)
|
||||
- [REST Pagination in Spring](http://www.baeldung.com/2012/01/18/rest-pagination-in-spring/)
|
||||
- [HATEOAS for a Spring REST Service](http://www.baeldung.com/2011/11/13/rest-service-discoverability-with-spring-part-5/)
|
||||
- [REST API Discoverability and HATEOAS](http://www.baeldung.com/2011/11/06/restful-web-service-discoverability-part-4/)
|
||||
- [ETags for REST with Spring](http://www.baeldung.com/2013/01/11/etags-for-rest-with-spring/)
|
||||
- [Error Handling for REST with Spring 3](http://www.baeldung.com/2013/01/31/exception-handling-for-rest-with-spring-3-2/)
|
||||
- [Integration Testing with the Maven Cargo plugin](http://www.baeldung.com/2011/10/16/how-to-set-up-integration-testing-with-the-maven-cargo-plugin/)
|
||||
- [Introduction to Spring Data JPA](http://www.baeldung.com/2011/12/22/the-persistence-layer-with-spring-data-jpa/)
|
||||
- [Project Configuration with Spring](http://www.baeldung.com/2012/03/12/project-configuration-with-spring/)
|
||||
|
@ -24,11 +22,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
|
|||
- [Metrics for your Spring REST API](http://www.baeldung.com/spring-rest-api-metrics)
|
||||
- [REST Query Language with RSQL](http://www.baeldung.com/rest-api-search-language-rsql-fiql)
|
||||
- [Spring RestTemplate Tutorial](http://www.baeldung.com/rest-template)
|
||||
- [A Guide to CSRF Protection in Spring Security](http://www.baeldung.com/spring-security-csrf)
|
||||
- [Intro to Spring Security Expressions](http://www.baeldung.com/spring-security-expressions)
|
||||
- [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)
|
||||
- [Bootstrap a Web Application with Spring 4](http://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration)
|
||||
- [REST Query Language – Implementing OR Operation](http://www.baeldung.com/rest-api-query-search-or-operation)
|
||||
|
||||
|
|
|
@ -38,17 +38,6 @@
|
|||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Security -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring -->
|
||||
|
||||
<dependency>
|
||||
|
@ -220,10 +209,6 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency> -->
|
||||
<!-- <groupId>org.hamcrest</groupId> -->
|
||||
|
|
|
@ -10,7 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -36,6 +35,7 @@ public class FooService extends AbstractService<Foo> implements IFooService {
|
|||
|
||||
// custom methods
|
||||
|
||||
@Override
|
||||
public Foo retrieveByName(final String name) {
|
||||
return dao.retrieveByName(name);
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ public class FooService extends AbstractService<Foo> implements IFooService {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
public List<Foo> findAll() {
|
||||
return Lists.newArrayList(getDao().findAll());
|
||||
}
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
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;
|
||||
|
@ -35,15 +31,7 @@ public class WebConfig extends WebMvcConfigurerAdapter {
|
|||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
super.addViewControllers(registry);
|
||||
registry.addViewController("/graph.html");
|
||||
registry.addViewController("/csrfHome.html");
|
||||
registry.addViewController("/homepage.html");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(final InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new LoggerInterceptor());
|
||||
registry.addInterceptor(new UserInterceptor());
|
||||
registry.addInterceptor(new SessionTimerInterceptor());
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,6 @@ import org.baeldung.web.metric.IMetricService;
|
|||
import org.baeldung.web.util.LinkUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
@ -53,7 +52,6 @@ public class RootController {
|
|||
return metricService.getFullMetric();
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "/status-metric", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public Map getStatusMetric() {
|
||||
|
@ -70,16 +68,5 @@ public class RootController {
|
|||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/admin/x", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public String sampleAdminPage() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/my-error-page", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public String sampleErrorPage() {
|
||||
return "Error Occurred";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,13 +11,11 @@ import org.springframework.http.HttpHeaders;
|
|||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
//import org.springframework.security.access.AccessDeniedException;
|
||||
|
||||
@ControllerAdvice
|
||||
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
@ -55,12 +53,6 @@ public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionH
|
|||
return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
// 403
|
||||
@ExceptionHandler({ AccessDeniedException.class })
|
||||
public ResponseEntity<Object> handleAccessDeniedException(final Exception ex, final WebRequest request) {
|
||||
System.out.println("request" + request.getUserPrincipal());
|
||||
return new ResponseEntity<Object>("Access denied message here", new HttpHeaders(), HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
// 404
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/security
|
||||
http://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd"
|
||||
>
|
||||
|
||||
<http pattern="/securityNone" security="none"/>
|
||||
|
||||
<http use-expressions="true" >
|
||||
<intercept-url pattern="/admin/*" access="hasAnyRole('ROLE_ADMIN')"/>
|
||||
<intercept-url pattern="/**" access="isAuthenticated()"/>
|
||||
|
||||
<http-basic/>
|
||||
|
||||
<csrf disabled="true"/>
|
||||
|
||||
<!-- <access-denied-handler error-page="/my-error-page" /> -->
|
||||
|
||||
<access-denied-handler ref="customAccessDeniedHandler" />
|
||||
</http>
|
||||
|
||||
<authentication-manager>
|
||||
<authentication-provider>
|
||||
<user-service>
|
||||
<user name="user1" password="user1Pass" authorities="ROLE_USER"/>
|
||||
<user name="admin" password="adminPass" authorities="ROLE_ADMIN"/>
|
||||
</user-service>
|
||||
</authentication-provider>
|
||||
</authentication-manager>
|
||||
|
||||
<global-method-security pre-post-annotations="enabled"/>
|
||||
|
||||
<!-- <mvc:interceptors>
|
||||
<bean id="loggerInterceptor" class="org.baeldung.web.interceptor.LoggerInterceptor" />
|
||||
</mvc:interceptors> -->
|
||||
|
||||
</beans:beans>
|
|
@ -1,7 +1,6 @@
|
|||
package org.baeldung;
|
||||
|
||||
import org.baeldung.persistence.PersistenceTestSuite;
|
||||
import org.baeldung.security.SecurityTestSuite;
|
||||
import org.baeldung.web.LiveTestSuite;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
@ -10,7 +9,6 @@ import org.junit.runners.Suite;
|
|||
@Suite.SuiteClasses({
|
||||
// @formatter:off
|
||||
PersistenceTestSuite.class
|
||||
,SecurityTestSuite.class
|
||||
,LiveTestSuite.class
|
||||
}) //
|
||||
public class TestSuite {
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
package org.baeldung.security;
|
||||
|
||||
import org.baeldung.security.csrf.CsrfDisabledIntegrationTest;
|
||||
import org.baeldung.security.csrf.CsrfEnabledIntegrationTest;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({
|
||||
// @formatter:off
|
||||
CsrfEnabledIntegrationTest.class
|
||||
,CsrfDisabledIntegrationTest.class
|
||||
}) //
|
||||
public class SecurityTestSuite {
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package org.baeldung.security.csrf;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
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.PersistenceConfig;
|
||||
import org.baeldung.spring.WebConfig;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessMainPageWithoutAuthorization() throws Exception {
|
||||
mvc.perform(get("/graph.html").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessOtherPages() throws Exception {
|
||||
mvc.perform(get("/auth/transfer").contentType(MediaType.APPLICATION_JSON).param("accountNo", "1").param("amount", "100")).andExpect(status().isUnauthorized()); // without authorization
|
||||
mvc.perform(get("/auth/transfer").contentType(MediaType.APPLICATION_JSON).param("accountNo", "1").param("amount", "100").with(testUser())).andExpect(status().isOk()); // with authorization
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessAdminPage() throws Exception {
|
||||
mvc.perform(get("/auth/admin/x").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isUnauthorized()); // without authorization
|
||||
mvc.perform(get("/auth/admin/x").contentType(MediaType.APPLICATION_JSON).with(testAdmin())).andExpect(status().isOk()); // with authorization
|
||||
}
|
||||
|
||||
}
|
|
@ -14,3 +14,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
|
|||
- [An Intro to Spring HATEOAS](http://www.baeldung.com/spring-hateoas-tutorial)
|
||||
- [Spring Security Context Propagation with @Async](http://www.baeldung.com/spring-security-async-principal-propagation)
|
||||
- [Servlet 3 Async Support with Spring MVC and Spring Security](http://www.baeldung.com/spring-mvc-async-security)
|
||||
- [Intro to Spring Security Expressions](http://www.baeldung.com/spring-security-expressions)
|
||||
- [Spring Security Expressions - hasRole Example](http://www.baeldung.com/spring-security-expressions-basic)
|
||||
- [Error Handling for REST with Spring 3](http://www.baeldung.com/2013/01/31/exception-handling-for-rest-with-spring-3-2/)
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<artifactId>spring-security-config</artifactId>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Spring -->
|
||||
|
||||
<dependency>
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package org.baeldung.spring;
|
||||
|
||||
import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.baeldung.web.error.CustomAccessDeniedHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
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.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
@ -13,9 +16,13 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
|
|||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@ComponentScan("org.baeldung.security")
|
||||
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CustomAccessDeniedHandler accessDeniedHandler;
|
||||
|
||||
// @Autowired
|
||||
// private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
|
||||
|
||||
|
@ -40,14 +47,15 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
|||
.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.and()
|
||||
.exceptionHandling()
|
||||
// .authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
|
||||
// .authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/api/csrfAttacker*").permitAll()
|
||||
.antMatchers("/api/customer/**").permitAll()
|
||||
.antMatchers("/api/foos/**").authenticated()
|
||||
.antMatchers("/api/async/**").permitAll()
|
||||
.antMatchers("/api/admin/**").hasRole("ADMIN")
|
||||
.and()
|
||||
.httpBasic()
|
||||
// .and()
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
package org.baeldung.spring;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.builders.ResponseMessageBuilder;
|
||||
import springfox.documentation.schema.ModelRef;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
public class SwaggerConfig {
|
||||
|
@ -25,7 +29,7 @@ public class SwaggerConfig {
|
|||
}
|
||||
|
||||
private ApiInfo apiInfo() {
|
||||
ApiInfo apiInfo = new ApiInfo("My REST API", "Some custom description of API.", "API TOS", "Terms of service", "myeaddress@company.com", "License of API", "API license URL");
|
||||
ApiInfo apiInfo = new ApiInfo("My REST API", "Some custom description of API.", "API TOS", "Terms of service", new Contact("John Doe", "www.example.com", "myeaddress@company.com"), "License of API", "API license URL", Collections.emptyList());
|
||||
return apiInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package org.baeldung.web.controller;
|
||||
|
||||
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;
|
||||
|
||||
@Controller
|
||||
public class RootController {
|
||||
|
||||
public RootController() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@RequestMapping(value = "/admin/x", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public String sampleAdminPage() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/my-error-page", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public String sampleErrorPage() {
|
||||
return "Error Occurred";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package org.baeldung.web.error;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
//import org.springframework.security.access.AccessDeniedException;
|
||||
|
||||
@ControllerAdvice
|
||||
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
public RestResponseEntityExceptionHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
// 400
|
||||
|
||||
@ExceptionHandler({ DataIntegrityViolationException.class })
|
||||
public ResponseEntity<Object> handleBadRequest(final DataIntegrityViolationException ex, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleHttpMessageNotReadable(final HttpMessageNotReadableException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
// ex.getCause() instanceof JsonMappingException, JsonParseException // for additional information later on
|
||||
return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseEntity<Object> handleMethodArgumentNotValid(final MethodArgumentNotValidException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request);
|
||||
}
|
||||
|
||||
// 403
|
||||
@ExceptionHandler({ AccessDeniedException.class })
|
||||
public ResponseEntity<Object> handleAccessDeniedException(final Exception ex, final WebRequest request) {
|
||||
System.out.println("request" + request.getUserPrincipal());
|
||||
return new ResponseEntity<Object>("Access denied message here", new HttpHeaders(), HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
// 409
|
||||
|
||||
@ExceptionHandler({ InvalidDataAccessApiUsageException.class, DataAccessException.class })
|
||||
protected ResponseEntity<Object> handleConflict(final RuntimeException ex, final WebRequest request) {
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request);
|
||||
}
|
||||
|
||||
// 412
|
||||
|
||||
// 500
|
||||
|
||||
@ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class })
|
||||
/*500*/public ResponseEntity<Object> handleInternal(final RuntimeException ex, final WebRequest request) {
|
||||
logger.error("500 Status Code", ex);
|
||||
final String bodyOfResponse = "This should be application specific";
|
||||
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.baeldung.web.exception;
|
||||
|
||||
public final class MyResourceNotFoundException extends RuntimeException {
|
||||
|
||||
public MyResourceNotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MyResourceNotFoundException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public MyResourceNotFoundException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MyResourceNotFoundException(final Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,8 @@
|
|||
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
|
||||
|
||||
<http use-expressions="true" entry-point-ref="restAuthenticationEntryPoint">
|
||||
<intercept-url pattern="/admin/*" access="hasAnyRole('ROLE_ADMIN')"/>
|
||||
|
||||
<intercept-url pattern="/api/**" access="isAuthenticated()" />
|
||||
|
||||
<csrf disabled="true" />
|
||||
|
@ -17,6 +19,11 @@
|
|||
<form-login authentication-success-handler-ref="mySuccessHandler"
|
||||
authentication-failure-handler-ref="myFailureHandler" />
|
||||
|
||||
|
||||
<!-- <access-denied-handler error-page="/my-error-page" /> -->
|
||||
|
||||
<access-denied-handler ref="customAccessDeniedHandler" />
|
||||
|
||||
<logout />
|
||||
</http>
|
||||
|
||||
|
@ -30,8 +37,12 @@
|
|||
<user-service>
|
||||
<user name="temporary" password="temporary" authorities="ROLE_ADMIN" />
|
||||
<user name="user" password="userPass" authorities="ROLE_USER" />
|
||||
<user name="user1" password="user1Pass" authorities="ROLE_USER"/>
|
||||
<user name="admin" password="adminPass" authorities="ROLE_ADMIN"/>
|
||||
</user-service>
|
||||
</authentication-provider>
|
||||
</authentication-manager>
|
||||
|
||||
<global-method-security pre-post-annotations="enabled"/>
|
||||
|
||||
</beans:beans>
|
|
@ -17,17 +17,20 @@ import com.jayway.restassured.specification.RequestSpecification;
|
|||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||
public class FooLiveTest {
|
||||
private static final String URL_PREFIX = "http://localhost:8082/spring-security-rest";
|
||||
private static final String URL_PREFIX = "http://localhost:8080/spring-security-rest";
|
||||
// private FormAuthConfig formConfig = new FormAuthConfig(URL_PREFIX + "/login", "temporary", "temporary");
|
||||
|
||||
private String cookie;
|
||||
|
||||
private RequestSpecification givenAuth() {
|
||||
// return RestAssured.given().auth().form("user", "userPass", formConfig);
|
||||
if (cookie == null) {
|
||||
cookie = RestAssured.given().contentType("application/x-www-form-urlencoded").formParam("password", "userPass").formParam("username", "user").post(URL_PREFIX + "/login").getCookie("JSESSIONID");
|
||||
}
|
||||
return RestAssured.given().cookie("JSESSIONID", cookie);
|
||||
// if (cookie == null) {
|
||||
// cookie = RestAssured.given().contentType("application/x-www-form-urlencoded").formParam("password", "userPass").formParam("username", "user").post(URL_PREFIX + "/login").getCookie("JSESSIONID");
|
||||
// }
|
||||
// return RestAssured.given().cookie("JSESSIONID", cookie);
|
||||
return RestAssured.given()
|
||||
.auth()
|
||||
.basic("user", "userPass");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -8,7 +8,7 @@ import com.jayway.restassured.RestAssured;
|
|||
import com.jayway.restassured.response.Response;
|
||||
|
||||
public class SwaggerLiveTest {
|
||||
private static final String URL_PREFIX = "http://localhost:8082/spring-security-rest/api";
|
||||
private static final String URL_PREFIX = "http://localhost:8080/spring-security-rest/api";
|
||||
|
||||
@Test
|
||||
public void whenVerifySpringFoxIsWorking_thenOK() {
|
||||
|
|
Loading…
Reference in New Issue