How to solve 'Empty encoded password' error when trying to connect LDAP - ldap

I am trying to connect to LDAP of the company and I am getting a lot of troubles. I solve one and suddenly I get a new one.
Right now I think the context is well defined and there is connectivity but it complains about 'Empty encoded password' and I dont know how to face it.
I am trying to authenticate through a service user.
Now I am working with this code:
auth.ldapAuthentication()
.userSearchBase("ou=xxxx,ou=yyyy")
.userSearchFilter("SamAccountName={0}")
.contextSource()
.url("ldap://servername:389/dc=aaaa,dc=bbbb,dc=cccc")
.managerDn("CN=serviceUserName,OU=uuuu,OU=yyyy,DC=aaaa,DC=bbbb,DC=cccc")
.managerPassword("serviceUserPass")
.and()
.passwordCompare()
.passwordEncoder(passwordEncoder())
.passwordAttribute("password");
And:
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
And I am having this error:
2019-05-13 10:41:37.808 WARN 22928 --- [nio-8080-exec-6] o.s.s.c.bcrypt.BCryptPasswordEncoder : Empty encoded password
2019-05-13 10:41:37.926 ERROR 22928 --- [nio-8080-exec-6] w.a.UsernamePasswordAuthenticationFilter : An internal error occurred while trying to authenticate the user.
org.springframework.security.authentication.InternalAuthenticationServiceException: [LDAP: error code 16 - 00000057: LdapErr: DSID-0C090D70, comment: Error in attribute conversion operation, data 0, v1db1
I try changing the PasswordEncoder function to:
#Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
#Override
public String encode(CharSequence rawPassword) {
return BCrypt.hashpw(rawPassword.toString(), BCrypt.gensalt(4));
}
#Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}
};
}
And I check that the 'encodedPassword' variable is empty (The 'rawPassword' is the one I enter in the login page). This error is:
java.lang.IllegalArgumentException: salt cannot be null
I don't know if it means it doesn't have access to LDAP, if the password can't be encoded, if it doesn't find the user...
Any help is really appreciate.

Related

How to get details about an error from RequestFailedException

