Authentication and Authorization in RAP [message #1248801] |
Mon, 17 February 2014 12:24  |
Eclipse User |
|
|
|
Hi,
I have an application available in SWT and RAP.
Currently i have authentication working on SWT client with a custom security filter (that connects with a remote service).
On RAP, i would like to have a similar solution compared with SWT, meaning the only place that knows to talk with remote services is the server (it requires a bunch of legacy libraries and configuration).
Is it possible to put the RAP client talking with server security in order to authenticate the webuser?
Will this mechanism impact scout Authorization mechanisms??
Thanks for your help
|
|
|
|
|
Re: Authentication and Authorization in RAP [message #1251753 is a reply to message #1249837] |
Thu, 20 February 2014 10:10  |
Eclipse User |
|
|
|
Hi,
i have managed to have authentication working in RAP and SWT, both solutions using a custom scout service provided by the server.
SWT
-----
Custom filter defined on the server that calls the scout service:
protected boolean login(final SortedSet<Credential> theUpdatedCredentials) {
ServerJob job = new ServerJob("security-filter-job", new ServerSession()) {
@Override
protected IStatus runTransaction(IProgressMonitor monitor) throws Exception {
//Here you can call serviceS.getservice(..)
//Use the status to decide if the user is valid or not.
Authentication anAuthentication = SERVICES.getService(IAuthenticationService.class).doAuthenticate(theUpdatedCredentials);
//Return a status depending on result
if (anAuthentication.isAuthenticated())
{
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
}
};
IStatus status = job.runNow(new NullProgressMonitor());
if (status.isOK()) {
return true;
}
return false;
}
...
For RAP, it was not easy. The only option i have found was to create a custom authentication servlet in scout server (declared in server plugin.xml) and then call it from the RAP security filter.
For the servlet code i have:
public class AuthenticationServlet extends ServiceTunnelServlet {
/**
* The long <code>serialVersionUID</code>.
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws IOException, ServletException {
// creates the credential set with mandatory credentials (user and pass)
SortedSet<Credential> aCredentialsSet = new TreeSet<Credential>();
// fill the empty credentials with values received in http headers
if (fillCredentials(aCredentialsSet, theReq)) {
if (login(aCredentialsSet)) {
{
theResp.setStatus(HttpServletResponse.SC_OK);
return;
}
}
}
theResp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
/**
* Invokes the custom server security service to perform the authentication based on credentials.
*
* @param theUpdatedCredentials
* @return true if login has success
*/
protected boolean login(final SortedSet<Credential> theUpdatedCredentials) {
ServerJob job = new ServerJob("security-filter-job", new ServerSession()) {
@Override
protected IStatus runTransaction(IProgressMonitor monitor) throws Exception {
//Here you can call serviceS.getservice(..)
//Use the status to decide if the user is valid or not.
Authentication anAuthentication = SERVICES.getService(IAuthenticationService.class).doAuthenticate(theUpdatedCredentials);
//Return a status depending on result
if (anAuthentication.isAuthenticated())
{
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
}
};
IStatus status = job.runNow(new NullProgressMonitor());
if (status.isOK()) {
return true;
}
return false;
}
...
In RAP security filter :
public class DialogSecurityFilter extends AbstractChainableSecurityFilter {
/**
* the prop used to control the filter
* The String <code>PROP_BASIC_ATTEMPT</code>.
*/
public static final String PROP_BASIC_ATTEMPT = "BasicSecurityFilter.basicAttempt";
@Override
protected int negotiate(HttpServletRequest theReq, HttpServletResponse theResp, PrincipalHolder theHolder) throws IOException, ServletException {
String aUser;
// get user name and password from request and try to efectuate the login
if ((aUser = login(theReq)) != null) {
{
//updates the holder with a new principal with user name
theHolder.setPrincipal(new SimplePrincipal(aUser));
return STATUS_CONTINUE_WITH_PRINCIPAL;
}
}
int attempts = getBasicAttempt(theReq);
if (attempts > 2) {
return STATUS_CONTINUE_CHAIN;
}
else {
setBasicAttept(theReq, attempts + 1);
theResp.setHeader("WWW-Authenticate", "Basic realm=\"" + getRealm() + "\"");
return STATUS_CONTINUE_CHAIN;
}
}
/**
* Call a server authentication servlet responsable for user authentication
*
* @param theReq
* @return the user name if login succeeds
*/
protected String login(HttpServletRequest theReq) {
URL aAuthServlet = null;
try {
String h = theReq.getHeader("Authorization");
if (h != null && h.matches("Basic .*")) {
String[] a = new String(Base64Utility.decode(h.substring(6)), "ISO-8859-1").split(":", 4);
String user = unescapeColon(a[0].toLowerCase());
String pass = unescapeColon(a[1]);
// TODO we should get server base url from configuration
aAuthServlet = new URL("localhost/example_server/auth?user=" + user + "&pass=" + pass);
HttpURLConnection servletConnection = (HttpURLConnection) aAuthServlet.openConnection();
servletConnection.setRequestMethod("GET");
servletConnection.connect();
int aResultStatus = servletConnection.getResponseCode();
if (aResultStatus == HttpServletResponse.SC_OK) {
return user;
}
}
}
catch (Exception e) {
// TODO
e.printStackTrace();
}
return null;
}
...
The code is still a proof of concept, so if you have a better suggestion please tell me.
Thanks
|
|
|
Powered by
FUDForum. Page generated in 0.03757 seconds