96
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. From 0 to Spring Security 4.0 Rob Winch @rob_winch

From 0 to Spring Security 4.0

Embed Size (px)

DESCRIPTION

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements. In this presentation Rob will start with an insecure application and incrementally Spring Security 4 to demonstrate how easily you can secure your application. Throughout the presentation, new features found in Spring Security 4 will be highlighted. Whether you are new to Spring Security or are wanting to learn what is new in Spring Security 4, this presentation is a must!

Citation preview

Page 1: From 0 to Spring Security 4.0

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

From 0 to Spring Security 4.0 Rob Winch

@rob_winch

Page 2: From 0 to Spring Security 4.0

Agenda

•  Introductions •  Hello Spring Security (Java Config) •  Custom Authentication •  Spring Data Integration •  Testing Support •  WebSocket Support •  White Hat Hacker

2

Page 3: From 0 to Spring Security 4.0

About Me

•  Open Source fanatic •  Spring Security & Spring

Project Lead •  Committer on Spring

Framework •  Co-author of Spring Security

3.1 book •  Twitter @rob_winch

3

Page 4: From 0 to Spring Security 4.0

What is Spring Security?

•  Comprehensive support for Authentication And Authorization •  Protection against common attacks •  Servlet API Integration •  Optional integration with Spring MVC •  Optional Spring Data Integration •  WebSocket Support

4

Page 5: From 0 to Spring Security 4.0

Demo

Unless otherwise indicated, these sl ides are © 2013-2014 Pivotal Software, Inc. and l icensed under a Creative Commons Attr ibution-NonCommercial l icense: http://creativecommons.org/l icenses/by-nc/3.0/

Message Application

SPRING SECURITY

Page 6: From 0 to Spring Security 4.0

Spring Security

Page 7: From 0 to Spring Security 4.0

web.xml

<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class> org.springframework.web.filter.DelegatingFilterProxy </filter-class></filter><filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern></filter-mapping>

Page 8: From 0 to Spring Security 4.0

Hello Java Configuration – Replaces web.xml

public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {// optionally override methods

}

Page 9: From 0 to Spring Security 4.0

Hello Java Configuration – WebSecurityConfig @Configuration@EnableWebMvcSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {...}

Page 10: From 0 to Spring Security 4.0

Hello Java Configuration – WebSecurityConfig @Autowired public void configureGlobal( AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication()

.withUser("admin”) .password("password”) .roles("ADMIN","USER") .and()

.withUser("user") .password("password") .roles("USER");}

Page 11: From 0 to Spring Security 4.0

Hello Java Configuration

Page 12: From 0 to Spring Security 4.0

Hello Java Configuration

Page 13: From 0 to Spring Security 4.0

Hello Java Configuration <div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

Page 14: From 0 to Spring Security 4.0

Hello Java Configuration <div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

public interface HttpServletRequest … { Principal getUserPrincipal(); ...}

Page 15: From 0 to Spring Security 4.0

Hello Java Configuration <div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

public interface Principal … { String getName(); ...}

Page 16: From 0 to Spring Security 4.0

Hello Java Configuration <div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p> </div></div>

Page 17: From 0 to Spring Security 4.0

Custom Log in Form

Page 18: From 0 to Spring Security 4.0

Java Configuration @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().and() .httpBasic();}

Page 19: From 0 to Spring Security 4.0

Java Configuration http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().and() .httpBasic();<http use-expressions="true"> <intercept-url pattern="/**" access="authenticated"/> <form-login /> <http-basic /></http>

Page 20: From 0 to Spring Security 4.0

http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login”) .permitAll() .and() .logout() .permitAll();

Java Configuration

Page 21: From 0 to Spring Security 4.0

