I'm using Spring 4.1.6 and Spring Security 4.0.1
I'm trying to convert my Spring and Spring Security XML configurations over to Java config and have been stuck with the exception below for quite a while now...
... 25 more
Caused by: java.lang.IllegalStateException: org.springframework.security.config.annotation.ObjectPostProcessor is a required bean. Ensure you have used #EnableWebSecurity and #Configuration
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$1.postProcess(WebSecurityConfigurerAdapter.java:78)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:171)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:290)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:67)
at csc.oceanlaw.config.SecurityConfig$$EnhancerBySpringCGLIB$$f2885b2e.init(<generated>)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:369)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:323)
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:105)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$80da63d.CGLIB$springSecurityFilterChain$0(<generated>)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$80da63d$$FastClassBySpringCGLIB$$2a6cb227.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$80da63d.springSecurityFilterChain(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 26 more
Here's my security config class:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity( prePostEnabled = true )
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String LOGIN_URL = "/login";
private static final String USER_BY_USERNAME_QUERY =
"select userName as username, password as password, 'true' as enabled " +
"from Users " +
"where (userName = ?)";
private static final String AUTHORITIES_BY_USERNAME_QUERY =
"select userName as username, role as authority " +
"from UserRoles " +
"where userName = ?";
private BasicDataSource dataSource;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// Intercept-url config...
.authorizeRequests()
.antMatchers("/*").permitAll()
.antMatchers("/_a/**").hasRole("ROLE_USER")
.antMatchers("/_/**").hasRole("ROLE_USER")
.and()
.requiresChannel()
.anyRequest().requiresSecure()
.and()
// Login form config...
.formLogin()
.loginPage(LOGIN_URL)
.loginProcessingUrl("/j_spring_security_check")
.failureUrl("/login?err=1")
.successHandler(customAuthenticationHandler())
.usernameParameter("j_username")
.passwordParameter("j_password")
.and()
// Logout handling...
.logout()
.addLogoutHandler(logoutFilter())
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout=1")
.and()
// Exception handling config...
.exceptionHandling()
.accessDeniedPage("/unauthorized")
.authenticationEntryPoint(ajaxAwareAuthenticationEntryPoint())
.and()
.csrf()
.disable();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.usersByUsernameQuery(USER_BY_USERNAME_QUERY)
.authoritiesByUsernameQuery(AUTHORITIES_BY_USERNAME_QUERY)
.passwordEncoder(md5PasswordEncoder())
.dataSource(getDataSource());
};
#Bean
public AuthenticationFilter customAuthenticationHandler() {
return new AuthenticationFilter();
}
#Bean
public SecurityLogoutHandler logoutFilter() {
return new SecurityLogoutHandler();
}
#Bean
public AjaxAwareAuthenticationEntryPoint ajaxAwareAuthenticationEntryPoint() {
return new AjaxAwareAuthenticationEntryPoint(LOGIN_URL);
}
#Bean
public Md5PasswordEncoder md5PasswordEncoder() {
return new Md5PasswordEncoder();
}
#Bean
public DefaultRolesPrefixPostProcessor defaultRolesPrefixPostProcessor() {
return new DefaultRolesPrefixPostProcessor();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
public BasicDataSource getDataSource() {
dataSource = new PersistenceConfig().dataSource();
return dataSource;
}
public void setDataSource(BasicDataSource dataSource) {
this.dataSource = dataSource;
}
}
It seems to point out the security config, however, it may be elsewhere in the config classes. So, below is the rest of config...
Main Spring config:
#Configuration
#ComponentScan(
basePackages = {
"myproject.model",
"myproject.web",
"myproject.dao",
"myproject.dao.jpa",
"myproject.config"
}
)
public class MainConfig {
/**
* Apache commons config bean.
* #return {#link CompositeConfiguration}
*/
#Bean(name="config")
public CompositeConfiguration compositeConfiguration() throws ConfigurationException {
PropertiesConfiguration textProps = null;
PropertiesConfiguration validationProps = null;
PropertiesConfiguration configProps = null;
textProps = new PropertiesConfiguration("olsdmText.properties");
textProps.setReloadingStrategy(new FileChangedReloadingStrategy());
validationProps = new PropertiesConfiguration("ValidationMessages.properties");
validationProps.setReloadingStrategy(new FileChangedReloadingStrategy());
configProps = new PropertiesConfiguration("olsdmSettings.properties");
configProps.setReloadingStrategy(new FileChangedReloadingStrategy());
CompositeConfiguration bean = new CompositeConfiguration();
bean.addConfiguration(textProps);
bean.addConfiguration(validationProps);
bean.addConfiguration(configProps);
bean.setDelimiterParsingDisabled(false);
bean.setListDelimiter('|');
return bean;
}
}
Spring MVC config:
#Configuration
#EnableWebMvc
public class WebMVCConfig extends WebMvcConfigurerAdapter {
#Inject org.apache.commons.configuration.Configuration config;
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/docs/**").addResourceLocations("/docs");
registry.addResourceHandler("/resources/**").addResourceLocations("/resources");
}
#Bean
public ViewResolver viewResolver() {
ContentNegotiatingViewResolver bean = new ContentNegotiatingViewResolver();
List<ViewResolver> viewResolvers = new ArrayList<ViewResolver>();
// Apache Tiles view resolver...
UrlBasedViewResolver tilesResolver = new UrlBasedViewResolver();
tilesResolver.setViewClass(TilesView.class);
tilesResolver.setOrder(0);
viewResolvers.add(tilesResolver);
// Default view resolver as a fallback. Allow view names to be served with just
// .jsp extension rather than a tiles id. This is primarily for AJAX calls that
// request a JSP resource...
InternalResourceViewResolver defaultResolver = new InternalResourceViewResolver();
defaultResolver.setPrefix(new String("/WEB-INF/views/"));
defaultResolver.setSuffix(new String(".jsp"));
defaultResolver.setOrder(1);
viewResolvers.add(defaultResolver);
bean.setViewResolvers(viewResolvers);
return bean;
}
/**
* Sets Apache Tiles XML config file location.
* #return {#link TilesConfigurer}
*/
#Bean
public TilesConfigurer tilesConfig() {
TilesConfigurer bean = new TilesConfigurer();
String[] definitions = {"/WEB-INF/views/tiles/config/tiles-config.xml"};
bean.setDefinitions(definitions);
return bean;
}
#Bean
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
#Bean
public PasswordGen passwordGen() {
return new PasswordGen();
}
#Bean
public Encrypt encrypt() {
return new Encrypt();
}
}
Datasource/JPA config:
#Configuration
#PropertySource("classpath:olsdmSettings.properties")
public class PersistenceConfig {
#Value("${jdbc.driverClassName}")
private String driverClassName;
#Value("${jdbc.databaseUrl}")
private String databaseUrl;
#Value("${jdbc.userName}")
private String userName;
#Value("${jdbc.passWord}")
private String passWord;
#Value("${jdbc.validationQuery}")
private String validationQuery;
#Value("${jdbc.testWhileIdle}")
private boolean testWhileIdle;
#Value("${jdbc.maxTotal}")
private int maxTotal;
#Value("${jdbc.maxIdle}")
private int maxIdle;
#Value("${jdbc.maxWailMillis}")
private int maxWailMillis;
/**
* Sets datasource configuration.
* #return {#link BasicDataSource}
*/
#Bean(name="dataSource")
public BasicDataSource dataSource() {
BasicDataSource bean = new BasicDataSource();
bean.setDriverClassName(driverClassName);
bean.setUrl(databaseUrl);
bean.setUsername(userName);
bean.setPassword(passWord);
bean.setValidationQuery(validationQuery);
bean.setTestWhileIdle(testWhileIdle);
bean.setMaxTotal(maxTotal);
bean.setMaxIdle(maxIdle);
bean.setMaxWaitMillis(maxWailMillis);
return bean;
}
/**
* Sets application {#link LocalContainerEntityManagerFactoryBean}
* #return {#link LocalContainerEntityManagerFactoryBean}
*/
#Bean
public LocalContainerEntityManagerFactoryBean emf() {
LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
bean.setDataSource(dataSource());
return bean;
}
/**
* Sets application {#link JpaTransactionManager}
* #return {#link JpaTransactionManager}
#Bean
public JpaTransactionManager jpaTransactionManager() {
JpaTransactionManager bean = new JpaTransactionManager();
bean.setEntityManagerFactory((EntityManagerFactory) emf());
return bean;
} */
#Bean
public PlatformTransactionManager transactionManager(){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
emf().getObject());
return transactionManager;
}
/**
* Sets application {#link Jaxb2Marshaller}
* #return {#link Jaxb2Marshaller}
*/
#Bean
public Jaxb2Marshaller jaxb2Marshaller() {
Jaxb2Marshaller bean = new Jaxb2Marshaller();
bean.setPackagesToScan(new String("myproject.model"));
return bean;
}
//To resolve ${} in #Value
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
WebApplicationIntializer implementation:
public class ApplicationInitializer implements WebApplicationInitializer {
private static final String CONFIG_LOCATION = "myproject.config";
private static final String MAPPING_URL = "/*";
#Override
public void onStartup(ServletContext container) throws ServletException {
WebApplicationContext context = getContext();
container.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic servlet =
container.addServlet("dispatcher", new DispatcherServlet(context));
servlet.setLoadOnStartup(1);
servlet.addMapping(MAPPING_URL);
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation(CONFIG_LOCATION);
return context;
}
}
Thanks a lot in advance for any help!
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
public static final String CHARACTER_ENCODING = "UTF-8";
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{
WebMVCConfig.class,
PersistenceConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/*","/*"};
}
#Override
protected javax.servlet.Filter[] getServletFilters() {
final CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding(CHARACTER_ENCODING);
encodingFilter.setForceEncoding(true);
final OpenSessionInViewFilter openSessionInViewFilter = new OpenSessionInViewFilter();
return new Filter[] { encodingFilter, openSessionInViewFilter };
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
registerListener(servletContext);
}
private void registerListener(ServletContext servletContext) {
RequestContextListener requestContextListener = new RequestContextListener();
servletContext.addListener(requestContextListener);
}}
needs to #Override Class[] getRootConfigClasses method.that will make you configurer class as a configurer bean.so you can use #EnableWebSecurity and #Configuration in you configclass code.
hope this can help!
like this:
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{
WebMVCConfig.class,
PersistenceConfig.class};
}
Related
I'm trying to build a Spring MVC application, using no XML. To load the application I am using a tomcat server. I want the homepage "home.html" to load, when I go to http://localhost:8080/.
I have followed many other spring mvc helloworld tutorials, but I can't see what I'm doing wrong. The webpage that loads, when I run the application is completely blank. When I inspect the html, it has an empty body. Any help is much appreciated.
Initialization class
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {ApplicationConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebMvcConfig.class};
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
DelegatingFilterProxy securityFilterChain = new DelegatingFilterProxy("springSecurityFilterChain");
return new Filter[] {characterEncodingFilter, securityFilterChain};
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setInitParameter("defaultHtmlEscape", "true");
registration.setInitParameter("spring.profiles.active", "default");
}
}
MVC configuration
#Configuration
class WebMvcConfig extends WebMvcConfigurationSupport {
private static final String MESSAGE_SOURCE = "/WEB-INF/i18n/messages";
private static final String VIEWS = "/WEB-INF/views/";
private static final String RESOURCES_LOCATION = "/resources/";
private static final String RESOURCES_HANDLER = RESOURCES_LOCATION + "**";
#Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping requestMappingHandlerMapping = super.requestMappingHandlerMapping();
requestMappingHandlerMapping.setUseSuffixPatternMatch(false);
requestMappingHandlerMapping.setUseTrailingSlashMatch(false);
return requestMappingHandlerMapping;
}
#Bean(name = "messageSource")
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename(MESSAGE_SOURCE);
messageSource.setCacheSeconds(5);
return messageSource;
}
#Bean
public ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix(VIEWS);
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new SpringSecurityDialect()); //TODO no using Spring security
templateEngine.addDialect(new Java8TimeDialect());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(templateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
}
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(RESOURCES_HANDLER).addResourceLocations(RESOURCES_LOCATION);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
* Handles favicon.ico requests assuring no <code>404 Not Found</code> error is returned.
*/
#Controller
static class FaviconController {
#RequestMapping("favicon.ico")
String favicon() {
return "forward:/resources/images/favicon.ico";
}
}
}
Home controller
#Controller
public class HomeController {
#RequestMapping(value = "/")
public String index() {
return "home";
}
}
Here is what my views look like
I am trying to implement Method Security using #PreAuthorize.
Spring Version: 4.2.3.Release
Spring Security: 4.0.3.Release
I have implemented a CustomPermissionEvaluator. I have noticed that it seems to be working fine except for 1 service where the hasPmerission is not called.
I know this because I get the a logging message from hasPermission / or in the erroneous case do not get the log:
public boolean hasPermission(Authentication authentication, Object o, Object o1) {
logger.info("Call to hasPermission with "+o+" and "+o1);
...
}
My Spring configuration is as follows:
#Configuration
#ComponentScan
public class RootConfiguration {
}
MVC Config
#EnableWebMvc
#Configuration
#ComponentScan({"OntoRais.*"})
#PropertySource("classpath:application.properties")
#EnableGlobalMethodSecurity(prePostEnabled=true)
public class MvcConfiguration extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver getViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigIn() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean(name="multipartResolver")
public CommonsMultipartResolver commonsMultipartResolver(){
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
commonsMultipartResolver.setDefaultEncoding("utf-8");
commonsMultipartResolver.setMaxUploadSize(50000000);
return commonsMultipartResolver;
}
}
Method Security Config:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
#ComponentScan
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
#Autowired
private CustomPermissionEvaluator permissionEvaluator;
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler handler
= new DefaultMethodSecurityExpressionHandler();
handler.setPermissionEvaluator(permissionEvaluator);
return handler;
}
public CustomPermissionEvaluator getPermissionEvaluator() {
return permissionEvaluator;
}
public void setPermissionEvaluator(CustomPermissionEvaluator permissionEvaluator) {
this.permissionEvaluator = permissionEvaluator;
}
}
Initializer:
#Configuration
#EnableSpringConfigured
public class MessageWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addListener(org.springframework.web.context.request.RequestContextListener.class);
super.onStartup(servletContext);
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { MvcConfiguration.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Filter[] getServletFilters() {
return new Filter[]{new HiddenHttpMethodFilter(),
new OpenEntityManagerInViewFilter(),
new DelegatingFilterProxy("springSecurityFilterChain")
};
}
}
Security Config:
#Configuration
#EnableWebSecurity
#ComponentScan
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
OntoRAISUserDetailsService ontoRAISUserDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
formLogin().
and().
logout().
and().
authorizeRequests().
antMatchers("/login").permitAll().
anyRequest().authenticated().
and().csrf().disable();
}
#Autowired
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(ontoRAISUserDetailsService);
auth.authenticationProvider(authenticationProvider());
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(ontoRAISUserDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
public OntoRAISUserDetailsService getOntoRAISUserDetailsService() {
return ontoRAISUserDetailsService;
}
public void setOntoRAISUserDetailsService(OntoRAISUserDetailsService ontoRAISUserDetailsService) {
this.ontoRAISUserDetailsService = ontoRAISUserDetailsService;
}
The Service in question:
#Service
public class StakeholderService {
#Autowired
private OntopManager om;
private static final Logger logger = LoggerFactory.getLogger("OntoRais");
public OntopManager getOm() {
return om;
}
public void setOm(OntopManager om) {
this.om = om;
}
#PreAuthorize("hasPermission(#stakeholderType, 'Create_StakeholderType')")
public void createStakeholderType(StakeholderType stakeholderType) {
try {
logger.info("Create stakeholder type in service layer");
List<OBDADataSource> sources = om.getObdaModel().getSources();
OBDAMappingAxiom mapping = om.getObdaModel().getMapping(new URI("genertatedURI"), MappingList.StakheholderType());
HashMap<String, String> values = new HashMap<>();
values.put("stakeholderName", stakeholderType.getLabel());
String query = ClassSQLHelper.generateSQLCreateSatement(mapping.getSourceQuery(), values);
SQLHelper.executeSQL(query, sources.get(0));
} catch (URISyntaxException e) {
logger.error(e.getMessage());
}
}
And the controller from which i call the service layer:
#Api(description = "Operations related to Stakeholders")
#RestController
public class StakeholderController {
#Autowired
private OntopManager om;
#Autowired
StakeholderService stakeholderService;
#Autowired
ProjectService projectService;
private static final Logger logger = LoggerFactory.getLogger("OntoRais");
...
/**
* Add a new Stakeholder Type
*
* #param stakeholdertype The new Stakeholder to be added.
* #return
*/
#ApiOperation(value = "Add new stakeholder type",
notes = "",
response = ResponseResource.class,
responseContainer = "Object")
#JsonView(Views.Details.class)
#RequestMapping(value = "/api/stakeholder/types", method = RequestMethod.POST)
public ResponseEntity<List<StakeholderType>> addStakeholderType(#RequestBody StakeholderType stakeholdertype) {
logger.info("Add Stakeholder type in controller");
getStakeholderService().createStakeholderType(stakeholdertype);
return getStakeholderTypes();
}
When calling api/stakeholder/types" with method = POST
This is my debug output:
Add Stakeholder type in controller
Create stakeholder type in service layer
INSERT INTO prefix_http_www_ontorais_de_stakeholdertype(id,stakeholderName) VALUES(DEFAULT,'TESTEWRTERETE');
As you can see the log from hasPermission is not present -> not called.
I can see that the method is called from my other method sercurity annotations in other service objects.
A similar Service which correctly invokes hasPermission as expected just for comparison:
#Service
public class OrganisationService {
private static final Logger logger = LoggerFactory.getLogger("OntoRais");
#Autowired
private OntopManager om;
#Autowired
private ProjectService projectService;
...
#PreAuthorize("hasAuthority('Add_Organisation')")
public void addOrganisation(Organisation organisation) {
List<OBDADataSource> sources = om.getObdaModel().getSources();
OBDAMappingAxiom mapping = null;
try {
mapping = om.getObdaModel().getMapping(new URI("genertatedURI"), MappingList.OrganisationMapping());
} catch (URISyntaxException e) {
e.printStackTrace();
}
HashMap<String, String> valueMap = new HashMap<>();
valueMap.put("organisationName", organisation.getName());
valueMap.put("organisationDescription", organisation.getDescription());
String query = ClassSQLHelper.generateSQLCreateSatement(mapping.getSourceQuery(), valueMap);
SQLHelper.executeSQL(query, sources.get(0));
}
Any hints on what I am doing wrong/missing/am blind for are very welcome thanks.
Benedict
Ok I found the problem, and a solution.
The Problem was that my CustomPermissionEvaluator depended on a method within the StakeholderService. Even though that method was not secured this resulted in the Spring not being able to proxy the object, therefore preventing any security checks.
Even though it is a bad idea to use a service layer object in the PermissionEvaluator, perhaps someone could elaborate on the exact implications, as i am definately not an expert in spring sercurity
I'm using Spring data and Hibernate to manage my database. I have for example repository class like this:
public interface NotificationHasUserRepository extends JpaRepository<NotificationHasUser, NotificationHasUserKeys> {
List<NotificationHasUser> findByPkUserAndIsReadFalse(User user);
#Modifying
#Query("UPDATE NotificationHasUser u SET u.isRead=true WHERE u.pk.user = ?1")
void setNotificationsAsRead(User user);
void deleteByPkUserAndPkNotification(User user, Notification notification);
List<NotificationHasUser> findByPkUser(User user);
#Query("select count(u)>0 from NotificationHasUser u WHERE u.pk.notification = ?1")
boolean existsByPkNotification(Notification notification);
}
I inject this class in my service class:
#Service
#Transactional
public class NotificationHasUserServicesImpl implements NotificationHasUserServices {
#Resource
private NotificationHasUserRepository notificationHasUserRepository;
#Override
public NotificationHasUser create(NotificationHasUser notificationHasUser) {
return notificationHasUserRepository.save(notificationHasUser);
}
#Override
public NotificationHasUser findById(NotificationHasUserKeys id) {
return notificationHasUserRepository.findOne(id);
}
#Override
public boolean exists(NotificationHasUserKeys id) {
return notificationHasUserRepository.exists(id);
}
#Override
public List<NotificationHasUser> findByPkUserAndIsReadFalse(User user) {
return notificationHasUserRepository.findByPkUserAndIsReadFalse(user);
}
#Override
public void setNotificationsAsRead(User user) {
notificationHasUserRepository.setNotificationsAsRead(user);
}
#Override
public List<NotificationHasUser> getNotifications(User user) {
return notificationHasUserRepository.findByPkUser(user);
}
#Override
public void deleteSelectedNotification(User user, Notification notification) {
notificationHasUserRepository.deleteByPkUserAndPkNotification(user, notification);
}
#Override
public boolean existsByPkNotification(Notification notification) {
return notificationHasUserRepository.existsByPkNotification(notification);
}
}
I'm using #Transaction on the service class but I receive exception when I call delete or update query
.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
If I add #Transcational on each method in repository class all work fine, is it not possible to add at service level?Thanks
This is my spring configuration:
#EnableAsync
#EnableWebMvc
#Configuration
#PropertySource(value = { "classpath:application.properties" })
#ComponentScan({ "com.*" })
#EnableTransactionManagement
#Import({ SecurityConfig.class, SpringMvcInitializer.class})
#EnableJpaRepositories("com.repository")
public class AppConfig extends WebMvcConfigurerAdapter implements AsyncConfigurer{
#Autowired
private Environment env;
#Autowired
private MyAsyncUncaughtExceptionHandler myAsyncUncaughtExceptionHandler;
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
// private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
/**
* This and the next methods are used to avoid exception while jackson mapping the entity, so fields are setted with null value
* unless use Hibernate.initialize
* #return
*/
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
//Registering Hibernate4Module to support lazy objects
mapper.registerModule(new Hibernate4Module());
messageConverter.setObjectMapper(mapper);
return messageConverter;
}
/**
* Used for spring security
* #return
*/
#Bean
public SpringSecurityDialect springSecurityDialect() {
SpringSecurityDialect dialect = new SpringSecurityDialect();
return dialect;
}
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//Here we add our custom-configured HttpMessageConverter
converters.add(jacksonMessageConverter());
super.configureMessageConverters(converters);
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
// properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
properties.put("hibernate.enable_lazy_load_no_trans",true);
return properties;
}
#Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
ds.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
ds.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
ds.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return ds;
}
#Bean
public ServletContextTemplateResolver TemplateResolver(){
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/templates/pages/");
resolver.setSuffix(".html");
resolver.setTemplateMode("LEGACYHTML5");
resolver.setCacheable(false);
return resolver;
/*ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
return resolver;*/
}
#Bean
public SpringTemplateEngine templateEngine(){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(TemplateResolver());
templateEngine.addDialect(springSecurityDialect());
return templateEngine;
}
#Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setOrder(1);
resolver.setViewNames(new String[]{"*", "js/*", "template/*"});
return resolver;
}
/**
* Register multipartResolver for file upload
* #return
*/
#Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver=new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
return resolver;
}
/**
* Allow use of bootstrap
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("/static/");
}
/**
* Allow use of JPA
*/
#Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan(env.
getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setJpaProperties(getHibernateProperties());
return entityManagerFactoryBean;
}
/**
* Async exception configuration
*/
#Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(10);
executor.initialize();
return executor;
}
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return myAsyncUncaughtExceptionHandler;
}
}
I have a serious problem... i'm trying to create login page with spring security integrated.
but, the problem is when i authenticate myself, spring security redirect me on the login page... and i really don't know why...
ApplicationConfig.java
#Configuration
#ComponentScan("id.mobiledashboard.*")
#EnableWebMvc
#EnableTransactionManagement
#PropertySource(value = "classpath:application.properties")
public class ApplicationConfig extends WebMvcConfigurerAdapter {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_HIBERNATE_HBM2DLL_AUTO = "hibernate.hbm2ddl.auto";
private static final String PROPERTY_NAME_HIBERNATE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setHibernateProperties(hibernateProperties());
return sessionFactoryBean;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_LAZY_LOAD_NO_TRANS, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_LAZY_LOAD_NO_TRANS));
//properties.put(PROPERTY_NAME_HIBERNATE_HBM2DLL_AUTO, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DLL_AUTO));
return properties;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping rmh = new RequestMappingHandlerMapping();
rmh.setUseTrailingSlashMatch(true);
return rmh;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**").addResourceLocations("/WEB-INF/assets/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
SecurityConfig.java
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new CustomAuthenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/assets/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/user/view")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.permitAll()
.and()
.csrf()
.and()
.exceptionHandling()
.accessDeniedPage("/403");
}
}
CustomAuthenticationProvider.java
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String name = authentication.getName();
System.out.println("################# before name " + name);
String password = authentication.getCredentials().toString();
System.out.println("################# before password " + password);
// Your custom authentication logic here
WsBackendMobileDashboard wsOrganizations = new WsBackendMobileDashboard();
WsBackendMobileDashboardPortType port = wsOrganizations.getSkkmigasMobileDashboardWsBackendMobileDashboardPort();
BindingProvider bp = (BindingProvider) port;
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, Constants.USERNAME_PROPERTY);
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, Constants.PASSWORD_PROPERTY);
ServiceReturn serviceReturn = port.loginBackEnd(name, password);
if (serviceReturn.getCode().equals("0")) {
System.out.println("################# success ");
Collection<GrantedAuthority> authorities = new HashSet<>();
GrantedAuthority authorityAdmin = new SimpleGrantedAuthority("ROLE_ADMIN");
authorities.add(authorityAdmin);
Authentication auth = new UsernamePasswordAuthenticationToken(name, password, authorities);
System.out.println("################# after name " + auth.getPrincipal().toString());
System.out.println("################# after password " + auth.getCredentials().toString());
System.out.println("");
return auth;
}
return null;
}
#Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
ApplicationInitializer.java
public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { ApplicationConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
the authentication seems no problem.
any ideas ? i'm almost despered...
Thank you in advance.
UPDATE
I must login twice before redirecting to defaultSuccessUrl.
Try adding this to your security configuration.
.antMatchers("/assets/**", "/login").permitAll()
Any changes?
I have a web application with 2 types of resources.
web pages
web services
I want to secure the web pages using one authentication provider (i.e. CAS) and the web services using another authentication provider (i.e. BASIC authentication).
I found a solution which could work here, but it uses XML, and I would prefer to not use XML configuration if possible.
Is there a Java Config solution to this?
Well it took a while to figure out how to do it...
Basically I split up my original security configuration class into 3 separate configuration classes.
This is basically how I did it...
The main security configuration...
#Configuration
#Import({WebPageSecurityConfig.class, WebServiceSecurityConfig.class})
public class SecurityConfig {
}
The security configuration for web pages... (URL does not begin with /service/**)
#Configuration
#Order(200)
#EnableWebMvcSecurity
public class WebPageSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(casAuthenticationProvider());
}
#Override
public void configure(final HttpSecurity http) throws Exception {
http.csrf().disable();
http.requestMatcher(new RequestMatcher() {
#Override
public boolean matches(final HttpServletRequest request) {
final String url = request.getServletPath() + StringUtils.defaultString(request.getPathInfo());
return !(url.startsWith("/service/"));
}
});
http.addFilter(casAuthenticationFilter()).exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint());
http.authorizeRequests().
antMatchers("/securedPage").hasAuthority("ROLE_CAS_USER"). // /securedPage can only be accessed by cas user
anyRequest().permitAll(); // all other pages are unsecured
}
// General Application Security (CAS Authentication)
#Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
final CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
return casAuthenticationFilter;
}
#Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
final CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
casAuthenticationEntryPoint.setLoginUrl(env.getRequiredProperty("cas.server.url") + "/login");
casAuthenticationEntryPoint.setServiceProperties(casServiceProperties());
return casAuthenticationEntryPoint;
}
#Bean
public ServiceProperties casServiceProperties() {
final ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(env.getRequiredProperty("cas.service.url") + "/j_spring_cas_security_check");
serviceProperties.setSendRenew(false);
return serviceProperties;
}
#Bean
public CasAuthenticationProvider casAuthenticationProvider() {
final CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
casAuthenticationProvider.setAuthenticationUserDetailsService(casAuthenticationUserDetailsService());
casAuthenticationProvider.setServiceProperties(casServiceProperties());
casAuthenticationProvider.setTicketValidator(casTicketValidator());
casAuthenticationProvider.setKey("casAuthenticationProviderKey");
casAuthenticationProvider.setStatelessTicketCache(casStatelessTicketCache());
return casAuthenticationProvider;
}
#Bean
public AuthenticationUserDetailsService casAuthenticationUserDetailsService() {
final AbstractCasAssertionUserDetailsService authenticationUserDetailsService = new AbstractCasAssertionUserDetailsService() {
#Override
protected UserDetails loadUserDetails(final Assertion assertion) {
final String username = assertion.getPrincipal().getName();
final List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_CAS_USER"));
return new User(username, "notused", authorities);
}
};
return authenticationUserDetailsService;
}
#Bean
public TicketValidator casTicketValidator() {
final Saml11TicketValidator ticketValidator = new Saml11TicketValidator(env.getRequiredProperty("cas.server.url"));
ticketValidator.setTolerance(env.getRequiredProperty("cas.ticket.tolerance", Long.class));
return ticketValidator;
}
#Bean
public StatelessTicketCache casStatelessTicketCache() {
final EhCacheBasedTicketCache ticketCache = new EhCacheBasedTicketCache();
ticketCache.setCache(casCache());
return ticketCache;
}
#Bean(initMethod = "initialise", destroyMethod = "dispose")
public Cache casCache() {
final Cache cache = new Cache("casTickets", 50, true, false, 3600, 900);
return cache;
}
#Autowired
private Environment env;
}
The security configuration for RESTful web services (URL starts with /service/**)
#Configuration
#Order(300)
#EnableWebMvcSecurity
public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
withUser("admin").password("password").authorities(new SimpleGrantedAuthority("ROLE_WS_USER"));
}
#Override
public void configure(final HttpSecurity http) throws Exception {
http.csrf().disable();
http.
antMatcher("/service/**"). // only process URLs that begin with /service/
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and(). // RESTful web services are stateless
addFilter(wsAuthenticationFilter()).exceptionHandling().authenticationEntryPoint(wsAuthenticationEntryPoint());
http.authorizeRequests().anyRequest().hasAuthority("ROLE_WS_USER"); // all requests are secured
}
// Web Service Security (BASIC Authentication)
#Bean
public BasicAuthenticationFilter wsAuthenticationFilter() throws Exception {
final BasicAuthenticationFilter wsAuthenticationFilter = new BasicAuthenticationFilter(authenticationManager(), wsAuthenticationEntryPoint());
return wsAuthenticationFilter;
}
#Bean
public BasicAuthenticationEntryPoint wsAuthenticationEntryPoint() {
final BasicAuthenticationEntryPoint wsAuthenticationEntryPoint = new BasicAuthenticationEntryPoint();
wsAuthenticationEntryPoint.setRealmName("My Realm");
return wsAuthenticationEntryPoint;
}
#Autowired
private Environment env;
}
It's explain how to create multiple securities in the docs
http://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html#multiple-httpsecurity
something like this should work
#EnableWebSecurity
public class MultiHttpSecurityConfig {
#Configuration
#Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Resource private UserDetailsService userBasicAuthService;
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**")
.userDetailsService(userBasicAuthService)
.authorizeRequests()
.and()
.httpBasic();
}
}
#Configuration
public static class PagesWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Resource private UserDetailsService userCasService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/pages/**")
.userDetailsService(userCasService)
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
}
}
}