How to handle password Strings in ADF Faces? - java

Per company policy (and other recommendations), we should not use String class to handle passwords. Because this objects are immutable and may live until the GC deallocates it, so a "memory inspection" could show a not yet deallocated String containing the password. So the alternative is to use char[] instead and overwrite it contents once is no longer needed. However, when using an
inputText component, the setter method must receive a String.
I have an inputText like:
<af:inputText value="{myBean.password}" secret="true"/>
And
public class MyBean {
...
private transient char[] password;
...
public void setPassword(String password) {
this.password = password.toCharArray();
}
...
public void sumbit(ActionEvent e) {
...
//Wipe password
for(int i = 0 ; i < password.length ; i++) { password[i] = ' '; }
password = null;
}
}
As you can see, there is still a String object containing the password (the argument of the setter), and I don't know how to deal with that value. Is there any way to receive a char[] value? Does the cycle of ADF contemplates the fact that this is a password and should do something special?
This is a server and calling the CG is not a good idea.

One way I could think is passing the value of the password field from client to server in an encrypted format using JavaScript encryption libraries and decrypt it on the server. This way the receiving string will be in a non plain text format.

Instead of keeping the value of the component in the bean, keep a reference to the component itself:
<af:inputText bindings="{myBean.password}" secret="true"/>
......
private RichInputText password;
......
public void setPassword(RichInputText password) {
this.password = password;
}
public RichInputText getPassword() {
return password;
}
and in action listener get the value from the component:
public void sumbit(ActionEvent e) {
char[] pswd = password.getValue().toCharArray();
............
}
Hope this helps.

Related

Convert instanced object to string

I initialize a Password object and I am having trouble using the same object as a string for later purposes like counting the amount of letters in the string. I know that I'm only getting the textual representation of the object with the methods String.valueOf and .toString. How do I go about taking the my object pass and getting the "hello" string I initialized it with?
public class Password {
public Password (String text) {
}
public String getText(){
String string = String.valueOf(this);
return string;
}
public static void main (String[] args) {
Password pass = new Password ("hello");
System.out.println(pass.toString());
}
}
Your actual getText() method doesn't make sense :
public String getText(){
String string = String.valueOf(this);
return string;
}
You try to recreate a String from the toString() method of the Password instance.
It is really not necessary (useless computation) and it is clumsy as toString() is not designed to provide a functional data.
To reach your goal, it is very basic.
Store the text in a field of the Password instance :
public Password (String text) {
this.text = text;
}
And provide a view on the text field.
You could replace getText() in this way :
public String getText(){
return text;
}
Use fields.
public class Password {
private String text; // This is a member (field) It belongs to each
// Password instance you create.
public Password(String value) {
this.text = value; // Copy the reference to the text to the field
// 'text'
}
}
The problem with String.valueOf(this), where this is a Password instance, is that the valueOf() method has absolutely no idea of how to convert a Password instance to a field. You named it "Password", but it could also beMyTextorMySecret. So you need to tell how aPasswordinstance can be displayed as text. In your case, you'll need to just use thetext` field from the abovementioned example.
You should definitely read the docs about classes. I think you're missing something basic.
Note: You should also never store a password into a String, because of security implications, but that's a whole other story, and beyond the scope of your question.

bindFromRequest validation null

