How to create custom user in esapi - java

How can I create my own user class with additional properties in it?
I tried to create my own user class by implementing org.owasp.esapi.User interface and added some extra properties.
public class MyUserClass implements User{
then I tried this
MyUserClass userClass=(MyUserClass) ESAPI.authenticator().getCurrentUser();
But getting this exception:
SecurityConfiguration for Logger.LogEncodingRequired not found in ESAPI.properties. Using default: false
java.lang.ClassCastException: org.owasp.esapi.reference.DefaultUser cannot be cast to com.bean.MyUserClass
I also tried to extend DefaultUser class but error was same.

The "exception" you are posting is actually two different items: (1) a log message, and (2) an actual exception. And while these are different items altogether, they still stem from the same underlying issue.
Short answer: You are forgetting to set your security configuration system property when your app initializes. It should look something like this:
System.setProperty("org.owasp.esapi.SecurityConfiguration",
"org.you.yourapp.YourAppSecurityConfiguration");
Where org.you.yourapp.YourAppSecurityConfiguration is the name of a class you'll write that implements SecurityConfiguration. Because you are failing to set this system property, when the following ESAPI code runs:
private static String securityConfigurationImplName =
System.getProperty("org.owasp.esapi.SecurityConfiguration",
"org.owasp.esapi.reference.DefaultSecurityConfiguration");
...then since you never set the property, ESAPI is selecting the DefaultSecurityConfiguration for you.
When this DefaultSecurityConfiguration goes to initialize ESAPI's internal logging system, the following method is called:
protected String getESAPIProperty( String key, String def ) {
String value = properties.getProperty(key);
if ( value == null ) {
logSpecial( "SecurityConfiguration for " + key + " not found in ESAPI.properties. Using default: " + def, null );
return def;
}
return value;
}
The property it's looking for here is a boolean called Logger.LogEncodingRequired. So if you want this first message to go away, you need something like:
boolean logEncodingRequired = true; // or false, your choice
System.setProperty("Logger.LogEncodingRequired", logEncodingRequired);
That takes care of your first issue:
SecurityConfiguration for Logger.LogEncodingRequired not found in ESAPI.properties. Using default: false
Your second issue is also a result of ESAPI choosing a DefaultSecurityConfiguration for you. This default configuration has an authenticator() method that returns an instance of FileBasedAuthenticator. And as that javadoc link explains, you need to have a users.txt file on your runtime classpath that contains all the serialized information about your users. And, of course, the FileBasedAuthenticator returns instances of DefaultUser which is why you're getting the 2nd issue (which is an actual exception):
java.lang.ClassCastException: org.owasp.esapi.reference.DefaultUser cannot be cast to com.bean.MyUserClass.
Because you can't cast the DefaultUser (passed back from the FileBasedAuthenticator) to your own MyUser class.
Confused? It's really not so bad. Just implement your own SecurityConfiguration and set it as a system property, and you will be all set. HTH.

Related

AspectJ trouble using around advice and ProceedingJoinPoint

I'm new to AOP and I need to use AspectJ on my project.
I need to use around advice but I have a problem using it, I've the following code in my .aj class,
pointcut checkUser(ProceedingJoinPoint jp,User user): call(* com.example.UserAccount.MyUI.checkUser(..))&& args(jp,user);
void around(ProceedingJoinPoint jp,User user) throws Throwable : checkUser(jp,user){
// Condition checks one of the user boolean property
if(condition){
jp.proceed();
}else{
// Do nothing
}
}
but I get this warning all the time,
advice defined in Aspects.UserAccount has not been applied [Xlint:adviceDidNotMatch]
By the way, I tried it without ProceedingJoinPoint and tried just proceed(); but then got this warning, too few arguments to proceed, expected 1
I'm thankful for any single help or hint!
Reza
First I recommend to read the AspectJ documentation in order to learn the syntax. As you are using native AspectJ syntax, this is like learning a new programming language or at least a Java extension. What you are doing is mix native syntax with annotation-based syntax. Try to stick with one. I am sure that you did not find this in any tutorial but ended up with that syntax via trial and error.
You do not need to bind a joinpoint parameter in native syntax because it is there implicitly and automatically. The automatically bound joinpoint is always named thisJoinPoint as all tutorials surely show you. Only in annotation-based syntax you need to bind the joinpoint and can name it as you wish, but even then I recommend to stick with thisJoinPoint because then refactoring from annotation to native syntax is easier and your eyes get used to spotting that variable name in your aspect code.
The warning you get means that the pointcut you defined does not match any part of your code, at least not any part which is visible to the aspect weaver or compiler. There could be plenty of reasons why this can occur, e.g. misspelled package or class names, wrong around advice return type (return type must be Object for non-void methods or more specifically match what the method you want to intercept returns). Assuming that e.g. checkUser(..) returns a boolean, the around advice should do the same. I made up an example using your package and class names. Besides, package names should be lower-case but I used yours, assuming they are really package names and not inner classes:
Helper class:
package com.example.UserAccount;
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override
public String toString() {
return "User(" + name + ")";
}
}
Class targeted by aspect + sample main method:
package com.example.UserAccount;
public class MyUI {
public boolean checkUser(User user) {
return user.getName().toUpperCase().contains("ADMIN");
}
public static void main(String[] args) {
MyUI ui = new MyUI();
System.out.println(ui.checkUser(new User("Administrator")));
System.out.println(ui.checkUser(new User("john")));
System.out.println(ui.checkUser(new User("xander")));
System.out.println(ui.checkUser(new User("admiral")));
System.out.println(ui.checkUser(new User("SySaDmiN")));
}
}
As you can see, we expect an output of "true" for the first and last entry, but "false" for the ones in between due to the check logic I made up for checkUser(..).
Now let us write an aspect which also returns "true" for a user named "Xander", e.g. in order to give him admin rights or whatever. I am making this up because you did not provide an MCVE as you always should on StackOverflow, but just an incoherent code snippet which keeps everyone trying to answer your question guessing what the heck you might want to achieve and how to reproduce your problem.
Aspect:
package Aspects;
import com.example.UserAccount.User;
import com.example.UserAccount.MyUI;
public aspect UserAccount {
pointcut checkUser(User user) :
execution(boolean MyUI.checkUser(*)) && args(user);
boolean around(User user) : checkUser(user) {
System.out.println(thisJoinPoint + " -> " + user);
if (user.getName().equalsIgnoreCase("xander"))
return true;
return proceed(user);
}
}
I just imported the MyUI class, so there is no need to use a fully-qualified class name here. Again, this is an advantage of native syntax, in annotation-based syntax you would have to use the fully qualified name.
I also replaced the generic * MyUI.checkUser(..) (which would also work) by the more explicit boolean MyUI.checkUser(*) because we already know that the method returns a boolean and has exactly one parameter, which both we assume anyway by returning a boolean from the around advice and by binding exactly one parameter via args(). You could also be even more specific and use boolean MyUI.checkUser(User).
Furthermore, I am using execution() rather than call() because it is more efficient, as it weaves the advice code just into the executing method once instead of five times for each method call in the main method. You only need to use call() if the MyUI class is out of reach of the AspectJ weaver/compiler, i.e. because it is not in the module you compile with AspectJ Maven.
Console log:
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(Administrator)
true
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(john)
false
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(xander)
true
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(admiral)
false
execution(boolean com.example.UserAccount.MyUI.checkUser(User)) -> User(SySaDmiN)
true
Et voilà, the aspect works. It makes the target method return "true" for user "xander".

