Reputation: 123
I'm migrating a Spring XML configured application to Spring Java configured one. I'm new to Java configuration haven't found what the configuration should look like. I'm looking at their (Stormpath's) example app and it is XML based configuration.
Can anyone help me translate their application over to a Java configured application? I can get it from there if I have a base to work from.
Upvotes: 2
Views: 908
Reputation: 1162
The closest to a 1:1 mapping would be:
The servlet-context.xml
config would be translated to this:
/**
* Spring JavaConfig defining this Servlet's request-processing infrastructure
*/
@Configuration
@EnableWebMvc
@ComponentScan("com.stormpath.spring.security.example.controller")
public class ServletContextConfig {
@Bean
InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
}
root-context.xml
would be:
/**
* Spring JavaConfig defining shared resources visible to all other web components.
*/
@Configuration
public class RootContextConfig {
//Let's create the Stormpath client using the apiKey.properties file from the User's home folder.
@Bean
ClientFactory stormpathClient(CacheManager cacheManager) {
ClientFactory clientFactory = new ClientFactory();
clientFactory.setApiKeyFileLocation(System.getProperty("user.home") + File.separator + ".stormpath" + File.separator + "apiKey.properties");
clientFactory.setCacheManager(cacheManager);
return clientFactory;
}
//Let's instantiate the Stormpath Authentication Provider
@Bean
@Autowired
public StormpathAuthenticationProvider stormpathAuthenticationProvider(Client client, String applicationRestUrl) throws Exception {
StormpathAuthenticationProvider stormpathAuthenticationProvider = new StormpathAuthenticationProvider();
stormpathAuthenticationProvider.setClient(client);
stormpathAuthenticationProvider.setApplicationRestUrl(applicationRestUrl);
return stormpathAuthenticationProvider;
}
//Bean for CustomData Management
@Bean
CustomDataManager customDataManager() {
return new CustomDataManager();
}
@Bean
WildcardPermissionEvaluator permissionEvaluator() {
return new WildcardPermissionEvaluator();
}
@Bean
MethodSecurityExpressionHandler methodExpressionHandler(WildcardPermissionEvaluator permissionEvaluator) {
DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
methodSecurityExpressionHandler.setPermissionEvaluator(permissionEvaluator);
return methodSecurityExpressionHandler;
}
@Bean
DefaultWebSecurityExpressionHandler webExpressionHandler(WildcardPermissionEvaluator permissionEvaluator) {
DefaultWebSecurityExpressionHandler webSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
webSecurityExpressionHandler.setPermissionEvaluator(permissionEvaluator);
return webSecurityExpressionHandler;
}
@Bean
CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
Collection<Cache> caches = new ArrayList<Cache>();
caches.add(applicationCache().getObject());
caches.add(accountCache().getObject());
caches.add(groupCache().getObject());
caches.add(customDataCache().getObject());
cacheManager.setCaches(caches);
return cacheManager;
}
@Bean
ConcurrentMapCacheFactoryBean applicationCache(){
ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();
cacheFactoryBean.setName("com.stormpath.sdk.application.Application");
return cacheFactoryBean;
}
@Bean
ConcurrentMapCacheFactoryBean accountCache(){
ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();
cacheFactoryBean.setName("com.stormpath.sdk.account.Account");
return cacheFactoryBean;
}
@Bean
ConcurrentMapCacheFactoryBean groupCache(){
ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();
cacheFactoryBean.setName("com.stormpath.sdk.group.Group");
return cacheFactoryBean;
}
@Bean
ConcurrentMapCacheFactoryBean customDataCache(){
ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();
cacheFactoryBean.setName("com.stormpath.sdk.directory.CustomData");
return cacheFactoryBean;
}
}
and spring-security.xml
would be:
/**
* Spring JavaConfig defining Spring Security settings.
*/
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
//The HREF to the Stormpath Application
final String applicationRestUrl = "REPLACE_ME_WITH_YOUR_STORMPATH_APP_REST_URL";
//Let's specify some role here so we can later grant it access to restricted resources
final String roleA = "REPLACE_ME_WITH_YOUR_STORMPATH_GROUP_ALLOWED_TO_ACCESS_THIS_SECURED_RESOURCE";
@Autowired
private AuthenticationProvider stormpathAuthenticationProvider;
//The access control settings are defined here
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.and()
.authorizeRequests()
.accessDecisionManager(accessDecisionManager())
.antMatchers("/account/*").hasAuthority(roleA)
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/index.jsp")
.and()
.httpBasic()
.and()
.csrf().disable();
}
@Bean
public AuthenticationManager getAuthenticationManager() throws Exception {
return this.authenticationManagerBean();
}
//Let's add the StormpathAuthenticationProvider to the AuthenticationManager
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(stormpathAuthenticationProvider);
}
//Prevents the addition of the "ROLE_" prefix in authorities
@Bean
public WebExpressionVoter webExpressionVoter() {
WebExpressionVoter webExpressionVoter = new WebExpressionVoter();
return webExpressionVoter;
}
@Bean
public AffirmativeBased accessDecisionManager() {
AffirmativeBased affirmativeBased = new AffirmativeBased(Arrays.asList((AccessDecisionVoter) webExpressionVoter()));
affirmativeBased.setAllowIfAllAbstainDecisions(false);
return affirmativeBased;
}
@Bean
public String getApplicationRestUrl() {
return this.applicationRestUrl;
}
}
Then, in web.xml
you should do the following changes in order for the new JavaConfig to be picked up.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
to
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
and finally:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml,
/WEB-INF/spring-security.xml
</param-value>
</context-param>
for this:
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
com.stormpath.spring.security.example.config.ServletContextConfig,
com.stormpath.spring.security.example.config.RootContextConfig,
com.stormpath.spring.security.example.config.SpringSecurityConfig
</param-value>
</context-param>
You will also need to add this dependency in your project:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
You can see a fully-migrated working version in their java_config branch: https://github.com/stormpath/stormpath-spring-security-example/tree/java_config
Upvotes: 4