DataSourceSecurityFilter and RAP Client [message #1608187] |
Mon, 09 February 2015 05:39  |
Eclipse User |
|
|
|
Hello,
I tried to configure the DataSourceSecurityFilter in the RAP configi.ini and added the mysql driver to dependencies of the *-rap-dev.product.
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#active=true
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#realm=bbk Development
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#jdbcDriverName=com.mysql.jdbc.Driver
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#jdbcMappingName=jdbc:mysql://127.0.0.1:3306/BFZ
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#jdbcUsername=admin
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#jdbcPassword=changeme
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#selectUserPass=SELECT LOWER(username), id, countyid, seclevel FROM Users WHERE LOWER(username)=? AND PASSWORD=?
When starting the rap client i get the following exception:
HTTP ERROR: 500
Problem accessing /web. Reason:
javax.servlet.ServletException: com.mysql.jdbc.Driver cannot be found by org.eclipse.scout.rt.server.commons_4.3.0.20150112-1427
Powered by Jetty://
What am I missing?
Thanks,
Peter
|
|
|
|
|
|
|
Re: DataSourceSecurityFilter and RAP Client [message #1614864 is a reply to message #1614499] |
Fri, 13 February 2015 09:51   |
Eclipse User |
|
|
|
Ok I took some time on your problem.
Peter Pfeifer wrote on Fri, 13 February 2015 10:32Isn't the mysql driver included in the com.bsiag.scout.rt.server.jdbc.mysql5117 bundle
You can find out by doing CTRL+SHIFT+T and search for "com.mysql.jdbc.Driver".
The Editor show nothing but a "Source not found" error.
If you have clicked "Link with Editor" button (the one with the 2 yellow arrows) in the Package Explorer, you will find out where the class is.
=> com.mysql.jdbc_5117.fragment
You can add this fragment to the list ("Dependencies" Tab in the Product File Editor).
Peter Pfeifer wrote on Mon, 09 February 2015 13:26I tried to add the mysql bundle to the rap project plugin xml too. But then the RAP server refuses to startup at all...
If you do so, you will have a product validation problem (the dependencies declared in the MANIFEST.MF are not all fulfilled).
(I assume you have added the mysql bundle com.bsiag.scout.rt.server.jdbc.mysql5117 to the rap-dev product xml file. You can not add dependency to plugin.xml)
When you validate your product, you have a "missing requirement con" error, because com.bsiag.scout.rt.server.jdbc.mysql5117 has a dependency to:
* Package: com.mysql.jdbc [1]
* Bundle: org.eclipse.scout.rt.server [2]
You can fulfill the requirement [1] by adding the fragment " com.mysql.jdbc_5117.fragment " into the list. But you cannot fulfill requirement [2] because you do not have the server code in your rap project (it is the Scout client).
At the end if you look what is in the com.bsiag.scout.rt.server.jdbc.mysql5117 bundle you will notice that this is not necessary (You have for example AbstractMySqlSqlService that is not necessary).
On the dependency topic, I recommend you my forum post where I tried to explain target-platform, target-definition, product file...
----
If you look at DataSourceSecurityFilter.negotiate(HttpServletRequest, HttpServletResponse, PrincipalHolder) you will notice that the password parameter (passEncrypted) passed to DataSourceSecurityFilter.isValidUser(String, String) is the Base64 encryption of the Password entered by the in the login box.
Your statement should probabely look more like:
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#selectUserPass=SELECT LOWER(username), id, countyid, seclevel FROM Users WHERE LOWER(username)=? AND TO_BASE64(PASSWORD)=?
----
I have asked my coworker what is the state of the art solution of your problem.
In our vision the RAP-Server (aka Scout Client) does not connect to the database.
The solution was presented at the EclipseCon Europe 2012. See the slides: 20121022_BahBah_Slides.pdf
On slide 23 you will see the overview:

The RAP-Scout-Client has a BasicForwardSecurity filter who will ask the "/auth" servlet on the Scout Server. This servlet is available without any password.
The Server will be responsible to log the user in. This way you have your Database configuration at one single point (the server) and the RAP-Scout-Client knows nothing the Database.
If you do not have a desktop client, you do not need the "/process" servlet in the server.
You can check the Bahbah Chat demo application where this is implemented.
[Updated on: Tue, 21 April 2015 04:58] by Moderator
|
|
|
Re: DataSourceSecurityFilter and RAP Client [message #1615935 is a reply to message #1614864] |
Sat, 14 February 2015 02:34   |
Eclipse User |
|
|
|
Hello Jeremie,
thanks for the explanations.
Jeremie Bresson wrote on Fri, 13 February 2015 14:51
I have asked my coworker what is the state of the art solution of your problem.
In our vision the RAP-Server (aka Scout Client) does not connect to the database.
The solution was presented at the EclipseCon Europe 2012. See the slides: 20121022_BahBah_Slides.pdf
On slide 23 you will see the overview:

The RAP-Scout-Client has a BasicForwardSecurity filter who will ask the "/auth" servlet on the Scout Server. This servlet is available without any password.
The Server will be responsible to log the user in. This way you have your Database configuration at one single point (the server) and the RAP-Scout-Client knows nothing the Database.
If you do not have a desktop client, you do not need the "/process" servlet in the server.
You can check the Bahbah Chat demo application where this is implemented.
Ok. I think I know what you mean. But I have to look further through the code. But if this is more or less the reference implementation of how to authenticate web users, wouldn't this be worth a wiki entry? Since there only securityfilters are mentioned?
Jeremie Bresson wrote on Fri, 13 February 2015 14:51
If you look at DataSourceSecurityFilter.negotiate(HttpServletRequest, HttpServletResponse, PrincipalHolder) you will notice that the password parameter (passEncrypted) passed to DataSourceSecurityFilter.isValidUser(String, String) is the Base64 encryption of the Password entered by the in the login box.
Your statement should probabely look more like:
org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter#selectUserPass=SELECT LOWER(username), id, countyid, seclevel FROM Users WHERE LOWER(username)=? AND TO_BASE64(PASSWORD)=?
This would mean that the password is stored as plain text in the database. I hope nobody is doing that 
Thanks
Peter
[Updated on: Tue, 21 April 2015 04:58] by Moderator
|
|
|
|
|
|
|
Re: DataSourceSecurityFilter and RAP Client [message #1642818 is a reply to message #1636872] |
Sun, 01 March 2015 03:10   |
Eclipse User |
|
|
|
Yeah, default implementation uses md5 hashes. I came up with something which (I think) is workable. I based my solution on the following article (which for anyone interested provides a fairly succinct all-you-need-to-know explanation of password security): https://crackstation.net/hashing-security.htm.
The first part of my solution is to copy a PBKDF2 hashing algorithm (PasswordHash.java) directly from the crackstation.net website. Other than a package declaration, it requires no modification.
The second part is the security filter implementation, which inherits heavily from DataSourceSecurityFilter:
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
import org.eclipse.scout.rt.server.commons.servletfilter.FilterConfigInjection;
import org.eclipse.scout.rt.server.commons.servletfilter.security.DataSourceSecurityFilter;
/**
* @author Marco Dörfliger
*/
public class SaltedDataSourceSecurityFilter extends DataSourceSecurityFilter {
private static final IScoutLogger LOG = ScoutLogManager.getLogger(SaltedDataSourceSecurityFilter.class);
private String m_selectStatement;
@Override
public void init(FilterConfig config0) throws ServletException {
super.init(config0);
FilterConfigInjection.FilterConfig config = new FilterConfigInjection(config0, getClass()).getAnyConfig();
m_selectStatement = config.getInitParameter("selectUserPass");
if (m_selectStatement == null) {
throw new ServletException("Missing init-param with name 'selectUserPass'.");
}
}
@Override
protected String encryptPass(String pass) throws ServletException {
return pass;
}
/**
* The selectStatement parameter should be set to something like
* "SELECT PASSWORD FROM USERS WHERE ACCOUNT_LOCKED=0 AND LOWER(USERNAME)=?"
*/
@Override
protected boolean isValidUser(String username, String password, Connection connection) throws SQLException {
PreparedStatement stmt = null;
try {
stmt = connection.prepareStatement(m_selectStatement);
stmt.setString(1, username);
stmt.execute();
ResultSet resultSet = stmt.getResultSet();
return (resultSet.next() && PasswordHash.validatePassword(password, resultSet.getString(1)));
}
catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
LOG.error("Exception occurred validating password", e);
return false;
}
finally {
try {
if (stmt != null) {
stmt.close();
stmt = null;
}
}
catch (SQLException e) {
LOG.warn("Exception in close stmt!", e);
}
}
}
public static void main(String[] args) throws ServletException {
SaltedDataSourceSecurityFilter sdssf = new SaltedDataSourceSecurityFilter();
System.out.println("'sausages' encrypts to " + sdssf.encryptPass("sausages"));
}
}
The matching configuration lines in config.ini are as follows:
com.mycompany.myproject.server.services.common.security.SaltedDataSourceSecurityFilter#active=true
com.mycompany.myproject.server.services.common.security.SaltedDataSourceSecurityFilter#realm=development
com.mycompany.myproject.server.services.common.security.SaltedDataSourceSecurityFilter#jdbcDriverName=org.postgresql.Driver
com.mycompany.myproject.server.services.common.security.SaltedDataSourceSecurityFilter#jdbcMappingName=jdbc:postgresql://localhost:5432
com.mycompany.myproject.server.services.common.security.SaltedDataSourceSecurityFilter#jdbcUsername=appuser
com.mycompany.myproject.server.services.common.security.SaltedDataSourceSecurityFilter#jdbcPassword=dbpassword
com.mycompany.myproject.server.services.common.security.SaltedDataSourceSecurityFilter#selectUserPass=SELECT PASSWORD FROM USERS WHERE ACCOUNT_LOCKED=0 AND LOWER(USERNAME)=?
Finally, you need to update the extension in the server plugin.xml file, and replace the DataSourceSecurityFilter with the SaltedDataSourceSecurityFilter as follows:
<filter
aliases="/process /remotefiles /updatesite"
class="com.mycompany.myproject.server.services.common.security.SaltedDataSourceSecurityFilter"
ranking="40">
</filter>
Afaik the password is still sent "in the clear" from client to server which could be improved upon, but this is a step in the right direction I think.
[Updated on: Sun, 01 March 2015 03:14] by Moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.05774 seconds