Authenticating using LDAP with spring LDAP API and without using spring security - java

I am using spring-ldap-core plugin in my Sprint boot application.
Basically, the LDAPTemplate - http://docs.spring.io/spring-ldap/docs/current/apidocs/org/springframework/ldap/core/LdapTemplate.html
I basically want to convert the xml configuration below into java using Spring LDAP API and want to avoid using spring security.
The xml configuration that I want to convert is -
<ldap-server id="ldapServer"
url="ldap://ad.company.com:389"
manager-dn="CN=serviceaccount,OU=Service Accounts,DC=ad,DC=company,DC=com"
manager-password="password"/>
<authentication-manager>
<ldap-authentication-provider
server-ref="ldapServer"
user-search-base="dc=ad,dc=company,dc=com"
user-search-filter="sAMAccountName={0}"
group-search-filter="member={0}"
group-search-base="ou=Groups,dc=ad,dc=company,dc=com"
group-role-attribute="cn"/>
</authentication-manager>
Here is my java code below-
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.authentication.DefaultValuesAuthenticationSourceDecorator;
#Configuration
public class LdapConfiguration {
#Bean
public LdapContextSource contextSource(){
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldap://ad.company.com:389");
contextSource.setBase("DC=ad,DC=company,DC=com");
contextSource.setUserDn("CN=serviceaccount,OU=Service Accounts,DC=ad,DC=company,DC=com");
contextSource.setPassword("password");
contextSource.afterPropertiesSet();
return contextSource;
}
#Bean
public LdapTemplate ldapTemplate(){
LdapTemplate template = new LdapTemplate(contextSource());
try {
template.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
return template;
}
}
This is how I am trying to invoke authentication -
The method that this snippet is a part of returns a boolean value if authentication happens
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("sAMAccountName", userloginName));
return ldapTemplate.authenticate("OU=Service Accounts", filter.encode(), userPassword);
This is not working and the error I get is that :
No results found for search, base: 'OU=Service Accounts'; filter: '(sAMAccountName=usernameIinput)'.
I want to know how the following xml properties can be configured using LDAP API?
group-search-filter="member={0}"
group-search-base="ou=Groups,dc=ad,dc=company,dc=com"
group-role-attribute="cn"/>
Also, what else am I missing? Why is this not working?
Any help will be really appreciated!

I was able to figure this out.
//LDAP connection using LDAPTemplate
#Configuration
public class LdapConfiguration {
#Bean
public LdapContextSource contextSource(){
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldap://companyurl.com:389");
contextSource.setUserDn("CN=serviceaccount,OU=Service Accounts,DC=ad,DC=company,DC=com");
contextSource.setPassword("secretpassword");
return contextSource;
}
#Bean
public LdapTemplate ldapTemplate(){
LdapTemplate template = new LdapTemplate(contextSource());
return template;
}
}
//Authentication portion
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("mailNickname", username));
Boolean authenticate = ldapTemplate.authenticate(base, filter.encode(), userpassword);

Related

HttpInvokerServiceExporter is deprecated in spring 5. Is there any replacement? Will it be available in spring 6?

HttpInvokerServiceExporter is deprecated in spring 5. I want to call spring remote bean via HTTP protocol. Is there any replacement? HttpInvokerServiceExporter has a vulnerability of RCE also so i need to use some replacement of HttpInvokerServiceExporter.
RMI skeleton
#Configuration
public class RMIServer {
#Bean
DTBookingService bookingService() {
return new DTBookingServiceImpl();
}
#Bean(name = "exporter")
RmiServiceExporter exporter(DTBookingService implementation) {
Class<DTBookingService> serviceInterface = DTBookingService.class;
RmiServiceExporter exporter = new RmiServiceExporter();
exporter.setServiceInterface(serviceInterface); //interface
exporter.setService(implementation); //bean
exporter.setServiceName("bookingService"); //bean name
exporter.setRegistryPort(1099);
try {
exporter.prepare();
} catch (RemoteException e) {
e.printStackTrace();
}
return exporter;
}
}
RMI Stub to call remote bean
import javax.naming.Context;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
#Configuration
public class RMIClientConfig {
#Bean
RmiProxyFactoryBean service() {
RmiProxyFactoryBean proxyFactoryBean = new RmiProxyFactoryBean();
proxyFactoryBean.setServiceUrl("rmi://localhost:1099/bookingService");
proxyFactoryBean.setServiceInterface(DTBookingService.class);
return proxyFactoryBean;
}
}
Now i am trying to call bean via HttpInvokerServiceExporter via http protocol instead of rmi://(RmiServiceExporter). Please suggest if any replacement of HttpInvokerServiceExporter.

