I finally able to write a standalone java which I am able to connect to LDAP and get user name and also able to authenticate (with password). But When I try same url and other details in Spring LDAP, I am getting error. Not getting what I am missing in Spring LDAP. Any help please???
LDAPService.java (Standalone)
public class LDAPService {
private final static int ACCOUNT_DISABLED = 2;
private static String[] ldapUrls = null;
private static String adminId = null;
private static String adminPassword = null;
private static SearchControls searchCtls = null;
private static String defaultGroup = null;
private static LDAPService ldapService;
private static String searchBase = null;
private int domainIndex;
private int domainCount;
public static LDAPService getInstance() {
if(ldapService == null ) ldapService = new LDAPService();
return ldapService;
}
public LDAPService() {
super();
String ldapUrl = "ldap://mycompany-ldap-tdu.lb.xyz.dm.company.com:389/OU=Engine,OU=PQR%20Global,DC=am,DC=mds,DC=pqr,DC=com";
ldapUrls = StringUtils.split(ldapUrl, ";");
adminId = "CN=APP-XYZ-GRP,OU=Non-Person,OU=Users,OU=QWE,OU=Engine,OU=PQR Global,DC=am,DC=mds,DC=pqr,DC=com";
adminPassword = "admpasswd";
defaultGroup = "85";
searchBase = "";
searchCtls = new SearchControls();
String attrTemp = "distinguishedName,userPassword,memberOf,pwdLastSet,accountExpires,userAccountControl,givenName,sn";
String returnedAtts[]= null;
if(null != attrTemp){
StringTokenizer st = new StringTokenizer(attrTemp,",");
int size = st.countTokens();
returnedAtts = new String[size];
int counter = 0;
while(st.hasMoreElements()){
returnedAtts[counter++] = st.nextToken();
}
}
int scope = 2;
searchCtls.setReturningAttributes(returnedAtts);
searchCtls.setSearchScope(scope);
//Start with a random domain controller to balance load.
Random randomGenerator = new Random();
domainIndex = randomGenerator.nextInt(ldapUrls.length);
domainCount = 0;
}
private Hashtable<String,String> getEnvironment(String userId, String password) {
Hashtable<String,String> envDC = new Hashtable<String,String>();
envDC.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
envDC.put(Context.SECURITY_AUTHENTICATION,"simple");
envDC.put(Context.PROVIDER_URL, ldapUrls[domainIndex]);
envDC.put(Context.SECURITY_PRINCIPAL,userId);
envDC.put(Context.SECURITY_CREDENTIALS,password);
return envDC;
}
public List<UserSecurityGroupId> authenticate(String userId,String password)throws Exception{
List<UserSecurityGroupId> groups = null;
String distinguishedName = null;
String memberOf = null;
Long pwdLastSet = null;
Long accountExpires = null;
Hashtable<String,String> envGC = getEnvironment(adminId, adminPassword);
String searchFilter = "(&(cn="+ userId + ")(objectClass=user))";
try{
LdapContext ctxGC = new InitialLdapContext(envGC,null);
//search LDAP Server using search Filter.
NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);
if (answer.hasMoreElements()) {
SearchResult result = (SearchResult)answer.next();
Attributes attrs = result.getAttributes();
// get all attributes if the user exists
if (attrs != null) {
//Check if the User Account has been disabled
//This is identified by the returned values binary place holder for the decimal value 2 being a 1
if(null != attrs.get("useraccountcontrol")){
int userAccountControl = NumberUtils.toInt(attrs.get("useraccountcontrol")
.toString().replaceAll("userAccountControl: ", ""), ACCOUNT_DISABLED);
if((userAccountControl & ACCOUNT_DISABLED) == ACCOUNT_DISABLED){
return null;
}
}
//memberOf attribute retrieves the groups to which user belongs.
//only retrieve group memberships if password is provided
if(null != attrs.get("memberOf") && (null != password) && (password.trim().length() > 0)){
memberOf = attrs.get("memberOf").toString();
}
groups = getListOfGroups(memberOf, userId);
//pwdLastSet retrieves the time when password was last set.
if(null != attrs.get("pwdLastSet")){
pwdLastSet = new Long(attrs.get("pwdLastSet").get().toString());
}
//accountExpires retrieves the time when account will expire.
if(null != attrs.get("accountExpires")){
accountExpires = new Long(attrs.get("accountExpires").get().toString());
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(1601, 0, 1, 0, 0);
accountExpires = accountExpires / 10000 + calendar.getTime().getTime();
}
//distinguished name retrieves the distinguished name for the user.
if(null != attrs.get("distinguishedName")){
distinguishedName = attrs.get("distinguishedName").get().toString();
}
}
}else{
// if no attributes retrieved then user does not exist.
throw new LoginException(LoginStatus.USER_NOT_EXIST.toString());
}
ctxGC.close();
// verify if account is already expired.
if ( (null != accountExpires) && (accountExpires.longValue() > 0)) {
long today = System.currentTimeMillis();
long expireDay = accountExpires.longValue();
if ( expireDay < today ) {
throw new LoginException(LoginStatus.PASSWORD_EXPIRED.toString());
}
}
} catch (NamingException e) {
System.out.println("Naming Exception occurred");
if(checkNextDomainController())
authenticate(userId, password);
else
throw new LoginException(LoginStatus.AUTHENTICATION_ERROR.toString());
}
if(null != distinguishedName){
// verify the username and password if password is provided
if((null != password) && (password.trim().length() > 0)){
try {
Hashtable envDC = getEnvironment(distinguishedName,password);
DirContext ctx = new InitialDirContext(envDC);
ctx.close();
return groups;
}catch (CommunicationException comEx){
System.out.println("Communication Exception occurred");
if(checkNextDomainController())
return authenticate(userId, password);
else
throw new LoginException(LoginStatus.AUTHENTICATION_ERROR.toString());
}catch (AuthenticationException authEx){
authEx.printStackTrace();
System.out.println("Authentication Exception occurred");
throw new LoginException(LoginStatus.PASSWORD_INCORRECT.toString());
}catch (NamingException nameEx){
System.out.println("Naming Exception occurred");
if(checkNextDomainController())
return authenticate(userId, password);
else
throw new LoginException(LoginStatus.AUTHENTICATION_ERROR.toString());
}
}else{
return groups;
}
}else{
throw new LoginException(LoginStatus.USER_NOT_EXIST.toString());
}
}
private List<UserSecurityGroupId> getListOfGroups(String memberOf, String userId) {
List<UserSecurityGroupId> userScrityGrpList = new ArrayList<UserSecurityGroupId>();
String[] userSecurityGroupFilter = {"APP-XYZ"};
if(null != memberOf){
while(memberOf.indexOf("CN=") > 0){
memberOf = memberOf.substring(memberOf.indexOf("CN=")+3);
String tmp = memberOf.substring(0,memberOf.indexOf(','));
if(StringUtils.startsWithAny(tmp, userSecurityGroupFilter )) {
UserSecurityGroupId groupId = new UserSecurityGroupId(userId, tmp);
userScrityGrpList.add(groupId);
}
}
}
UserSecurityGroupId group = new UserSecurityGroupId(userId, defaultGroup);
if(!userScrityGrpList.contains(group)){
userScrityGrpList.add(group);
}
return userScrityGrpList;
}
/**
* This utility will return Associate Name from Active Directory corresponding to given user id.
* #param userId
* #return Associate Name
*/
public String getAssociateName(String userId) {
Hashtable<String,String> envGC = getEnvironment(adminId, adminPassword);
String searchFilter = "(&(cn="+ userId + ")(objectClass=user))";
String associateName = "";
try{
LdapContext ctxGC = new InitialLdapContext(envGC,null);
//search LDAP Server using search Filter.
NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);
if (answer.hasMoreElements()) {
SearchResult result = (SearchResult)answer.next();
Attributes attrs = result.getAttributes();
// get all attributes if the user exists
if (attrs != null) {
//givenName attribute retrieves Given Name.
if(null != attrs.get("givenName") ){
associateName = associateName + attrs.get("givenName").get().toString() + " ";
}
//sn retrieves the Surname.
if(null != attrs.get("sn")){
associateName += attrs.get("sn").get().toString();
}
System.out.println(attrs.get("userPassword"));
}
}
ctxGC.close();
} catch (NamingException e) {
System.out.println("Naming Exception occurred while retrieving associate name");
}
return associateName;
}
public static void main(String[] a) {
LDAPService s = new LDAPService();
try {
System.out.println(s.getAssociateName("12345"));
//System.out.println(s.authenticate("12345", "password123"));
}catch(Exception e) {
e.printStackTrace();
}
}
}
WebSecurityConfiguration.java (Spring class)
#Configurable
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
try {
auth.ldapAuthentication()
.contextSource().url("ldap://mycompany-ldap-tdu.lb.xyz.dm.company.com:389/OU=Engine,OU=PQR%20Global,DC=am,DC=mds,DC=pqr,DC=com")
.managerDn("CN=APP-XYZ-GRP,OU=Non-Person,OU=Users,OU=QWE,OU=Engine,OU=PQR Global,DC=am,DC=mds,DC=pqr,DC=com")
.managerPassword("admpasswd")
.and()
.userSearchBase("")
.groupSearchBase("")
.userSearchFilter("(&(cn={0})(objectClass=user))")
.groupSearchFilter("(member=userGroup)");
}catch(Exception e) {
e.printStackTrace();
}
}
Error:
o.s.security.web.FilterChainProxy : /account/login at position 7 of 14 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
o.s.security.web.FilterChainProxy : /account/login at position 8 of 14 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
o.s.s.w.a.www.BasicAuthenticationFilter : Basic Authentication Authorization header found for user 'user'
o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
o.s.s.l.a.LdapAuthenticationProvider : Processing authentication request for user: user
o.s.s.l.s.FilterBasedLdapUserSearch : Searching for user 'user', with user search [ searchFilter: '(&(cn={0})(objectClass=user))', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
.s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.authentication.InternalAuthenticationServiceException
o.s.s.w.a.www.BasicAuthenticationFilter : Authentication request for failed: org.springframework.security.authentication.InternalAuthenticationServiceException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310020A, problem 2001 (NO_OBJECT), data 0, best match of:
'DC=am,DC=mds,DC=pqr,DC=com'
]; nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310020A, problem 2001 (NO_OBJECT), data 0, best match of:
'DC=am,DC=mds,DC=pqr,DC=com'
]; remaining name '/'
Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#1dd945b2
w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Related
I have to check if username and password gave from user are right matching with the Ldap server. I use two connection, in the first I retrieve dn from uid and in the second I connect to Ldap with dn and password.
I have a problem with retrieved dn, it doesn't have the right fields.
It returns
cn=Lu Ca+sn=Ca+uid=luca+userPassword={SSHA}OiMBVTTZBPqnohYch9\+ISeVv\+5ucgxMR: null:null:No attributes
and not
cn=Lu Ca+sn=Ca+uid=luca+userPassword={SSHA}OiMBVTTZBPqnohYch9\+ISeVv\+5ucgxMR,ou=people,dc=example,dc=com
As you can see, ou and dc are not returned so my second query fails.
This is my code
#Override
public void isAuthenticated(String username, String password) throws LdapException{
String dn;
Hashtable<String, Object> ldapEnv = new Hashtable<String, Object>();
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, env.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
ldapEnv.put(Context.SECURITY_CREDENTIALS, "secret");
String[] returnAttribute = {"dn"};
DirContext ctx = null;
NamingEnumeration<SearchResult> results = null;
try {
ctx = new InitialDirContext(ldapEnv);
SearchControls controls = new SearchControls();
controls.setReturningAttributes(returnAttribute);
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "uid=" + username ;
results = ctx.search(env.getRequiredProperty(PROPERTY_NAME_LDAP_USERSEARCHBASE), filter, controls);
if (results.hasMore())
dn = results.nextElement().toString();
else throw new LdapException("Wrong username. Please retry!");
} catch (Exception e) {
throw new LdapException(e);
} finally {
try{
if (results != null)
results.close();
if (ctx != null)
ctx.close();
}catch(Exception e){
throw new LdapException(e);
}
}
Hashtable<String, Object> authEnv = new Hashtable<String, Object>();
authEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
authEnv.put(Context.PROVIDER_URL, env.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
authEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
authEnv.put(Context.SECURITY_PRINCIPAL, dn);
authEnv.put(Context.SECURITY_CREDENTIALS, password);
try {
new InitialDirContext(authEnv);
} catch (AuthenticationException authEx) {
throw new LdapException("Authentication error. Password was wrong");
} catch(Exception e){
throw new LdapException(e);
}
}
with this parameters
ldap.url=ldap://127.0.0.1:10389/dc=example,dc=com
ldap.userSearchBase=ou=people
I'm uing this value also for spring authentication but I have one method (send big file) that fails only if I use authentication so I would like to try to authenticate with java and not through Spring
Do you know why I have this problem? thanks
UPDATE: with
dn = results.nextElement().getNameInNamespace();
it works, is my codes robust?
This is jboss LDAP login module implementation you can compare you code:
full code link
protected void rolesSearch(LdapContext ctx, SearchControls constraints, String user, String userDN,
int recursionMax, int nesting) throws NamingException
{
LdapContext ldapCtx = ctx;
Object[] filterArgs = {user, sanitizeDN(userDN)};
boolean referralsExist = true;
while (referralsExist) {
NamingEnumeration results = ldapCtx.search(rolesCtxDN, roleFilter, filterArgs, constraints);
try
{
while (results.hasMore())
{
SearchResult sr = (SearchResult) results.next();
String dn;
if (sr.isRelative()) {
dn = canonicalize(sr.getName());
}
else {
dn = sr.getNameInNamespace();
}
if (nesting == 0 && roleAttributeIsDN && roleNameAttributeID != null)
{
if(parseRoleNameFromDN)
{
parseRole(dn);
}
else
{
// Check the top context for role names
String[] attrNames = {roleNameAttributeID};
Attributes result2 = null;
if (sr.isRelative()) {
result2 = ldapCtx.getAttributes(quoteDN(dn), attrNames);
}
else {
result2 = getAttributesFromReferralEntity(sr, user, userDN);
}
Attribute roles2 = (result2 != null ? result2.get(roleNameAttributeID) : null);
if( roles2 != null )
{
for(int m = 0; m < roles2.size(); m ++)
{
String roleName = (String) roles2.get(m);
addRole(roleName);
}
}
}
}
// Query the context for the roleDN values
String[] attrNames = {roleAttributeID};
Attributes result = null;
if (sr.isRelative()) {
result = ldapCtx.getAttributes(quoteDN(dn), attrNames);
}
else {
result = getAttributesFromReferralEntity(sr, user, userDN);
}
if (result != null && result.size() > 0)
{
Attribute roles = result.get(roleAttributeID);
for (int n = 0; n < roles.size(); n++)
{
String roleName = (String) roles.get(n);
if(roleAttributeIsDN && parseRoleNameFromDN)
{
parseRole(roleName);
}
else if (roleAttributeIsDN)
{
// Query the roleDN location for the value of roleNameAttributeID
String roleDN = quoteDN(roleName);
String[] returnAttribute = {roleNameAttributeID};
try
{
Attributes result2 = null;
if (sr.isRelative()) {
result2 = ldapCtx.getAttributes(roleDN, returnAttribute);
}
else {
result2 = getAttributesFromReferralEntity(sr, user, userDN);
}
Attribute roles2 = (result2 != null ? result2.get(roleNameAttributeID) : null);
if (roles2 != null)
{
for (int m = 0; m < roles2.size(); m++)
{
roleName = (String) roles2.get(m);
addRole(roleName);
}
}
}
catch (NamingException e)
{
PicketBoxLogger.LOGGER.debugFailureToQueryLDAPAttribute(roleNameAttributeID, roleDN, e);
}
}
else
{
// The role attribute value is the role name
addRole(roleName);
}
}
}
if (nesting < recursionMax)
{
rolesSearch(ldapCtx, constraints, user, dn, recursionMax, nesting + 1);
}
}
referralsExist = false;
}
catch (ReferralException e) {
ldapCtx = (LdapContext) e.getReferralContext();
}
finally
{
if (results != null)
results.close();
}
} // while (referralsExist)
}
I have 15 usernames with me, I need to pull worklog entries of these users and manipulate it from JAVA client
Below are the jar files am using to connect JIRA api and fetch values
The code is pasted below
public class JiraConnector {
JiraRestClient jira;
public JiraConnector() throws URISyntaxException {
String url = prop().getUrl();
String userName = prop().getUser() ;
String password = prop().getpwd() ;
JerseyJiraRestClientFactory clientFactory = new JerseyJiraRestClientFactory();
jira = clientFactory.createWithBasicHttpAuthentication(new URI(url),
userName, password);
System.out.println("Connection established to >> " + url);
}
public void printIssueDetails(String jiraNumber) {
System.out.println("JiraNumber is " + jiraNumber);
Issue issue = jira.getIssueClient().getIssue(jiraNumber, null);
System.out.println(issue.getSummary());
System.out.println(issue.getDescription());
}
public void printUserWorkLog(String userName) {
System.out.println("user details invoked ... ");
User user = jira.getUserClient().getUser(userName, null);
System.out.println(user.getDisplayName());
System.out.println(user.getEmailAddress());
}
For any given username, am able to print his displayName and emailAdress (all those basic infos).
But I need to get the list of worklogs for the given user. Not sure how to proceed
You can find all worklog records for selected issue:
List<Worklog> worklogByIssue = ComponentAccessor.getWorklogManager().getByIssue(issue);
After that you can parse all worklog records to determine for what user this record created:
for (Worklog worklogByIssueItem : worklogByIssue)
{
int timeSpent = worklogByIssueItem.getTimeSpent().intValue();
String worklogAuthorName = worklogByIssueItem.getAuthorObject().getName();
...
}
And last task is search of issues by some params:
public static List<Issue> searchIssues(SearchParametersAggregator searchParams)
{
String jqlQuery = searchParams.getJqlQuery();
String projectId = searchParams.getProjectId();
String condition = createCondition(jqlQuery, projectId);
JqlQueryBuilder jqlQueryBuilder = prepareJqlQueryBuilder(condition);
return searchIssues(jqlQueryBuilder);
}
static List<Issue> searchIssues(JqlQueryBuilder jqlQueryBuilder)
{
Query query = jqlQueryBuilder.buildQuery();
SearchService searchService = ComponentAccessor.getComponent(SearchService.class);
try
{
ApplicationUser applicationUser = ComponentAccessor.getJiraAuthenticationContext().getUser();
User user = applicationUser.getDirectoryUser();
SearchResults searchResults = searchService.search(user, query, PagerFilter.getUnlimitedFilter());
List<Issue> issues = searchResults.getIssues();
return issues;
}
catch (SearchException e)
{
LOGGER.error("Error occurs during search of issues");
e.printStackTrace();
}
return new ArrayList<Issue>();
}
static JqlQueryBuilder prepareJqlQueryBuilder(String condition)
{
try
{
Query query = jqlQueryParser.parseQuery(condition);
JqlQueryBuilder builder = JqlQueryBuilder.newBuilder(query);
return builder;
}
catch (JqlParseException e)
{
throw new RuntimeException("JqlParseException during parsing jqlQuery!");
}
}
How can we make a fulltext search with collectionId on Oracle UCM? Is it possible to do fulltext search supplying recursively start with collectionId parameter?
I did some trials (you can take a look below) but if i test with collectionId, there is no result return.
public List<UCMDocumentTemplate> fullTextSearchByFolderId(#WebParam(name = "searchCriteria")
String paramSearchCriteria, #WebParam(name = "ucmFolderId")
Long ucmFolderId) throws UCMDocumentSearchException
{
List<UCMDocumentTemplate> documentTemplateList = new ArrayList<UCMDocumentTemplate>();
String documentSearchCriteria = "";
try
{
if (ucmFolderId != null)
documentSearchCriteria = "xCollectionID <= <qsch>" + ucmFolderId + "</qsch> <AND>";
documentSearchCriteria += "dDocFullText <substring> <qsch>" + paramSearchCriteria + "</qsch>";
List<Properties> childDocumentList = UCM_API.fullTextSearch(documentSearchCriteria);
UCMDocumentTemplate ucmDocumentTemplate = null;
if (childDocumentList != null)
for (Properties properties : childDocumentList)
{
ucmDocumentTemplate = transformToUCMDocumentTemplate(new UCMDocumentTemplate(), properties);
documentTemplateList.add(ucmDocumentTemplate);
}
}
catch (Exception e)
{
UCMDocumentSearchException exc = new UCMDocumentSearchException(documentSearchCriteria, e);
System.err.println(exc.getCompleteCode());
e.printStackTrace();
throw exc;
}
return documentTemplateList;
}
public static List<Properties> fullTextSearch(String searchCriteria) throws Exception
{
List<Properties> resultList = null;
List<Field> fields = null;
Properties responseProperties = null;
Properties inputBinderProperties = new Properties();
inputBinderProperties.put("IdcService", "GET_SEARCH_RESULTS");
inputBinderProperties.put("QueryText", searchCriteria);
inputBinderProperties.put("SearchEngineName", "databasefulltext");
inputBinderProperties.put("ResultCount", "500");
DataBinder responseBinder = getExecutedResponseBinder(userName, inputBinderProperties);
DataResultSet resultSet = responseBinder.getResultSet("SearchResults");
fields = resultSet.getFields();
resultList = new ArrayList<Properties>();
for (DataObject dataObject : resultSet.getRows())
{
responseProperties = new Properties();
for (Field field : fields)
{
if (field.getType() == Field.Type.DATE && dataObject.getDate(field.getName()) != null)
responseProperties.put(field.getName(), dataObject.getDate(field.getName()));
else
responseProperties.put(field.getName(), dataObject.get(field.getName()));
}
resultList.add(responseProperties);
}
return resultList;
}
i found a solution. when adding a parameter to inputBinderProperties, it works properly
inputBinderProperties.put("folderChildren", ucmFolderId);
I have using Google (GDATA) Gmail API for retrieving the contact list from gmail, It is working successfully on windows environment, but when I run the same code on Linux, I get error of Invalid Credentials.
I googled it, but can't get much help,
here is my code
public static String getGmailContactList() {
String response = "";
StringBuilder str = new StringBuilder();
String statusString = "";
ArrayList list = new ArrayList();
ContactsService myService = new ContactsService("");
String email = "xxxxx#gmail.com";
String password = "xxxxxxxx";
try
{
try
{
myService.setUserCredentials(email, password);
}
catch (AuthenticationException ex)
{
ex.printStackTrace();
//****I got exception here when using this code on LINUX ENVIORMENT** ***
}
response = printAllContacts(myService, email);
Iterator itr = list.iterator();
while (itr.hasNext())
{
ArrayList contact = (ArrayList) itr.next();
try
{
str.append(contact.get(1)).append(",");
}
catch (Exception e)
{
log.debug("Exception ocurred inside fethching gmail contact >
>
>
" + e);
str.append("no contacts found");
}
str.substring(0, str.length() - 1);
}
}
catch (Exception ae)
{
response = statusString;
log.debug("Exception ocurred inside ReadContacts : getGmailContactList()" + ae);
}
return response;
}
public static String printAllContacts(ContactsService myService, String emailSent)//
throws ServiceException, IOException
{
URL feedUrl = new URL("http://www.google.com/m8/feeds/contacts/" + emailSent + "/full");
Query myQuery = new Query(feedUrl);
myQuery.setMaxResults(100);
ContactFeed resultFeed = myService.getFeed(myQuery, ContactFeed.class);
String phones = null;
String emails = null;
log.debug(resultFeed.getTitle().getPlainText());
StringBuilder contacts = new StringBuilder();
contacts.append("<?xml version=\"1.0\"><Contacts>");
for (int i = 0; i < resultFeed.getEntries().size(); i++)
{
contacts.append("<Contact>");
ContactEntry entry = resultFeed.getEntries().get(i);
if (entry.hasName())
{
Name name = entry.getName();
if (name.hasFullName())
{
String fullNameToDisplay = name.getFullName().getValue();
if (name.getFullName().hasYomi())
{
fullNameToDisplay += " (" + name.getFullName().getYomi() + ")";
}
contacts.append("<Name>").append(fullNameToDisplay).append("</Name>");
}
else
{
contacts.append("<Name>").append("").append("</Name>");
}
}
else
{
contacts.append("<Name>").append("").append("</Name>");
}
StringBuilder emailIds = new StringBuilder();
if (entry.hasEmailAddresses())
{
List<Email> email = entry.getEmailAddresses();
if (email != null && email.size() > 0)
{
for (Email e : email)
{
emailIds.append(e.getAddress()).append(",");
}
emailIds.trimToSize();
if (emailIds.indexOf(",") != -1)
{
emails = emailIds.substring(0, emailIds.lastIndexOf(","));
}
contacts.append("<Email>").append(emails).append("</Email>");
}
else
{
contacts.append("<Email>").append("").append("</Email>");
}
}
else
{
contacts.append("<Email>").append("").append("</Email>");
}
contacts.append("</Contact>");
}
contacts.append("</Contacts>");
return contacts.toString();
}
so where I am lacking behind, some sort of help will be appriciated
here is the stack trace
com.google.gdata.client.GoogleService$InvalidCredentialsException: Invalid credentials
at com.google.gdata.client.GoogleAuthTokenFactory.getAuthException(GoogleAuthTokenFactory.java:660)
at com.google.gdata.client.GoogleAuthTokenFactory.getAuthToken(GoogleAuthTokenFactory.java:560)
at com.google.gdata.client.GoogleAuthTokenFactory.setUserCredentials(GoogleAuthTokenFactory.java:397)
at com.google.gdata.client.GoogleService.setUserCredentials(GoogleService.java:364)
at com.google.gdata.client.GoogleService.setUserCredentials(GoogleService.java:319)
at com.google.gdata.client.GoogleService.setUserCredentials(GoogleService.java:303)
at com.gmail.ReadContacts.getGmailContactList(ReadContacts.java:55)
I am trying to implement Active Directory authentication in Java which will be ran from a Linux machine. Our AD set-up will consist of multiple servers that share trust relationships with one another so for our test environment we have two domain controllers:
test1.ad1.foo.com who trusts test2.ad2.bar.com.
Using the code below I can successfully authenticate a user from test1 but not on test2:
public class ADDetailsProvider implements ResultSetProvider {
private String domain;
private String user;
private String password;
public ADDetailsProvider(String user, String password) {
//extract domain name
if (user.contains("\\")) {
this.user = user.substring((user.lastIndexOf("\\") + 1), user.length());
this.domain = user.substring(0, user.lastIndexOf("\\"));
} else {
this.user = user;
this.domain = "";
}
this.password = password;
}
/* Test from the command line */
public static void main (String[] argv) throws SQLException {
ResultSetProvider res = processADLogin(argv[0], argv[1]);
ResultSet results = null;
res.assignRowValues(results, 0);
System.out.println(argv[0] + " " + argv[1]);
}
public boolean assignRowValues(ResultSet results, int currentRow)
throws SQLException
{
// Only want a single row
if (currentRow >= 1) return false;
try {
ADAuthenticator adAuth = new ADAuthenticator();
LdapContext ldapCtx = adAuth.authenticate(this.domain, this.user, this.password);
NamingEnumeration userDetails = adAuth.getUserDetails(ldapCtx, this.user);
// Fill the result set (throws SQLException).
while (userDetails.hasMoreElements()) {
Attribute attr = (Attribute)userDetails.next();
results.updateString(attr.getID(), attr.get().toString());
}
results.updateInt("authenticated", 1);
return true;
} catch (FileNotFoundException fnf) {
Logger.getAnonymousLogger().log(Level.WARNING,
"Caught File Not Found Exception trying to read cris_authentication.properties");
results.updateInt("authenticated", 0);
return false;
} catch (IOException ioe) {
Logger.getAnonymousLogger().log(Level.WARNING,
"Caught IO Excpetion processing login");
results.updateInt("authenticated", 0);
return false;
} catch (AuthenticationException aex) {
Logger.getAnonymousLogger().log(Level.WARNING,
"Caught Authentication Exception attempting to bind to LDAP for [{0}]",
this.user);
results.updateInt("authenticated", 0);
return true;
} catch (NamingException ne) {
Logger.getAnonymousLogger().log(Level.WARNING,
"Caught Naming Exception performing user search or LDAP bind for [{0}]",
this.user);
results.updateInt("authenticated", 0);
return true;
}
}
public void close() {
// nothing needed here
}
/**
* This method is called via a Postgres function binding to access the
* functionality provided by this class.
*/
public static ResultSetProvider processADLogin(String user, String password) {
return new ADDetailsProvider(user, password);
}
}
public class ADAuthenticator {
public ADAuthenticator()
throws FileNotFoundException, IOException {
Properties props = new Properties();
InputStream inStream = this.getClass().getClassLoader().
getResourceAsStream("com/bar/foo/ad/authentication.properties");
props.load(inStream);
this.domain = props.getProperty("ldap.domain");
inStream.close();
}
public LdapContext authenticate(String domain, String user, String pass)
throws AuthenticationException, NamingException, IOException {
Hashtable env = new Hashtable();
this.domain = domain;
env.put(Context.INITIAL_CONTEXT_FACTORY, com.sun.jndi.ldap.LdapCtxFactory);
env.put(Context.PROVIDER_URL, "ldap://" + test1.ad1.foo.com + ":" + 3268);
env.put(Context.SECURITY_AUTHENTICATION, simple);
env.put(Context.REFERRAL, follow);
env.put(Context.SECURITY_PRINCIPAL, (domain + "\\" + user));
env.put(Context.SECURITY_CREDENTIALS, pass);
// Bind using specified username and password
LdapContext ldapCtx = new InitialLdapContext(env, null);
return ldapCtx;
}
public NamingEnumeration getUserDetails(LdapContext ldapCtx, String user)
throws NamingException {
// List of attributes to return from LDAP query
String returnAttributes[] = {"ou", "sAMAccountName", "givenName", "sn", "memberOf"};
//Create the search controls
SearchControls searchCtls = new SearchControls();
searchCtls.setReturningAttributes(returnAttributes);
//Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// Specify the user to search against
String searchFilter = "(&(objectClass=*)(sAMAccountName=" + user + "))";
//Perform the search
NamingEnumeration answer = ldapCtx.search("dc=dev4,dc=dbt,dc=ukhealth,dc=local", searchFilter, searchCtls);
// Only care about the first tuple
Attributes userAttributes = ((SearchResult)answer.next()).getAttributes();
if (userAttributes.size() <= 0) throw new NamingException();
return (NamingEnumeration) userAttributes.getAll();
}
From what I understand of the trust relationship, if trust1 receives a login attempt for a user in trust2, then it should forward the login attempt on to it and it works this out from the user's domain name.
Is this correct or am I missing something or is this not possible using the method above?
--EDIT--
The stack trace from the LDAP bind is
{java.naming.provider.url=ldap://test1.ad1.foo.com:3268, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.security.authentication=simple, java.naming.referral=follow}
30-Oct-2012 13:16:02
ADDetailsProvider assignRowValues
WARNING: Caught Authentication Exception attempting to bind to LDAP for [trusttest]
Auth error is [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db0]
As far as I know, you should set Context.REFERRAL to true.
Is this what you meant in your code?
In addition, when I switched to GSSAPI/Kerberos,
I defined trust relationships between the kerberos realms and it worked for me.