BAEL-9467 Update Spring Security article
- Migrated module to inherit from spring-5 and spring-security-5 - Relevant changes and fixes in code for upgraded spring-security module
This commit is contained in:
parent
da4e0f7bd7
commit
201c3a75c8
|
@ -2,7 +2,6 @@
|
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-security-rest</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>spring-security-rest</name>
|
||||
|
@ -10,9 +9,9 @@
|
|||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-spring-4</artifactId>
|
||||
<artifactId>parent-spring-5</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-spring-4</relativePath>
|
||||
<relativePath>../parent-spring-5</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -195,13 +194,6 @@
|
|||
</resources>
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>${maven-war-plugin.version}</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.cargo</groupId>
|
||||
<artifactId>cargo-maven2-plugin</artifactId>
|
||||
|
@ -282,17 +274,17 @@
|
|||
|
||||
<properties>
|
||||
<!-- Spring -->
|
||||
<org.springframework.security.version>4.2.6.RELEASE</org.springframework.security.version>
|
||||
<org.springframework.hateoas.version>0.21.0.RELEASE</org.springframework.hateoas.version>
|
||||
<org.springframework.security.version>5.1.0.RELEASE</org.springframework.security.version>
|
||||
<org.springframework.hateoas.version>0.25.0.RELEASE</org.springframework.hateoas.version>
|
||||
|
||||
<!-- various -->
|
||||
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
|
||||
<javax.validation.version>1.1.0.Final</javax.validation.version>
|
||||
<jstl.version>1.2</jstl.version>
|
||||
<jackson.version>2.8.5</jackson.version>
|
||||
<jackson.version>2.9.2</jackson.version>
|
||||
|
||||
<!-- util -->
|
||||
<guava.version>19.0</guava.version>
|
||||
<guava.version>26.0-jre</guava.version>
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
<commons-fileupload.version>1.3.2</commons-fileupload.version>
|
||||
|
||||
|
@ -303,7 +295,6 @@
|
|||
<springfox-swagger.version>2.9.2</springfox-swagger.version>
|
||||
|
||||
<!-- Maven plugins -->
|
||||
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import javax.validation.constraints.Size;
|
|||
|
||||
public class Foo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5422285893276747592L;
|
||||
|
||||
private long id;
|
||||
|
||||
@Size(min = 5, max = 14)
|
||||
|
|
|
@ -11,8 +11,10 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationSu
|
|||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||
import org.springframework.security.web.savedrequest.RequestCache;
|
||||
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@Component
|
||||
public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
|
||||
|
||||
private RequestCache requestCache = new HttpSessionRequestCache();
|
||||
|
@ -33,11 +35,6 @@ public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAu
|
|||
}
|
||||
|
||||
clearAuthenticationAttributes(request);
|
||||
|
||||
// Use the DefaultSavedRequest URL
|
||||
// final String targetUrl = savedRequest.getRedirectUrl();
|
||||
// logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
|
||||
// getRedirectStrategy().sendRedirect(request, response, targetUrl);
|
||||
}
|
||||
|
||||
public void setRequestCache(final RequestCache requestCache) {
|
||||
|
|
|
@ -16,7 +16,11 @@ import org.springframework.stereotype.Component;
|
|||
public final class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException {
|
||||
public void commence(
|
||||
final HttpServletRequest request,
|
||||
final HttpServletResponse response,
|
||||
final AuthenticationException authException) throws IOException {
|
||||
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,16 +2,9 @@ package org.baeldung.spring;
|
|||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
public class ClientWebConfig extends WebMvcConfigurerAdapter {
|
||||
|
||||
public ClientWebConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public class ClientWebConfig implements WebMvcConfigurer {
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.baeldung.spring;
|
||||
|
||||
import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.baeldung.security.RestAuthenticationEntryPoint;
|
||||
import org.baeldung.web.error.CustomAccessDeniedHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -12,6 +13,8 @@ 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;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||
|
||||
@Configuration
|
||||
|
@ -20,35 +23,41 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
|
|||
@ComponentScan("org.baeldung.security")
|
||||
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder encoder;
|
||||
|
||||
@Autowired
|
||||
private CustomAccessDeniedHandler accessDeniedHandler;
|
||||
|
||||
// @Autowired
|
||||
// private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
|
||||
@Autowired
|
||||
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
|
||||
|
||||
// @Autowired
|
||||
// private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler;
|
||||
@Autowired
|
||||
private MySavedRequestAwareAuthenticationSuccessHandler mySuccessHandler;
|
||||
|
||||
private SimpleUrlAuthenticationFailureHandler myFailureHandler = new SimpleUrlAuthenticationFailureHandler();
|
||||
|
||||
public SecurityJavaConfig() {
|
||||
super();
|
||||
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication().withUser("temporary").password("temporary").roles("ADMIN").and().withUser("user").password("userPass").roles("USER");
|
||||
auth.inMemoryAuthentication()
|
||||
.withUser("admin").password(encoder.encode("adminPass")).roles("ADMIN")
|
||||
.and()
|
||||
.withUser("user").password(encoder.encode("userPass")).roles("USER");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final HttpSecurity http) throws Exception {// @formatter:off
|
||||
http
|
||||
.csrf().disable()
|
||||
protected void configure(final HttpSecurity http) throws Exception {
|
||||
http.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.and()
|
||||
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
|
||||
// .authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||
.exceptionHandling()
|
||||
.accessDeniedHandler(accessDeniedHandler)
|
||||
.authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/api/csrfAttacker*").permitAll()
|
||||
|
@ -57,22 +66,18 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
|||
.antMatchers("/api/async/**").permitAll()
|
||||
.antMatchers("/api/admin/**").hasRole("ADMIN")
|
||||
.and()
|
||||
.formLogin()
|
||||
.successHandler(mySuccessHandler)
|
||||
.failureHandler(myFailureHandler)
|
||||
.and()
|
||||
.httpBasic()
|
||||
// .and()
|
||||
// .successHandler(authenticationSuccessHandler)
|
||||
// .failureHandler(new SimpleUrlAuthenticationFailureHandler())
|
||||
.and()
|
||||
.logout();
|
||||
} // @formatter:on
|
||||
|
||||
@Bean
|
||||
public MySavedRequestAwareAuthenticationSuccessHandler mySuccessHandler() {
|
||||
return new MySavedRequestAwareAuthenticationSuccessHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleUrlAuthenticationFailureHandler myFailureHandler() {
|
||||
return new SimpleUrlAuthenticationFailureHandler();
|
||||
public PasswordEncoder encoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
}
|
|
@ -24,8 +24,19 @@ public class SwaggerConfig {
|
|||
|
||||
@Bean
|
||||
public Docket api() {
|
||||
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.basePackage("org.baeldung.web.controller")).paths(PathSelectors.ant("/foos/*")).build().apiInfo(apiInfo()).useDefaultResponseMessages(false)
|
||||
.globalResponseMessage(RequestMethod.GET, newArrayList(new ResponseMessageBuilder().code(500).message("500 message").responseModel(new ModelRef("Error")).build(), new ResponseMessageBuilder().code(403).message("Forbidden!!!!!").build()));
|
||||
return new Docket(DocumentationType.SWAGGER_2).select()
|
||||
.apis(RequestHandlerSelectors.basePackage("org.baeldung.web.controller"))
|
||||
.paths(PathSelectors.ant("/foos/*"))
|
||||
.build()
|
||||
.apiInfo(apiInfo())
|
||||
.useDefaultResponseMessages(false)
|
||||
.globalResponseMessage(RequestMethod.GET, newArrayList(new ResponseMessageBuilder().code(500)
|
||||
.message("500 message")
|
||||
.responseModel(new ModelRef("Error"))
|
||||
.build(),
|
||||
new ResponseMessageBuilder().code(403)
|
||||
.message("Forbidden!!!!!")
|
||||
.build()));
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo() {
|
||||
|
|
|
@ -8,18 +8,14 @@ import org.springframework.web.servlet.ViewResolver;
|
|||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan("org.baeldung.web")
|
||||
@EnableWebMvc
|
||||
@EnableAsync
|
||||
public class WebConfig extends WebMvcConfigurerAdapter {
|
||||
|
||||
public WebConfig() {
|
||||
super();
|
||||
}
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
|
||||
|
@ -38,7 +34,6 @@ public class WebConfig extends WebMvcConfigurerAdapter {
|
|||
|
||||
@Override
|
||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
super.addViewControllers(registry);
|
||||
registry.addViewController("/csrfAttacker.html");
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ public class AsyncController {
|
|||
@RequestMapping(method = RequestMethod.GET, value = "/async")
|
||||
@ResponseBody
|
||||
public Object standardProcessing() throws Exception {
|
||||
log.info("Outside the @Async logic - before the async call: " + SecurityContextHolder.getContext().getAuthentication().getPrincipal());
|
||||
log.info("Outside the @Async logic - before the async call: {}", SecurityContextHolder.getContext().getAuthentication().getPrincipal());
|
||||
asyncService.asyncCall();
|
||||
log.info("Inside the @Async logic - after the async call: " + SecurityContextHolder.getContext().getAuthentication().getPrincipal());
|
||||
log.info("Inside the @Async logic - after the async call: {}", SecurityContextHolder.getContext().getAuthentication().getPrincipal());
|
||||
return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public class CustomerController {
|
|||
}
|
||||
|
||||
Link link =linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customerId)).withSelfRel();
|
||||
Resources<Order> result = new Resources<Order>(orders,link);
|
||||
Resources<Order> result = new Resources<>(orders,link);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class CustomerController {
|
|||
}
|
||||
|
||||
Link link =linkTo(CustomerController.class).withSelfRel();
|
||||
Resources<Customer> result = new Resources<Customer>(allCustomers,link);
|
||||
Resources<Customer> result = new Resources<>(allCustomers,link);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@ import java.util.List;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.baeldung.persistence.model.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;
|
||||
|
@ -25,17 +23,9 @@ import com.google.common.collect.Lists;
|
|||
@RequestMapping(value = "/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) {
|
||||
|
@ -43,7 +33,6 @@ public class FooController {
|
|||
}
|
||||
|
||||
// read - multiple
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public List<Foo> findAll() {
|
||||
|
|
|
@ -17,18 +17,18 @@ public class AsyncServiceImpl implements AsyncService {
|
|||
@Async
|
||||
@Override
|
||||
public void asyncCall() {
|
||||
log.info("Inside the @Async logic: " + SecurityContextHolder.getContext().getAuthentication().getPrincipal());
|
||||
log.info("Inside the @Async logic: {}", SecurityContextHolder.getContext().getAuthentication().getPrincipal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Callable<Boolean> checkIfPrincipalPropagated() {
|
||||
Object before = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
log.info("Before new thread: " + before);
|
||||
log.info("Before new thread: {}", before);
|
||||
|
||||
return new Callable<Boolean>() {
|
||||
public Boolean call() throws Exception {
|
||||
Object after = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
log.info("New thread: " + after);
|
||||
log.info("New thread: {}", after);
|
||||
return before == after;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
|
||||
|
||||
<!-- Spring Security Configurations are managed in SecurityJavaConfig class -->
|
||||
<!--
|
||||
<http use-expressions="true" entry-point-ref="restAuthenticationEntryPoint">
|
||||
<intercept-url pattern="/admin/*" access="hasAnyRole('ROLE_ADMIN')"/>
|
||||
|
||||
|
@ -20,7 +22,7 @@
|
|||
authentication-failure-handler-ref="myFailureHandler" />
|
||||
|
||||
|
||||
<!-- <access-denied-handler error-page="/my-error-page" /> -->
|
||||
<access-denied-handler error-page="/my-error-page" />
|
||||
|
||||
<access-denied-handler ref="customAccessDeniedHandler" />
|
||||
|
||||
|
@ -44,5 +46,5 @@
|
|||
</authentication-manager>
|
||||
|
||||
<global-method-security pre-post-annotations="enabled"/>
|
||||
|
||||
-->
|
||||
</beans:beans>
|
Loading…
Reference in New Issue