Java properties file validation

My Java application loads a properties file at startup, which contains key-value pairs. I can set and retrieve the expected properties successfully.
However, as it stands the properties file can contain any property name I care to put in there. I'd like to be able to restrict the properties to a specific set, some of which are mandatory and others optional.
I can manually check each loaded property against a valid set but I was wondering if there was a more elegant way to do this. E.g. perhaps some way to declare the expected mandatory/optional properties, so that when the properties file is loaded, an exception is thrown if an invalid or missing property is detected. Similar to the kind of thing boost::program_options offers in C++.
Since Properties is already a simple iterable structure, I would just perform your validation against that object. Below is a simple validation of required vs optional.
public static void testProps(Properties props, Set<String> required, Set<String> optional) {
int requiredCount=0;
Enumeration keys = props.keys();
while (keys.hasMoreElements()) {
String key=(String) keys.nextElement();
if (required.contains(key)) {
requiredCount++;
} else if (!optional.contains(key)) {
throw new IllegalStateException("Unauthorized key : " + key);
}
}
if (requiredCount<required.size()) {
for (String requiredKey : required) {
if (!props.containsKey(requiredKey)) {
throw new IllegalStateException("Missing required key : " + requiredKey);
}
}
}
}
I can manually check each loaded property against a valid set but I
was wondering if there was a more elegant way to do this. E.g. perhaps
some way to declare the expected mandatory/optional properties, so
that when the properties file is loaded, an exception is thrown if an
invalid or missing property is detected.
The built-in API of the JDK (java.util.Properties) do not offer this kind of validation.
However, it should not be difficult to implment your own ConfigLoader class which does this. Your class could wrap java.util.Properties, and validate the data after loading. You could for example maintain a list of mandatory and optional keys (hardcoded, or loaded externally), and then check the list of loaded keys against these lists.
It's possible you could find some implementation which does this, but as the validation itself will be specific to your needs anyway, and the rest is fairly simple, I don't think it's worth hunting for an existing solution.

Append type level validation error message to specific field