Exporting two services in Spring

I have a problem in Spring such that I get the next error when I try to export two services from server to client:
Caused by: org.springframework.remoting.RemoteLookupFailureException: Could not find RMI service [rmi://localhost:1099/ClientsService] in RMI registry; nested exception is java.rmi.NotBoundException: ClientsService
This is my Configuration in the server side:
#Configuration
public class ClientsServerConfig {
#Bean
RmiServiceExporter rmiServiceExporter() {
RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
rmiServiceExporter.setServiceInterface(ClientService.class);
rmiServiceExporter.setService(clientService());
rmiServiceExporter.setServiceName("ClientsService");
return rmiServiceExporter;
}
#Bean
ClientService clientService() {
return new ClientsServiceImpl(clientRepository());
}
#Bean
RepositoryInterface<Long, Client> clientRepository() {
return new ClientDbRepository();
}
}
and
#Configuration
public class GunProviderServerConfig{
#Bean
RmiServiceExporter rmiServiceExporter() {
RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
rmiServiceExporter.setServiceInterface(GunProviderService.class);
rmiServiceExporter.setService(gunProviderService());
rmiServiceExporter.setServiceName("GunProviderService");
return rmiServiceExporter;
}
#Bean
GunProviderService gunProviderService() {
return new GunProviderServiceImpl(gunProviderRepository());
}
#Bean
RepositoryInterface<Long, GunProvider> gunProviderRepository() {
return new GunProviderDbRepository();
}
}
and this is the configuration in the client side:
#Configuration
public class ClientConfig {
#Bean
RmiProxyFactoryBean rmiProxyFactoryBean() {
RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
rmiProxyFactoryBean.setServiceUrl("rmi://localhost:1099/ClientsService");
rmiProxyFactoryBean.setServiceInterface(ClientService.class);
return rmiProxyFactoryBean;
}
#Bean
RmiProxyFactoryBean rmiProxyFactoryBean2() {
RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
rmiProxyFactoryBean.setServiceUrl("rmi://localhost:1099/GunProviderService");
rmiProxyFactoryBean.setServiceInterface(GunProviderService.class);
return rmiProxyFactoryBean;
}
And the error is caused I think because the application does not know what service to use when two are exported. If I comment "GunProviderServerConfig" and "rmiProxyFactoryBean2" such that I have only the ClientService, the app will work.
I ran into the same issue yesterday but it worked for me this morning. consider moving the two exporters to the same configuration class

Unable to load wsdl using GUI tool using spring boot

I am new to both SOAP & spring boot technologies.However i have created soap webservice using below reference link.
https://spring.io/guides/gs/producing-web-service/
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "REL-6-MM7-1-4")
#Primary
public DefaultWsdl11Definition defaultWsdl11Definition() {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("MMSPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-4");
wsdl11Definition.setSchemaCollection(getXsdCollection());
return wsdl11Definition;
}
#Bean
public XsdSchemaCollection getXsdCollection() {
return new XsdSchemaCollection() {
public XsdSchema[] getXsdSchemas() {
return new XsdSchema[]{new SimpleXsdSchema(new ClassPathResource("REL-6-MM7-1-4.xsd")), new SimpleXsdSchema(new ClassPathResource("SoapEnvelope.xsd"))};
}
public XmlValidator createValidator() {
throw new UnsupportedOperationException();
}
};
}
Please find xsd posted.
This is the error that happen when you are not using the correct url into soap ui.
You need to search the right location of your XSD in the browser and make sure you can access to it.
Then you need to check the URL you are pasting into SOAP UI and see if the relative URLs actually are correct.
If they aren't, you have to use the correct location.
Edit :
In your case, I see the following code :
#Bean(name = "REL-6-MM7-1-4")
So I think that your ws is exposed at :
http://localhost:8080/ws/REL-6-MM7-1-4.wsdl
Edit 2 :
In your case, you also need to provide multiple xsd. You can do it by adding :
#Bean
public XsdSchemaCollection getXsdCollection() {
return new XsdSchemaCollection() {
public XsdSchema[] getXsdSchemas() {
return new XsdSchema[]{new SimpleXsdSchema(new ClassPathResource("REL-6-MM7-1-4.xsd")), new SimpleXsdSchema(new ClassPathResource("SoapEnvelope.xsd"))};
}
public XmlValidator createValidator() {
throw new UnsupportedOperationException();
}
};
}
and by using it at :
wsdl11Definition.setSchema(getXsdCollection());

ACL configuration problems with Spring Security

I'm new in the Spring's world I'm using Spring Boot 1.2.5 with Spring Security 3.1.2. Due to my project's requirements I need to configure an ACL security model. I have the following java class configuration:
#Configuration
public class ACLConfig {
#Autowired
DataSource dataSource;
#Bean
JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource);
}
#Bean
DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
#Bean
EhCacheBasedAclCache aclCache() {
EhCacheFactoryBean factoryBean = new EhCacheFactoryBean();
EhCacheManagerFactoryBean cacheManager = new EhCacheManagerFactoryBean();
cacheManager.setAcceptExisting(true);
cacheManager.setCacheManagerName(CacheManager.getInstance().getName());
cacheManager.afterPropertiesSet();
factoryBean.setName("aclCache");
factoryBean.setCacheManager(cacheManager.getObject());
factoryBean.setMaxBytesLocalHeap("16M");
factoryBean.setMaxEntriesLocalHeap(0L);
factoryBean.afterPropertiesSet();
return new EhCacheBasedAclCache(factoryBean.getObject());
}
#Bean
LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger());
}
#Bean
AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"),
new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"),
new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"));
}
#Bean
JdbcMutableAclService aclService() {
JdbcMutableAclService service = new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
service.setClassIdentityQuery("select currval(pg_get_serial_sequence('acl_class', 'id'))");
service.setSidIdentityQuery("select currval(pg_get_serial_sequence('acl_sid', 'id'))");
return service;
}
#Bean
AclEntryVoter aclDeleteVoter()
{
AclEntryVoter voter = new AclEntryVoter(aclService(),"ACL_NOMCITY_DELETE", new Permission[] {BasePermission.DELETE});
voter.setProcessDomainObjectClass(NomCity.class);
return voter;
}
#Bean
AclEntryVoter aclUpdateVoter()
{
return new AclEntryVoter(aclService(),"ACL_NOMCITY_UPDATE", new Permission[]{BasePermission.ADMINISTRATION});
}
#Bean
AclEntryVoter aclReadVoter()
{
return new AclEntryVoter(aclService(),"ACL_NOMCITY_READ", new Permission[]{BasePermission.READ});
}
#Bean
AccessDecisionManager accessDecisionManager (){
List<AccessDecisionVoter<? extends Object>> list = new ArrayList<>();
list.add(aclDeleteVoter());
list.add(aclReadVoter());
list.add(aclUpdateVoter());
return new AffirmativeBased(list);
}
}
I have the following RestController's methods, it use the ACLs defined earlier:
#RequestMapping(value = "/nomCitys",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
#Transactional
#Secured({"ROLE_ADMIN","ROLE_USER"})
public ResponseEntity<NomCity> create(#Valid #RequestBody NomCity nomCity) throws URISyntaxException {
NomCity result = nomCityRepository.save(nomCity);
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
ObjectIdentity oi = new ObjectIdentityImpl(NomCity.class,result.hashCode());
MutableAcl acl = mutableAclService.createAcl(oi);
acl.insertAce(0, BasePermission.ADMINISTRATION, new GrantedAuthoritySid("ROLE_ADMIN"), true);
acl.insertAce(1, BasePermission.DELETE, new PrincipalSid(user.getUsername()), true);
acl.insertAce(2, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER"), true);
mutableAclService.updateAcl(acl);
return ResponseEntity.created(new URI("/api/nomCitys/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert("nomCity", result.getId().toString()))
.body(result);
}
When I create a new city the following ACL entries are created too:
The user with ROLE_ADMIN role have Admin permission.
The user how create the city have Delete permission.
The user with ROLE_USER role can read the city.
The following method is the delete method:
#RequestMapping(value = "/nomCitys/{id}",
method = RequestMethod.DELETE,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
#Transactional
#Secured("ACL_NOMCITY_DELETE")
public ResponseEntity<Void> delete(#PathVariable Long id) {
nomCityRepository.delete(id);
ObjectIdentity oid = new ObjectIdentityImpl(NomCity.class,id);
mutableAclService.deleteAcl(oid, true);
return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert("nomCity", id.toString())).build();
}
When I create a new city all work fine, the ACL entries are created and stored in the data base, but when I go to remove a city I get a 403, although I'm logging with the user who created the city, reviewing some pages I saw the following xml entry:
<security:global-method-security
secured-annotations="enabled" access-decision-manager ref="customAccessDecisionManager" />
I suppose that it register the AccessDecisionManager but I don't know how do the same using Java Config and I don't if it's the reason of all my problems.
This question is for #secure anotation, but I finally solve the problem make a class configuration for using #Pre and #Post anotation, I post a config java class in my answer for this question.

Spring social NoSuchMethodError SocialAuthenticationFilter.getFilterProcessesUrl()

I use spring security login. Now I'm trying to add spring social facebook login, but I get many error information.
First, when I try to use the same method like spring social guide, I can't #Autowired private Facebook facebook
I found a solution
#Bean
#Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public Facebook facebook(ConnectionRepository repository) {
Connection<Facebook> connection = repository
.findPrimaryConnection(Facebook.class);
return connection != null ? connection.getApi() : null;
}
Next, I get the error "cannot find bean". I have to add:
#Bean
public ConnectionRepository connectionRepository() {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (authentication == null) {
throw new IllegalStateException(
"Unable to get a ConnectionRepository: no user signed in");
}
return usersConnectionRepository().createConnectionRepository(
authentication.getName());
}
#Bean
public ConnectionFactoryLocator connectionFactoryLocator() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(new FacebookConnectionFactory(facebookid,
facebookSecure));
return registry;
}
#Bean
public AuthenticationNameUserIdSource authenticationNameUserIdSource(){
return new AuthenticationNameUserIdSource();
}
#Bean
public ConnectController connectController(
ConnectionFactoryLocator connectionFactoryLocator,
ConnectionRepository connectionRepository) {
return new ConnectController(connectionFactoryLocator,
connectionRepository);
}
#Bean
public UsersConnectionRepository usersConnectionRepository() {
return new JdbcUsersConnectionRepository(dataSource,
connectionFactoryLocator(), Encryptors.noOpText());
}
After that, I have other issue java.lang.NoSuchMethodError: org.springframework.social.security.SocialAuthenticationFilter.getFilterProcessesUrl()Ljava/lang/String;
#Bean
public SocialAuthenticationServiceLocator socialAuthenticationServiceLocator() {
SocialAuthenticationServiceRegistry registry = new SocialAuthenticationServiceRegistry();
registry.addConnectionFactory(new FacebookConnectionFactory(facebookid,
facebookSecure));
return registry;
}
#Bean
public SocialAuthenticationFilter socialAuthenticationFilter()
throws Exception {
SocialAuthenticationFilter filter = new SocialAuthenticationFilter(
authenticationManager(), authenticationNameUserIdSource(),
usersConnectionRepository(), socialAuthenticationServiceLocator());
filter.setFilterProcessesUrl("/login");
filter.setSignupUrl("/signup");
filter.setConnectionAddedRedirectUrl("/home");
filter.setPostLoginUrl("/home"); // always open account profile
// page after login
// filter.setRememberMeServices(rememberMeServices());
return filter;
}
but always is the same.
This is my http configuration
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/home", "/css/**", "/**/*.css*", "/", "/signup",
"/facebook", "/signup.xhtml").permitAll().anyRequest()
.authenticated().and().formLogin().loginPage("/login").loginProcessingUrl("/login/authenticate")
.defaultSuccessUrl("/home").failureUrl("/login")
.permitAll().and().logout().logoutUrl("/logout")
.invalidateHttpSession(true).logoutSuccessUrl("/").and()
.apply(new SpringSocialConfigurer());
And controller
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage() {
return "redirect:/login/authenticate/connect/facebook";
}
I did a whole tutorial. Next, I removed SocialConfigurer implementation and created the same (not #Override, only #Bean) social documentation.
'Normal login '(spring security) works fine, but I can't configure spring social with spring security. I use JSF and .XHTML files.
Maybe someone knows where I make the mistakes?
Thanks for your help.
It looks like Spring Security removed getFilterProcessesUrl() in Spring Security 4.0.0.RC1 (it was marked as deprecated anyways).
It seems that other project filters have not been updated?
Try rolling back to 4.0.0.M2 or use the 3.2 train.
Please notice that spring security 4 will not accept spring social 1.1.0. Please upgrade all spring social dependencies(config, core, security and web) to 1.1.2.RELEASE. You can leave your spring social Facebook to 1.1.0
As hinted in my comment, you have the wrong version of some library. My intelligent guess is that version of Spring Security is wrong. From what I can find, you should use a version in the 3.2.x series (for example 3.2.5) of Spring Security.
Consider using version 1.1.4.
this is solved in spring-social-security 1.1.4.RELEASE (or perhaps some version before).
https://github.com/spring-projects/spring-social

Categories

Resources