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:
Dhawal Kapil 2018-10-16 23:22:04 +05:30
parent da4e0f7bd7
commit 201c3a75c8
13 changed files with 84 additions and 95 deletions

View File

@ -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>

View File

@ -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)

View File

@ -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) {

View File

@ -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");
}

View File

@ -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 {
}

View File

@ -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,59 +23,61 @@ 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()
.authorizeRequests()
.and()
.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()
// .successHandler(authenticationSuccessHandler)
// .failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and()
.logout();
} // @formatter:on
@Bean
public MySavedRequestAwareAuthenticationSuccessHandler mySuccessHandler() {
return new MySavedRequestAwareAuthenticationSuccessHandler();
protected void configure(final HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.and()
.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()
.formLogin()
.successHandler(mySuccessHandler)
.failureHandler(myFailureHandler)
.and()
.httpBasic()
.and()
.logout();
}
@Bean
public SimpleUrlAuthenticationFailureHandler myFailureHandler() {
return new SimpleUrlAuthenticationFailureHandler();
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}

View File

@ -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() {

View File

@ -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");
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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() {

View File

@ -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;
}
};

View File

@ -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>