1 package com.atlassian.asap.it;
2
3 import com.atlassian.asap.core.server.AuthenticationContext;
4 import com.atlassian.asap.core.server.springsecurity.BearerTokenAuthenticationProcessingFilter;
5 import com.atlassian.asap.core.server.springsecurity.IssuerAndSubjectWhitelistAsapAuthenticationProvider;
6 import com.atlassian.asap.core.validator.JwtValidator;
7 import com.atlassian.asap.core.validator.JwtValidatorImpl;
8 import org.eclipse.jetty.server.Server;
9 import org.eclipse.jetty.servlet.FilterHolder;
10 import org.eclipse.jetty.servlet.ServletContextHandler;
11 import org.eclipse.jetty.servlet.ServletHolder;
12 import org.junit.AfterClass;
13 import org.junit.BeforeClass;
14 import org.springframework.context.annotation.Bean;
15 import org.springframework.context.annotation.Configuration;
16 import org.springframework.security.authentication.AuthenticationProvider;
17 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
18 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
19 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
20 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
21 import org.springframework.security.core.authority.SimpleGrantedAuthority;
22 import org.springframework.security.core.context.SecurityContextHolder;
23 import org.springframework.security.web.AuthenticationEntryPoint;
24 import org.springframework.security.web.access.AccessDeniedHandlerImpl;
25 import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
26 import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
27 import org.springframework.web.bind.annotation.RequestMapping;
28 import org.springframework.web.bind.annotation.RestController;
29 import org.springframework.web.context.ContextLoaderListener;
30 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
31 import org.springframework.web.filter.DelegatingFilterProxy;
32 import org.springframework.web.servlet.DispatcherServlet;
33 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
34
35 import javax.servlet.DispatcherType;
36 import java.net.URI;
37 import java.util.Collections;
38 import java.util.EnumSet;
39
40 public class SpringSecurityIntegrationTest extends BaseIntegrationTest {
41 private static Server server;
42
43 @Override
44 protected URI getUrlForResourceName(String resourceName) {
45 return URI.create("http://localhost:9000/" + resourceName);
46 }
47
48 @BeforeClass
49 public static void startServer() throws Exception {
50 AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();
51 webApplicationContext.register(SecurityConfig.class, ResourceController.class);
52
53 ServletContextHandler servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
54 servletContext.addEventListener(new ContextLoaderListener(webApplicationContext));
55 servletContext.addFilter(new FilterHolder(new DelegatingFilterProxy("springSecurityFilterChain")), "/*",
56 EnumSet.allOf(DispatcherType.class));
57 servletContext.addServlet(new ServletHolder(new DispatcherServlet(webApplicationContext)), "/*");
58
59 server = new Server(9000);
60 server.setHandler(servletContext);
61 server.start();
62 }
63
64 @AfterClass
65 public static void stopServer() throws Exception {
66 server.stop();
67 server.destroy();
68 }
69
70 @Configuration
71 @EnableWebSecurity
72 @EnableWebMvc
73 public static class SecurityConfig extends WebSecurityConfigurerAdapter {
74 @Bean
75 public JwtValidator jwtValidator() {
76 return JwtValidatorImpl.createDefault(new AuthenticationContext(AUDIENCE, PUBLIC_KEY_PROVIDER));
77 }
78
79 private AuthenticationEntryPoint entryPoint() {
80 BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
81 entryPoint.setRealmName("ASAP Realm");
82 return entryPoint;
83 }
84
85 @Override
86 protected void configure(HttpSecurity http) throws Exception {
87 BearerTokenAuthenticationProcessingFilter filter = new BearerTokenAuthenticationProcessingFilter(authenticationManager());
88 http.addFilterBefore(filter, BasicAuthenticationFilter.class)
89 .authorizeRequests()
90 .antMatchers("/" + RESOURCE).hasAuthority("VALID_SUBJECT")
91 .and()
92 .exceptionHandling()
93 .accessDeniedHandler(new AccessDeniedHandlerImpl())
94 .authenticationEntryPoint(entryPoint());
95 }
96
97 @Override
98 public void configure(AuthenticationManagerBuilder auth) throws Exception {
99 auth.authenticationProvider(asapAuthenticationProvider(jwtValidator()));
100 }
101
102 @Bean
103 public AuthenticationProvider asapAuthenticationProvider(JwtValidator jwtValidator) {
104 return new IssuerAndSubjectWhitelistAsapAuthenticationProvider(jwtValidator,
105 Collections.singleton(ISSUER1),
106 Collections.singleton(ISSUER1),
107 Collections.singleton(new SimpleGrantedAuthority("VALID_SUBJECT")));
108 }
109 }
110
111 @RestController
112 public static class ResourceController {
113 @RequestMapping(RESOURCE)
114 public String serveResource() {
115 return "Protected resource, accessing as " + SecurityContextHolder.getContext().getAuthentication();
116 }
117 }
118 }