/* * Copyright 2015-2016 EuregJUG. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package eu.euregjug.site.config; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.actuate.autoconfigure.ManagementServerProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.core.annotation.Order; import org.springframework.data.redis.connection.RedisConnectionFactory; 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.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore; /** * @author Michael J. Simons, 2015-12-27 */ @Configuration @Slf4j @EnableGlobalMethodSecurity(prePostEnabled = true) @SuppressWarnings({"squid:S1118"}) // This is not a utility class. It cannot have a private constructor. public class SecurityConfig { @Configuration @EnableAuthorizationServer @ConditionalOnBean(SecurityConfig.class) static class AuthorizationServerConfig { } @Configuration @Profile("cloud") @ConditionalOnBean(SecurityConfig.class) static class TokenStoreConfig { @Bean public TokenStore tokenStore(final RedisConnectionFactory redisConnectionFactory) { log.debug("Enabling RedisTokenStore"); return new RedisTokenStore(redisConnectionFactory); } } @Configuration @EnableResourceServer @ConditionalOnBean(SecurityConfig.class) @Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER) static class ResourceServerConfig extends ResourceServerConfigurerAdapter { /** * The part of the api that needs protection is secured by method * level security. So all here the http security is matched on the /api/** * endpoints but permits all access by default. Secured resources are * then blacklisted on method level. * <br> * We must also take care of the actuator endpoints. An alternative * would be excluding them by using * <pre>http.regexMatcher("/api/(?!.*(system)).*")</pre> as first matcher * but that would mean having to separate auth mechanism in place. * <br> * I prefer manually enabling the non sensitive ones. * * @param http * @throws Exception */ @Override public void configure(final HttpSecurity http) throws Exception { http .antMatcher("/api/**") .authorizeRequests() .regexMatchers("/api/system/(?:info|health|metrics)").permitAll() .antMatchers("/api/system/**").authenticated() .antMatchers("/api/**").permitAll() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .enableSessionUrlRewriting(false) .and() .csrf() .disable(); } } @Configuration @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) @ConditionalOnBean(SecurityConfig.class) protected static class ApplicationWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { @Override protected void configure(final HttpSecurity http) throws Exception { http .httpBasic() .and() .authorizeRequests() .antMatchers("/oauth/**").authenticated() .antMatchers("/**").permitAll() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .enableSessionUrlRewriting(false); } } }