I've got a simple class which get's validated using the boolean isValid() method, which works and of course the error message is at class/type level.
Here's my simple class:
public class NewPasswordDTO {
#NotNull
public String password;
#NotNull
public String confirmation;
#AssertTrue(message="Passwords must match.")
protected boolean isValid() {
return password.equals(confirmation);
}
}
But what I really want is something like that:
public class NewPasswordDTO {
#NotNull
#Equals("confirmation", message="...")
public String password;
#NotNull
public String confirmation;
}
So the error message would be set at field level and not at class/type level.
Is this possible somehow? Maybe using a custom Validator for that class?
Thanks in advance!
SOLUTION:
Thanks to Gunnar! I've just came up with a nice, universal solution :-). I simply used (means copy & paste) the code from Hibernates #ScriptAssert and ScriptAssertValidator and modified it slightly:
#ScriptAssert:
Add new String field(). (this is where the error message gets appended)
ScriptAssertValidator:
Inside the initialize method, make sure to also save the fieldName and message properties, because we need to access them in the next step
Add this snippet at the bottom of isValid method:
context.buildConstraintViolationWithTemplate(errorMessage)
.addPropertyNode(fieldName).addConstraintViolation();
Also add context.disableDefaultConstraintViolation(); somewhere inside the isValid method to not generate the default error message which else would get appended at class level.
And that's it. Now I can use it like that:
#FieldScriptAssert(lang="javascript", script="_this.password.equals(_this.confirmation)", field="password", message="...")
public class NewPasswordDTO { ... }
You either could use the #ScriptAssert constraint on the class (note that a constraint should always be side-effect free, so it's not a good idea to alter the state of the validated bean; instead you should just check whether the two fieldss match) or you implement a custom class-level constraint.
The latter also allows to point to a custom property path for the constraint violation, which it allows to mark the "confirmation" property as erroneous instead of the complete class.
Simple answer : It is not (unless you implement it) :http://docs.oracle.com/javaee/6/api/javax/validation/constraints/package-summary.html shows all annotation constraints.
Of course you could inject your string as a resource in your class by #producer and so on (which recently is discussed to be removed in jdk8), but you could not use this value for your assert. In reply to the comment:
This was asuming that the nature is a constant string which you would like to use as a string resource.And then of course it is possible to write your own class based on java.lang.string with a #Producer which is then #Inject - able. Though it is certainly not the way I personally would deal with constant strings.
If you’re using the Spring Framework, then as an alternative to the #ScriptAssert using a JSR 223 scripting, you can use the #SpELAssert that uses the Spring Expression Language (SpEL). The advantage is that it doesn’t need any JSR 223 compliant scripting engine which may not be available on some environments. See this answer for more information.

Problem using GWT-VL?

I'm trying to evaluate GWT validation library with a very simple example taken from the author site.
and here is a code snippet
validator.addValidators( "birthYear",new IntegerValidator(schoolName_txt, 1890, 2009)
.addActionForFailure(new StyleAction("validationFailedBorder"))
.addActionForFailure(new LabelTextAction(error_label))
);
but the problem is that when I run the application I got the following error:
no property localization given for key: birthYear
but I'm sure that I have included this key in my localization files,so what is this?
Thanks
To get rid of this error message you have to extend ValidationMessages:
import eu.maydu.gwt.validation.client.i18n.ValidationMessages;
public class CustomValidationMessages extends ValidationMessages {
#Override
public String getPropertyName(String propertyName) {
return propertyName; // This just returns the property name instead of the error message
}
}
Then change pass an instance of this class to the ValidationProcessor instance instead of just an empty parameter:
ValidationProcessor validator = new DefaultValidationProcessor(new CustomValidationMessages());
The purpose of this I suppose to give you a chance to change the displayed input name in the error message if your app is multi-language.

com.sun.jdi.InvocationException occurred invoking method