I am trying to port code that had been using Microsoft.WindowsAzure.Storage classes to use the newer classes in Azure.Data.Tables, Azure.Storage.Queues, etc. From what I have been able to discern, the StorageException class has been replaced by RequestFailedException. Unfortunately, there are some properties in StorageException that do not exist in RequestFailedException, making it difficult to log appropriate messages when an exception is encountered (for example: RequestId, RequestInformation, etc.).
The migration document does not address the differences between StorageException and the new RequestFailedException, or how to get error details from it.
It seems that either the new libraries are not yet mature enough for prime time, or maybe it is just because the documentation is lacking the relevant information and I can't find the appropriate methodologies for getting all of the error information from the RequestFailedException.
Does anyone know how to get more data out of the new class? Here are some examples of what we used to do:
catch (StorageException e)
{
operation.Telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
Changing the above to use RequestFailedException is a problem because RequestInformation is not a property of RequestFailedException.
Here is another case:
catch (StorageException se)
{
var ri = se.RequestInformation;
if (ri.ErrorCode == "TableNotFound")
{
Logger.Info(
$"{SJResult.MakeInfo(64)} {ri.HttpStatusCode} {ri.HttpStatusMessage}, Storage Service code={ri.ErrorCode} This is OK if HL7 has not yet received messages."); // 60240040
}
else
{
Logger.Error(
$"{SJResult.MakeError(65)} HttpStatusCode: {ri.HttpStatusCode}, HttpStatusMessage: {ri.HttpStatusMessage}, Storage Service code={ri.ErrorCode}, " +
$"Extended.ErrorCode: {ri.ExtendedErrorInformation.ErrorCode} Extended.ErrorMessage: {ri.ExtendedErrorInformation.ErrorMessage}"); // E0240041
throw;
}
Again, RequestInformation is not available in RequestFailedException.
How do we get access to all the detailed information (RequestInformation) about an exception from the new RequestFailedException class?
As you can see the definition of RequestFailedException Class (Azure) and constuctors in the latest version of azure sdk.
RequestFailedException(Int32, String, String, Exception) : gives HTTP status code ,specified error message, error code, and a reference to the inner exception .
And
RequestFailedException(Response)
Gives error message, HTTP status code, error code obtained from the specified response.
The response in the argument represents the HTTP response from the service which has ClientRequestId as one of the properties as shown in the table which gets client request id that was sent to server in the form of x-ms-client-request-id headers.You can try the same while catching the error in the try-catch block.
In exception class you can give
public class RequestFailedException : Exception
{
...
public RequestFailedException(int status, string message, string? errorCode, Exception? innerException) : base(message , innerException) { }
}
Or use RequestFailedException(Response) from which you can get ClientRequestId.
I’ve not tested it myself, but please check if below can be worked around which is taken from the below references or check if something similar can give an idea.Also see if content property can be retrieved as a part of response.
try
{
...
}
catch (Exception aex)
{
foreach (var ex in aex.InnerExceptions)
{
if (ex is RequestFailedException except)
{
var innerException = excep.InnerException;
if (innerException != null && innerException.GetType() == typeof(WebException))
{
WebException webEx = innerException as WebException;
WebResponse resp = webEx.Response;
var responseHeaders = resp.Headers;
string requestId = responseHeaders["x-ms-request-id"];
Console.WriteLine("Request Id: " + requestId);
Console.WriteLine(except.InnerException.Message);
}
else
{
// (not a RequestFailedException)
Console.WriteLine($"{ex.Message}");
}
}
References:
How can I get Request ID when an exception occurs? (microsoft.com)
c# - How can you catch a RequestFailedException if making multiple
DownloadToAsync calls in parallel? - Stack Overflow

Spring Session Redis Auto DeSerializer un-unsed keys

we are using spring-session-data-redis starter, and meet one problem during this process.
We have two application A and B, and want to share same redis between A and B.
the problem is as below:
We call API in application A to add one User object to current Session:(url: http://localhost:9001/test) logic as below.
#RequestMapping("/test")
#ResponseBody
public User addUser(HttpServletRequest httpServletRequest) {
User user = new User("TEST", 10);
HttpSession session = httpServletRequest.getSession(true);
session.setAttribute("SESSION_USER", user);
return user;
}
Then call API in application B to visit another service ( this service is very simple, return a String) (url: http://localhost:9002/test) logic as below.
#RequestMapping("/test")
public String test() {
return "OK";
}
But application B will return error when visit url: http://localhost:9002/test, and application B does not have this class(com.du.demo.demo1.controller.model.User) under classpath..
There was an unexpected error (type=Internal Server Error, status=500).
Could not read JSON: Could not resolve type id 'com.du.demo.demo1.controller.model.User' into a subtype of [simple type, class java.lang.Object]: no such class found at [Source: [B#703e37; line: 1, column: 11]; nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'com.du.demo.demo1.controller.model.User' into a subtype of [simple type, class java.lang.Object]: no such class found at [Source: [B#703e37; line: 1, column: 11]
My question is that whether there are some configuration to skip this? Exception will only throw when we use this object? Just want to stop the automatically deserialize process...

Selenium valid Email test case

I have started writting test cases for a project, The first page is login page.
i have started to write test case for valid email adress validation.
public void LoginValidEmailProvided(string baseUrl)
{
_driver.Navigate().GoToUrl(baseUrl);
UserIdField.Clear();
UserIdField.SendKeys("abc.xyz.com");
PasswordField.Clear();
PasswordField.SendKeys("");
LoginButton.Click();
}
Now my question is do we need to write different function for each variation for valid emaiil address checking.
Like on manual testing test usually do
some.com
#some.com
#some
some#
some###.com
and many more.
so do we have to write test cases for above varaitions in automate testing. or just one variation is suffucient. as I am checking the return message and comparing with expected and what I get. In each case it returns Invalid credentials. So I have just checked is page contains the message Invalid credentials then the Invalid Emaild address test case passed.
Please advise
Thanks
The better approach would be have two methods one to check valid email address and other to check invalid email address
Advantages of having two methods
You can have valid credentials seperately in a file or a data provider(incase of frameworks) and pass valid credentials only to the check valid_email method and invalid credentials to invalid_email method so that if there is any error you can locate it easily(ex : valid credentials is throwing an error saying that the credentials in invalid) if you combine both the credentials then it will be difficult for you to find which is valid and which is invalid
pseudecode :
public void correct_email(){
enter username and other details
click submit
Get the success page or page title of homepage to check email validation passed
}
public void wrong_email(){
enter username and other details
click submit
Get the error page and compare it with the actual error message
}
EDIT :
1.If you're keeping your valid and invalid credentials together and having one method to validate it how do you know if a valid login credentials failed to login it will also throw an error invalid credentials and you're test will pass and you will not notice this error
2.Moreover if you're using frameworks like ex: testng you will get these data in reports if ur parameterizing your tests so in reports also it gives you a clear view of data passed and failed ie)Parameters run using valid credentials and parameters run using invalid credentials .if you use one method to validate vaiid and invalid credentials all will be listed as one.
Hope this helps you.Kindly get back if you have any queries
Do not create a different method you can use data provider for each test !!!
(you can write a rapper that the data provider will look nicer )
http://testng.org/doc/documentation-main.html
//This method will provide data to any test method that declares that its Data Provider
//is named "test1"
#DataProvider(name = "test1")
public Object[][] createData1() {
return new Object[][] {
{ "Cedric", new Integer(36) },
{ "Anne", new Integer(37)},
};
}
//This test method declares that its data should be supplied by the Data Provider
//named "test1"
#Test(dataProvider = "test1")
public void verifyData1(String n1, Integer n2) {
System.out.println(n1 + " " + n2);
}
will print
Cedric 36
Anne 37

How to manipulate LDAP using JNDI on websphere?

I am facing a problem with an LDAP operation. I want to dynamically add a member to an LDAP group when selected by the user from GUI / browser. I paste the code below which works perfectly well when I run it in a Test class (using com.sun.jndi.ldap.LdapCtxFactory). But, when I package it in my build, deploy on websphere app server 7.0 (using com.ibm.websphere.naming.WsnInitialContextFactory), and invoke this method according to user's selection, then I get the error below. I wonder what's wrong I am doing. Doesn't WAS provide implementation of ldap connection factory? I also tried deploying on WAS with the sun's ldap which otherwise works on the Test class, but I am getting the same exception as below. I'd appreciate if anybody can give a clue.
Problem adding member: javax.naming.OperationNotSupportedException: [LDAP: error code 53 - 00000561: SvcErr: DSID-031A120C, problem 5003 (WILL_NOT_PERFORM), data 0
My Code:
public class LDAPManager
{
String GROUPS_OU = "cn=users,dc=mit,dc=hq,dc=com";
public Boolean addMember(String user, String group)
{
Hashtable env = new Hashtable();
String adminName = "CN=Administrator,CN=Users,DC=mit,DC=hq,DC=com";
String adminPassword = "asdfasdf21Q";
String ldapURL = "ldap://mybox451Dev.mit.hq.com:389";
String userName = "CN="+user+",CN=Users,DC=mit,DC=hq,DC=com";
String groupName = "CN="+group+",CN=Users,DC=mit,DC=hq,DC=com";
//env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,adminName);
env.put(Context.SECURITY_CREDENTIALS,adminPassword);
//connect to my domain controller
env.put(Context.PROVIDER_URL, "ldap://mybox451Dev.mit.hq.com:389");
try {
// Create the initial directory context
InitialDirContext ctx = new InitialDirContext(env);
//Create a LDAP add attribute for the member attribute
ModificationItem mods[] = new ModificationItem[1];
mods[0]= new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("member", userName));
//update the group
ctx.modifyAttributes(groupName,mods);
ctx.close();
//System.out.println("Added " + userName + " to " + groupName);
}
catch (NamingException e) {
System.err.println("Problem adding member: " + e);
}
return true;
}
}
I got it solved. Posting solution here, hope this helps someone.
Use the standard JNDI context of sun, not websphere.
Additional properties I was missing in the hashtable, once I added them, it worked like a charm.
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,adminName);
env.put(Context.SECURITY_CREDENTIALS,adminPassword);
env.put(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");
env.put(Context.REFERRAL, "ignore");
Well, it's been more than a year since this question has been asked; so, I don't know answering will add any value. But, here it is. See WAS Javadocs for details on how what that factory class actually does and how it works. You may need to adjust your jndiprovider.properties file for WAS.

WebApi returning wrong status code

I have an operation handler that checks for authentication and throws an exception when authentication fails using
throw new WebFaultException(HttpStatusCode.Unauthorized);
However this still returns a 404 Not Found status code to the client/test client.
This is my operation handler
public class AuthOperationHandler : HttpOperationHandler<HttpRequestMessage, HttpRequestMessage>
{
RequireAuthorizationAttribute _authorizeAttribute;
public AuthOperationHandler(RequireAuthorizationAttribute authorizeAttribute) : base("response")
{
_authorizeAttribute = authorizeAttribute;
}
protected override HttpRequestMessage OnHandle(HttpRequestMessage input)
{
IPrincipal user = Thread.CurrentPrincipal;
if (!user.Identity.IsAuthenticated)
throw new WebFaultException(HttpStatusCode.Unauthorized);
if (_authorizeAttribute.Roles == null)
return input;
var roles = _authorizeAttribute.Roles.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
if (roles.Any(role => user.IsInRole(role)))
return input;
throw new WebFaultException(HttpStatusCode.Unauthorized);
}
}
Am I doing something wrong?
I have good and bad news for you. The framework your are using has evolved into ASP.NET Web API. Unfortunately, OperationHandlers no longer exist. Their closest equivalent are ActionFilters.
Having said that, WCF Web API never supported throwing WebFaultException, that is a vestige of WCF's SOAP heritage. I think the exception was called HttpWebException, however, I never used it, I just set the status code on the response.