http .authorizeRequests() .antMatchers("/resources/**”).permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login”) .permitAll() .and() .logout() .permitAll();

Java Configuration

Page 22: From 0 to Spring Security 4.0

<form th:action="@{/login}" method="post"> <label for="username">Username</label> <input type="text" id="username" name="username"/> <label for="password">Password</label> <input type="password" id="password" name="password"/> <button type="submit">Log in</button></form>

Java Configuration

Page 23: From 0 to Spring Security 4.0

Java Configuration <form th:action="@{/login}" method="post"> <label for="username">Username</label> <input type="text" id="username" name="username"/> <label for="password">Password</label> <input type="password" id="password" name="password"/> <button type="submit">Log in</button></form>

Page 24: From 0 to Spring Security 4.0

Java Configuration <form th:action="@{/login}" method="post"> <label for="username">Username</label> <input type="text" id="username" name="username"/> <label for="password">Password</label> <input type="password" id="password" name="password"/> <button type="submit">Log in</button></form>

http …. .formLogin() .loginPage("/login”)

Page 25: From 0 to Spring Security 4.0

Custom Authentication

Page 26: From 0 to Spring Security 4.0

public interface UserDetailsService { UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;}

Java Configuration – Custom Authentication

Page 27: From 0 to Spring Security 4.0

public interface UserDetails extends Serializable { Collection<? extends GrantedAuthority> getAuthorities(); String getPassword(); String getUsername(); boolean isAccountNonExpired(); boolean isAccountNonLocked(); boolean isCredentialsNonExpired(); boolean isEnabled();}

Java Configuration – Custom Authentication

Page 28: From 0 to Spring Security 4.0

@Entitypublic class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String firstName; private String lastName; private String email; private String password; ...}

Java Configuration – Custom Authentication

Page 29: From 0 to Spring Security 4.0

pubic class CustomUserDetails extends User implements UserDetails { public CustomUserDetails(User u) { super(user); } public Collection getAuthorities() { return AuthorityUtils.createAuthorityList("ROLE_USER"); } public String getUsername() { return getEmail(); } public boolean isEnabled() { return true; } ...

Java Configuration – Custom Authentication

Page 30: From 0 to Spring Security 4.0

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userRepository.findByEmail(username); if(user == null) { throw new UsernameNotFoundException(…); } return new CustomUserDetails(user);}

Java Configuration – Custom Authentication

Page 31: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication @Autowired public void configureGlobal( AuthenticationManagerBuilder auth, UserDetailsService userDetailsService) throws Exception { auth .userDetailsService(userDetailsService);}

Page 32: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication <div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

Page 33: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication <div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

public interface HttpServletRequest … { Principal getUserPrincipal(); ...}

Page 34: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication <div th:with="currentUser=${#httpServletRequest.userPrincipal?.name}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

public interface HttpServletRequest … { (Authentication) Principal getUserPrincipal(); ...}

Page 35: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication <div th:with="currentUser=${#httpServletRequest.userPrincipal?.principal}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

public interface Authentication … { Object getPrincipal(); ...}

Page 36: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication <div th:with="currentUser=${#httpServletRequest.userPrincipal?.principal}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

public interface Authentication … { (UserDetails) Object getPrincipal(); ...}

Page 37: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication <div th:with="currentUser=${#httpServletRequest.userPrincipal?.principal}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser}”> sample_user </p></div>

public interface Authentication … { (CustomUserDetails) Object getPrincipal(); ...}

Page 38: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication <div th:with="currentUser=${#httpServletRequest.userPrincipal?.principal}"> <div th:if="${currentUser != null}"> <form th:action="@{/logout}" method="post”> <input type="submit" value="Log out" /> </form> <p th:text="${currentUser.firstName}”> sample_user </p></div>

public class CustomUserDetails … { String getFirstName(); ...}

Page 39: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication @RequestMapping(method=RequestMethod.GET) public ModelAndView list() { SecurityContext ctx = SecurityContextHolder.getContext(); Authentication authentication = ctx.getAuthentication(); User custom = authentication == null ? null : (User) authentication.getPrincipal(); ...}

Page 40: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication

@RequestMapping(method=RequestMethod.GET) public ModelAndView list(Authentication authentication) { User custom = authentication == null ? null : (User) authentication.getPrincipal(); ...}

Page 41: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication @RequestMapping(method=RequestMethod.GET) public ModelAndView list( @AuthenticationPrincipal User currentUser) {...}

Page 42: From 0 to Spring Security 4.0

Java Configuration – Custom Authentication

@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented @AuthenticationPrincipal public @interface CurrentUser { }

Page 43: From 0 to Spring Security 4.0

@RequestMapping(method=RequestMethod.GET) public ModelAndView list( @CurrentUser User currentUser) { Iterable<Message> messages = messageRepository.findByToId(currentUser.getId()); ...}

Java Configuration – Custom Authentication

Page 44: From 0 to Spring Security 4.0

Spring Security / Spring Data SpEL Support

Page 45: From 0 to Spring Security 4.0

@Bean public SecurityEvaluationContextExtension securityEvaluationContextExtension() { return new SecurityEvaluationContextExtension();}

Spring Security / Spring Data

Page 46: From 0 to Spring Security 4.0

public interface MessageRepository extends CrudRepository<Message, Long> { @Query("select m from Message m where m.to.id = " + "?#{principal.id}”) Iterable<Message> findAllToCurrentUser();}

Spring Security / Spring Data

Page 47: From 0 to Spring Security 4.0

public interface MessageRepository extends CrudRepository<Message, Long> { @Query("select m from Message m where m.to.id = " + "?#{hasRole('ROLE_ADMIN') ? '%' : principal.id}”) Iterable<Message> findAll();}

Spring Security / Spring Data

Page 48: From 0 to Spring Security 4.0

Spring Security / Spring Data

Page 49: From 0 to Spring Security 4.0

@EnableAclSecurity public interface SecuredMessageRepository extends MessageRepository {}

In the year 2000….

Page 50: From 0 to Spring Security 4.0

Password Storage

Page 51: From 0 to Spring Security 4.0

Password Storage

auth .userDetailsService(userDetailsService) .passwordEncoder(new BCryptPasswordEncoder());

Page 52: From 0 to Spring Security 4.0

CSRF Protection

Page 53: From 0 to Spring Security 4.0

Demo

Unless otherwise indicated, these sl ides are © 2013-2014 Pivotal Software, Inc. and l icensed under a Creative Commons Attr ibution-NonCommercial l icense: http://creativecommons.org/l icenses/by-nc/3.0/

CSRF Protection

SPRING SECURITY

Page 54: From 0 to Spring Security 4.0

CSRF Protection

Page 55: From 0 to Spring Security 4.0

CSRF Protection

Page 56: From 0 to Spring Security 4.0

CSRF Protection

“When do I use CSRF protection?

Page 57: From 0 to Spring Security 4.0

CSRF Protection

“... but my application uses JSON

Page 58: From 0 to Spring Security 4.0

CSRF Protection

<form ... method="post" enctype="text/plain"> <input type='hidden' name=’{"summary":"Hi", … "ignore_me":"' value='test"}' /></form>

Page 59: From 0 to Spring Security 4.0

CSRF Protection

{ "summary": "Hi", "message": "New Message", "to": "[email protected]", "ignore_me": "=test"}

Page 60: From 0 to Spring Security 4.0

CSRF Protection

“… but my application is stateless

Page 61: From 0 to Spring Security 4.0

CSRF Protection

Page 62: From 0 to Spring Security 4.0

CSRF Protection

“…and I use a custom header for authentication and ignore cookies

Page 63: From 0 to Spring Security 4.0

CSRF Protection

•  Use proper HTTP Verbs

•  Configure CSRF Protection

•  Include the CSRF Token

Page 64: From 0 to Spring Security 4.0

CSRF Protection – Providing the Token

<form ... method="post"> ... <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/></form>

Page 65: From 0 to Spring Security 4.0

CSRF Protection – Providing the Token

<form ... method="post"> ... <sec:csrfInput /></form>

Page 66: From 0 to Spring Security 4.0

CSRF Protection – Providing the Token

<form:form … method="post”> ... </form:form>

Page 67: From 0 to Spring Security 4.0

CSRF Protection – Providing the Token

<form ... method="post"> ... <input type="hidden" name="_csrf" value="f81d4fae-…"/></form>

Page 68: From 0 to Spring Security 4.0

Security HTTP Response Headers

Page 69: From 0 to Spring Security 4.0

Demo

Unless otherwise indicated, these sl ides are © 2013-2014 Pivotal Software, Inc. and l icensed under a Creative Commons Attr ibution-NonCommercial l icense: http://creativecommons.org/l icenses/by-nc/3.0/

Click Jacking

SPRING SECURITY

Page 70: From 0 to Spring Security 4.0

Security HTTP Response Headers

Page 71: From 0 to Spring Security 4.0

Security HTTP Response Headers

Page 72: From 0 to Spring Security 4.0

Test Support

Page 73: From 0 to Spring Security 4.0

Testing Support

@Before public void setup() { Authentication auth = new TestingAuthenticationToken("user",”pass","ROLE_USER"); SecurityContext ctx = SecurityContextHolder.getContext(); ctx.setAuthentication(auth); SecurityContextHolder.setContext(ctx); }@After public void cleanup() { SecurityContextHolder.clearContext(); }

Page 74: From 0 to Spring Security 4.0

Testing Support

UserDetails user = ...List<GrantedAuthority> roles = AuthorityUtils.createAuthorityList("ROLE_USER");Authentication auth = new UsernamePasswordAuthenticationToken(user,”pass", roles);SecurityContext ctx = SecurityContextHolder.getContext();ctx.setAuthentication(auth);

Page 75: From 0 to Spring Security 4.0

Testing Support

User user = ...List<GrantedAuthority> roles = AuthorityUtils.createAuthorityList("ROLE_USER");Authentication auth = new UsernamePasswordAuthenticationToken(user,”pass", roles);SecurityContext ctx = SecurityContextHolder.getContext();ctx.setAuthentication(auth);

Page 76: From 0 to Spring Security 4.0

Testing Support

...@WithMockUser public class SecurityMethodTests { ...}

Page 77: From 0 to Spring Security 4.0

Testing Support

...public class SecurityMethodTests { @Test @WithMockUser public void findAllMessages() { ... }}

Page 78: From 0 to Spring Security 4.0

Testing Support

...public class SecurityMethodTests { @Test @WithMockUser(username="admin",roles="ADMIN”) public void findAllMessages() { repository.findAll(); } }

Page 79: From 0 to Spring Security 4.0

Testing Support

...public class SecurityMethodTests { @Test @WithUserDetails(”[email protected]") public void findAllMessages() { repository.findAll(); } }

Page 80: From 0 to Spring Security 4.0

Testing Support

@Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @WithSecurityContext(factory = WithCustomUserSecurityContextFactory.class) public @interface WithCustomUser { String email() default "[email protected]"; String firstName() default "Rob"; String lastName() default "Winch"; long id() default 0L;}

Page 81: From 0 to Spring Security 4.0

Testing Support

public class WithCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithCustomUser> { public SecurityContext createSecurityContext(WithCustomUser customUser) { User principal = new User(); principal.setEmail(customUser.email()); ... return ctx; }}

Page 82: From 0 to Spring Security 4.0

Testing Support

...public class SecurityMethodTests { @Test @WithCustomUser public void findAllMessages() { repository.findAll(); } }

Page 83: From 0 to Spring Security 4.0

Testing Support

...public class SecurityMethodTests { @Test @WithCustomUser(id=1,email=”[email protected]") public void findAllMessages() { repository.findAll(); } }

Page 84: From 0 to Spring Security 4.0

Testing Support

“…what about Spring Test MVC?

Page 85: From 0 to Spring Security 4.0

... public class SecurityMockMvcTests { @Before public void setup() { mvc = MockMvcBuilders .webAppContextSetup(context) .apply(springSecurity()) .build(); }

Testing Support

Page 86: From 0 to Spring Security 4.0

Testing Support

@Test @WithCustomUser public void inboxShowsOnlyTo() throws Exception { ...}

Page 87: From 0 to Spring Security 4.0

Testing Support

@Test @WithCustomUser(id=1,email=”[email protected]") public void inboxShowsOnlyTo() throws Exception { ...}

Page 88: From 0 to Spring Security 4.0

@Test @WithCustomUser public void compose() throws Exception { MockHttpServletRequestBuilder compose = post("/”) .param("summary", "Hello Luke”) .param("message", "This is my message”) .with(csrf()); mvc .perform(compose) .andExpect(status().is2xxSuccessful());}

Testing Support

Page 89: From 0 to Spring Security 4.0

WebSocket Security

Page 90: From 0 to Spring Security 4.0

Demo

Unless otherwise indicated, these sl ides are © 2013-2014 Pivotal Software, Inc. and l icensed under a Creative Commons Attr ibution-NonCommercial l icense: http://creativecommons.org/l icenses/by-nc/3.0/

Web Socket Authorization

SPRING SECURITY

Page 91: From 0 to Spring Security 4.0

WebSocket Authorization

@MessageMapping("/im") /app/im

/queue/messages-user<id>

Client (Web Browser)

Browser

Page 92: From 0 to Spring Security 4.0

@Configurationpublic class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

WebSocket Authorization

Page 93: From 0 to Spring Security 4.0

protected void configure( MessageSecurityMetadataSourceRegistry messages) { messages .matchers(message("/topic/**","/queue/**")).denyAll() .anyMessage().hasRole("USER");}

WebSocket Authorization

Page 94: From 0 to Spring Security 4.0

// avoid processing outbound channelpublic void configureClientOutboundChannel( ChannelRegistration registration) {}

WebSocket Authorization

Page 95: From 0 to Spring Security 4.0

WebSocket Security Spring Session

Page 96: From 0 to Spring Security 4.0

Learn More. Stay Connected.

•  Source http://github.com/rwinch/spring-security-0-to-4.0 •  http://spring.io/spring-security •  Twitter: @rob_winch

Security for Microservices with Spring & OAuth2 – 4:30 Today