Reputation: 2007
I am trying fire up my app where I use spring data rest and spring security without Spring Boot. But I could make Spring Security works. All security beans are created but when I send a request it doesn't go through security filter chain, but directly to the controller method.
What might be wrong with my configuration? What have I missed?
@Configuration
@ComponentScan({"com.demo.gallery"})
@Import({MongoConfig.class})
public class AppConfig {
@Bean
public PropertySourcesPlaceholderConfigurer propertiesPropertySource() throws IOException {
PropertySourcesPlaceholderConfigurer source = new PropertySourcesPlaceholderConfigurer();
ResourcePropertySource propertySource = new ResourcePropertySource("classpath:application.properties");
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(propertySource);
source.setPropertySources(propertySources);
return source;
}
}
_
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{AppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
super.customizeRegistration(registration);
String userHome = System.getProperty("java.io.tmpdir");
File bannersDir = Paths.get(userHome, ".gallery/banners").toFile();
if (!bannersDir.exists()) {
if (!bannersDir.mkdirs()) {
throw new RuntimeException(String.format("Could create %s directory", bannersDir));
}
}
registration.setMultipartConfig(new MultipartConfigElement(userHome));
}
}
_
@EnableMongoRepositories(basePackages = "com.demo.gallery.persistence.repository")
public class MongoConfig extends AbstractMongoConfiguration {
private final String dbName;
private final String host;
private final int port;
public MongoConfig(@Value("${db.name}") String dbName,
@Value("${db.host}") String host,
@Value("${db.port}") int port) {
this.dbName = dbName;
this.host = host;
this.port = port;
}
@Override
protected String getDatabaseName() {
return dbName;
}
@Override
public MongoClient mongoClient() {
return new MongoClient(host, port);
}
@Override
protected Collection<String> getMappingBasePackages() {
return Collections.singleton("com.demo.gallery.persistence.model");
}
}
_
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AppUserRepository appUserRepository;
@Autowired
public SecurityConfig(AppUserRepository appUserRepository) {
this.appUserRepository = appUserRepository;
}
@Bean
public UserDetailsService userDetailsService() {
return email -> {
AppUser appUser = appUserRepository.findByEmail(email);
List<SimpleGrantedAuthority> authorities = appUser.getRoles().stream()
.map(Enum::name)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
return new User(appUser.getEmail(), appUser.getPassword(), authorities);
};
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
}
}
_
@Configuration
@Import({RepositoryRestMvcConfiguration.class, SecurityConfig.class})
public class WebConfig {
@Bean
public ResourceProcessor<Resource<Ad>> personProcessor() {
return new ResourceProcessor<Resource<Ad>>() {
@Override
public Resource<Ad> process(Resource<Ad> resource) {
String baseUri = BasicLinkBuilder.linkToCurrentMapping().toString();
Link bannerLink = new Link(new UriTemplate(baseUri + "/api/ads/banner/{id}")
.with("id", TemplateVariable.VariableType.PATH_VARIABLE), "banner")
.expand(Collections.singletonMap("id", resource.getContent().getId()));
resource.add(bannerLink);
return resource;
}
};
}
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer() {
return RepositoryRestConfigurer.withConfig(config -> {
config.setBasePath("/api");
});
}
}
Here is my build.gradle file:
plugins {
id 'war'
id 'net.ltgt.apt' version '0.10'
id "org.akhikhl.gretty" version "2.0.0"
}
repositories {
mavenCentral()
mavenLocal()
maven {
url 'https://repo.spring.io/libs-milestone'
}
}
gretty {
httpPort = 8558
contextPath = '/'
}
group 'com.demo'
version '1.0-SNAPSHOT'
ext {
lombockVersion = '1.16.20'
servletapiVersion = '4.0.0'
junitVersion = '4.12'
springTestVersion = '5.0.5.RELEASE'
springDataMongodbVersion = '2.1.0.M2'
springDataRestWebMvcVersion = '3.1.0.M2'
log4jVersion = '1.2.17'
slf4jVersion = '1.7.25'
logbackVersion = '1.2.3'
springSecurityVersion = '5.0.5.RELEASE'
}
dependencies {
compile "ch.qos.logback:logback-classic:${logbackVersion}"
compileOnly "org.projectlombok:lombok:${lombockVersion}"
apt "org.projectlombok:lombok:${lombockVersion}"
testCompile "junit:junit:${junitVersion}"
compile "org.springframework:spring-test:${springTestVersion}"
compile "org.springframework.data:spring-data-mongodb:${springDataMongodbVersion}"
compile "org.springframework.data:spring-data-rest-webmvc:${springDataRestWebMvcVersion}"
compile "org.springframework.security:spring-security-web:${springSecurityVersion}"
compile "org.springframework.security:spring-security-config:${springSecurityVersion}"
providedCompile "javax.servlet:javax.servlet-api:${servletapiVersion}"
}
Upvotes: 2
Views: 2233
Reputation: 335
Security filter registration seems to be missing.
You need to map the springSecurityFilterChain
You can easily do this by extending AbstractSecurityWebApplicationInitializer
and optionally overriding methods to customize the mapping.
Refer the below spring guide. Spring Security Java Config Preview: Web Security
Upvotes: 3