I am new to the Java Play Framework and I'm trying to get the authentication to work. So I am following this tutorial: https://www.playframework.com/documentation/2.1.0/JavaGuide4
Here is my code:
public static Result authenticate()
{
Form<Login> loginForm = form(Login.class).bindFromRequest();
return ok(loginForm.toString());
}
public static class Login
{
public String email;
public String password;
public String validate()
{
return "VALIDATE "+email+password;
}
}
In the method autheticate() I can see the submitted values of the form, but the method validate() in the Login class does not see them (the variables are always null).. The output of loginForm.toString() contains:
Form(of=class controllers.Application$Login, data={email=asdf#asdf, password=asdf}, value=None, errors={=[ValidationError(,[VALIDATE nullnull],[])]})
As you can see, the data is received.. But in the validate method the data suddenly is equal to null. So how do I fix this?
You don't mention how you are calling validate() however I think this might do the trick, do something along the lines of:
public static Result authenticate() {
Form<Login> form = form(Login.class).bindFromRequest();
// handle errors
if (!form.hasErrors()) {
Login login = form.get();
Logger.debug(login.validate());
} else {
// bad request
}
}
This works for me.
Method validate in your model should return null if you think that validation has passed, otherwise you should return error message text. Then you need to check form if it contains error by "hasGlobalError" method. globalError is filled when validate() method returns String instead of null. But in your case you should use some model field annotations - https://www.playframework.com/documentation/2.3.x/api/java/play/data/validation/Constraints.html.
If you want to check if form fails on those - then you use "hasErrors" method.
public static class Login {
#Constraints.Email
public String email;
#Constraints.MinLength(value = 6)
public String password;
}
Such model will check if provided emails is really email and if password is longer or equal 6 characters.
ps. Do not use toString on template, you should use render()

Java Play! 2 - password constraints

I can't find an #Equal constraint in Play! 2.
I looked through the API
http://www.playframework.org/documentation/api/2.0.2/java/index.html
I want to have a SignupForm that checks if the passwords are equal. I don't believe that I have to write my own constraint for such a common problem.
Something like:
...
#Min(6)
public String password;
#Equal(password)
public String confirmPassword;
...
I don't any #Equal contraint in other Java framework neither in the JSR 303.
To check for password, it's not difficult: in your form object, just write a public String validate() method:
public class SignupForm {
#Min(6)
public String password;
#Min(6)
public String confirmPassword;
public String validate() {
if(!password.equals(confirmPassword)) {
return "Password mismatch";
}
return null;
}
}
Take a look at the zentask sample, in this class.
In case anyone stumbles across this question from google. This is what I did
#MinLength(6)
public String password;
#MinLength(6)
public String confirmPassword;
public List<ValidationError> validate(){
List<ValidationError> errors = new ArrayList<ValidationError>();
if(!this.password.equals(this.confirmPassword)){
errors.add(new ValidationError("password", "Passwords must match."));
}
return errors.isEmpty() ? null : errors;
}
You have to use #MinLength(6) instead of #Min(6), I think that's because password is a string. Returning a List of validation errors will show up as an error in your form if someone doesn't enter a matching password. Otherwise, they won't see what is wrong.
I found useful information here https://www.playframework.com/documentation/2.2.x/JavaForms
The below code returns global error.
public String validate() {
if(!password.equals(confirmPassword)) {
return "Password mismatch";
}
return null;
}
But the snippet below more specifically returns error specific to confirmPassword field.
public List<ValidationError> validate(){
List<ValidationError> errors = new ArrayList<ValidationError>();
if(!this.password.equals(this.confirmPassword)){
errors.add(new ValidationError("confirmPassword", "Password should be same."));
}
return errors.isEmpty() ? null : errors;
}
Here is the official documentation that describes more on this.

How to pass a variable value from one JFrame to Another JFrame in Netbeans

I have two JFrames login.java and account.java
I need to get the username from the login.java page and put it in a variable in the account.java JFrame. How can I do this in the Java NetBeans using the Swing?
Instead of Using JFrames for passing values between different forms you can use CardLayout which will persist your data which you have entered in the previous form.
All you have to do is Create a JFrameForm and add panels to it.
You can use getter and setter methods...
Set the username in a setter. And using object of login.java use it in account.java through getter...
public class login {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = this.usernameTextField.getText();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = this.passwordTextField.getText();
}
}
Using objects of login.java access getPassword(), getUsername() in account.java.
you need to pass object of login.java to account.java first...
Since you have asked how to pass a variable value from one JFrame to Another JFrame (using swing). So for this put one textbox(tx) and a button(jButton3) in login.java and one label(lx) in account.java where we will print the value of the textbox from login.java .
Type this in login.java :-
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
String msg= tx.getText();
new NewJFrame2(msg).setVisible(true);
}
Then overload constructor in account.java :-
public NewJFrame2(String abc ){
initComponents();
lx.setText(abc);
}
Well you have very nice way to do it.
Define new Static Final Objects of that class.
and Save that value into the Object.
and in other Class u can easily use that objects and as well as that values.
By using
CLASSNAME.OBJECT VALUE.
use that.
The 100% working solution. Suppose u r calling welcome.java
Account ac= new Account(new JFrame(), true);
After this line call a method of welcome.java which u have to create like:
wc.setUser(username);
For account.java
create a method:void setUser(String username) {
user1 = user;
cname.setText(user1);
}
User1 is global variable and available for all which u have to define lke:
String user1;
after it is assigning the username value to user1. here cname is a label which name is cname; so, we are seeting the text of cname to the user.

How deserialize, if lack of some date?

We have two systems: external and internal, which are sharing information in JSON format (GSON library).
Information from an external system comes in internal and processed here.
Everything was very good, coming from an external system data in JSON format in the internal system data deserialize and processed. For example:
come string:
{UserLogInEvent:{userName:'Name', time:'00.00.00'}}
this string deserialize in object of this class:
UserLogInEvent implement Event {
private String userName;
private Date time;
public UserLogInEvent (String userName, Date time)
{
this.userName = userName;
this.time = time;
}
private UserLogInEvent()
{
this.userName = null;
this.time = null;
}
public String getUserName()
{
return this.userName;
}
public Date time()
{
return this.time;
}
}
or other example:
{UserModifyFile: {userName:'Name',fileName: 'index.txt' time:'00.00.00'}}
UserModifyEvent implement Event {
private String userName;
private String fileName;
private Date time;
public UserLogInEvent (String userName, String fileName, Date time)
{
this.userName = userName;
this.fileName = fileName;
this.time = time;
}
private UserLogInEvent()
{
this.userName = null;
this.fileName = null;
this.time = null;
}
public String getUserName()
{
return this.userName;
}
public Date time()
{
return this.time;
}
public String getFileName ()
{
return this.fileName;
}
}
The algorithm is very simple:
string -> deserialization -> object events created.
But .. further problems began. These problems I can not decide ..
Added new events.
Information that comes with an external system does not contain all necessary data about the event, for example:
{UpdateProductInfoEvent: {userName:'name', time: '00.00.00', product: {id:'123', name: '???', type: '???', cost:'???'}}}
As you can see, the line does not contain all the data ... just deserialized not give a desired result ...
To do this, I still need to call a method that will receive information about a product by its Id.
The algorithm is as follows:
JSON string -> processing line -> product information from ID -> object creation * Event.
The following example:
{ModifyProductCatalogEvent:{userName: 'Name', time: '00.00.00', catalog:{id:'321', catalogType:'???', catalogName: '????'}}}
Again I not have all info about catalog...
So, I ask for help, how do I properly construct an algorithm to create objects in case of lack of data?
You can write your own serialization and deserialization methods by overwriting:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
which enables you to handle those cases yourself. You can still use the default methods by using out.defaultWriteObject/in.defaultReadObject to only have to handle the cases where data may be missing (or if you have default values for invalid objects, read all fields with the normal methods and then overwrite the invalid fields with the correct data).
The first question that I would ask is if the code is throwing exceptions? If not, then inspect the object and set the properties/objects to a defaulted state since there is not way to retrieve the data if they did not send it. Or in the constructor of the objects, add initialization code so that the deserializer will have an initialized object to work with.

Categories