I just want to create an object of class, but got this error when debugging. Can anybody tell me what the problem is? The location of this code is in some Spring(2.5) Service class.
There is a similar problem: OJB Reference Descriptor 1:0 relationship? Should I set auto-retrieve to false?
Thanks a lot~
The root cause is that when debugging the java debug interface will call the toString() of your class to show the class information in the pop up box, so if the toString method is not defined correctly, this may happen.
I also had a similar exception when debugging in Eclipse. When I moused-over an object, the pop up box displayed an com.sun.jdi.InvocationException message. The root cause for me was not the toString() method of my class, but rather the hashCode() method. It was causing a NullPointerException, which caused the com.sun.jdi.InvocationException to appear during debugging. Once I took care of the null pointer, everything worked as expected.
Well, it might be because of several things as mentioned by others before and after. In my case the problem was same but reason was something else.
In a class (A), I had several objects and one of object was another class (B) with some other objects. During the process, one of the object (String) from class B was null, and then I tried to access that object via parent class (A).
Thus, console will throw null point exception but eclipse debugger will show above mentioned error.
I hope you can do the remaining.
For me the same exception was thrown when the toString was defined as such:
#Override
public String toString() {
return "ListElem [next=" + next + ", data=" + data + "]";
}
Where ListElem is a linked list element and I created a ListElem as such:
private ListElem<Integer> cyclicLinkedList = new ListElem<>(3);
ListElem<Integer> cyclicObj = new ListElem<>(4);
...
cyclicLinkedList.setNext(new ListElem<Integer>(2)).setNext(cyclicObj)
.setNext(new ListElem<Integer>(6)).setNext(new ListElem<Integer>(2)).setNext(cyclicObj);
This effectively caused a cyclic linked list that cannot be printed. Thanks for the pointer.
I was facing the same issue because I was using Lombok #Data annotation that was creating toString and hashcode methods in class files, so I removed #Data annotation and used specific #Gettter #Setter annotation that fixed my issue.
we should use #Data only when we need all #ToString, #EqualsAndHashCode, #Getter on all fields, and #Setter on all non-final fields, and #RequiredArgsConstructor.
I had the same issue once. In my case toString() method was badly created. TO be precise a static final variable was included in the toString method when a developer form my team was assigned code cleaning task and to add toString(), hashCode() code and equals() methods to domain objects where ever possible. but in of the classes because of over looking at it, he included final static variable that caused the "com.sun.jdi.InvocationException" this exception was visible on debugging only when I hovered over the object which has the exception.
I got similar exception in Eclipse. This was due to java.lang.StackOverflowError error. I had overriden toString() method in child class, having JoinColumn, which was returning string using object of parentclass, resulting in circular dependency. Try to remove that object from toString(), and it will work.
Disabling 'Show Logical Structure' button/icon of the upper right corner of the variables window in the eclipse debugger resolved it, in my case.
so I had same problem here. Found out that my domain instance was getting detached from the hibernate session. I used isAttached() to check and attached the domain using d.attach()
This was my case
I had a entity Student which was having many-to-one relation with another entity Classes (the classes which he studied).
I wanted to save the data into another table, which was having foreign keys of both Student and Classes. At some instance of execution, I was bringing a List of Students under some conditions, and each Student will have a reference of Classes class.
Sample code :-
Iterator<Student> itr = studentId.iterator();
while (itr.hasNext())
{
Student student = (Student) itr.next();
MarksCardSiNoGen bo = new MarksCardSiNoGen();
bo.setStudentId(student);
Classes classBo = student.getClasses();
bo.setClassId(classBo);
}
Here you can see that, I'm setting both Student and Classes reference to the BO I want to save. But while debugging when I inspected student.getClasses() it was showing this exception(com.sun.jdi.InvocationException).
The problem I found was that, after fetching the Student list using HQL query, I was flushing and closing the session. When I removed that session.close(); statement the problem was solved.
The session was closed when I finally saved all the data into table(MarksCardSiNoGen).
Hope this helps.
I have received com.sun.jdi.InvocationException occurred invoking method when I lazy loaded entity field which used secondary database config (Spring Boot with 2 database configs - lazy loading with second config does not work). Temporary solution was to add FetchType.EAGER.
There could be two reasons an element doesn't exist:
Bad xpath (//*[#id'forgotQuote])
Correct xpath but no element (//*[contains(text(),'This text is not in the page')])
Would you get com.sun.jdi.InvocationException in either case when you are running Debug and you hover your mouse over a reference to the WeBElement (this with Selenium and Java)???
We use the following, but can't distinguish if it returns false due to bad xpath or non-existent element (valid xpath syntax):
public static boolean isElementDisplayed(WebElement element) {
boolean isDisplayed = false;
try {
isDisplayed = element.isDisplayed();
} catch (NoSuchElementException e) {
;// No Worries
}
return isDisplayed;
}
Removing hashCode() and equals() solved my issue. In my case, I used Apache's commons-lang hash code and equals builders for creating non-static classes manually, so the compiler didn't throw any exception. But at runtime it caused the invocation exception.
In my case it was due to the object reference getting stale.
I was automating my application using selenium webdriver, so i type something into a text box and then it navigates to another page, so while i come back on the previous page , that object gets stale.
So this was causing the exception, I handled it by again initialising the elements -
PageFactory.initElements(driver, Test.class;
I also faced the same problem. In my case I was hitting a java.util.UnknownFormatConversionException. I figured this out only after putting a printStackTrace call. I resolved it by changing my code as shown below.
from:
StringBuilder sb = new StringBuilder();
sb.append("***** Test Details *****\n");
String.format("[Test: %1]", sb.toString());
to:
String.format("[Test: %s]", sb.toString());
I faced the same problem once. In my case it was because of overridden equals method. One values was coming null.

Categories

Resources