Commit fe5aa708 by Tuomas Riihimäki

Argh.. New payara does not allow realm to modify the username (ie add domain, or…

… change login when using rest auth
1 parent 683dce59
......@@ -18,7 +18,9 @@
*/
package fi.codecrew.moya;
public class AuthenticationResult {
import java.io.Serializable;
public class AuthenticationResult implements Serializable {
private String username = null;
private String usertype = null;
......
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>moya-authmodule</artifactId>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.glassfish.main.security</groupId>
......
......@@ -35,4 +35,6 @@ public interface ApiApplicationBeanLocal {
ApiApplicationInstance createApplicationInstance(ApiApplication application);
ApiApplication findApplication(String appKey);
String findUsernameForApikey(String appkey, String userkey, String domain);
}
......@@ -25,6 +25,7 @@ import java.util.List;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
......@@ -114,6 +115,27 @@ public class ApiApplicationBean implements ApiApplicationBeanLocal {
return applicationFacade.findByAppid(appKey);
}
/**
* Note that this function can sould be allowed to be called without principal, ie without domain information.
*
* @param appkey
* @param userkey
* @param domain
* @return
*/
@Override
public String findUsernameForApikey(String appkey, String userkey, String domain) {
LanEvent event = eventBean.getEventForHostname(domain);
if (event == null) {
throw new EJBException("Event not found for domain: " + domain);
}
ApiApplicationInstance instance = instanceFacade.findInstance(appkey, userkey, event);
if (instance == null) {
throw new EJBException("ApiApplicationInstance not found");
}
return instance.getEventuser().getUser().getLogin();
}
@Override
@RolesAllowed(SpecialPermission.S_USER)
public List<ApiApplication> findMyApplications() {
......
......@@ -174,6 +174,9 @@ public class PermissionBean implements PermissionBeanLocal {
@Override
public EventUser getCurrentUser() {
LanEvent event = eventbean.getEventForHostname(getPrincipalDomain());
if (event == null) {
throw new EJBException("Could not find event for current user");
}
EventUser ret = eventUserFacade.findByLogin(getPrincipalName(), event);
if (ret == null) {
ret = getAnonEventUser();
......
......@@ -38,31 +38,37 @@ public class BasicAuthPBean extends ApiAuth implements AuthenticationFormat {
/**
* Authenticate application with username being `null` and password containing basic auth credentials:
* username should be constant 'appauth' and password should contain the following fields delimited by: `:`
* username should be constant 'appauth' and password should contain the following fields delimited by: `:`
* 1) application Id
* 2) application instance authname
* 3) application instance secret
*
*/
@Override
public AuthenticationResult authenticate(String jaasUsername, String password) {
public AuthenticationResult authenticate(final String username, final String password) {
AuthenticationResult ret = null;
String username = UserLoginUtils.getUsernameFromJaasString(jaasUsername);
String domain = UserLoginUtils.getDomainFromJaasString(jaasUsername);
LanEvent event = eventbean.getEventForHostname(domain);
//String username = UserLoginUtils.getUsernameFromJaasString(jaasUsername);
if ((username == null || username.isEmpty()) && password.startsWith(HEADER_PREFIX)) {
if (password.startsWith(HEADER_PREFIX)) {
ret = new AuthenticationResult();
ret.setUsertype(UserType.REST.name());
try {
String domain = UserLoginUtils.getDomainFromJaasString(username);
LanEvent event = eventbean.getEventForHostname(domain);
String[] pwdsplit = password.split(" ");
if (pwdsplit.length != 2) {
logger.warn("Rest auth with Basic failed because pwdsplit != 2: user '{}', password '{}'", username,
password);
logger.warn("Rest auth with Basic failed because pwdsplit != 2: user '{}''", username );
return null;
}
// There is a possibility that user has a password that starts with "Basic ". To combat this,
// we chech that the authdata is really a base64 string. If not, we continue trying with other methods
String authStr = null;
try {
authStr = new String(Base64.getDecoder().decode(pwdsplit[1]), UTF8);
} catch (IllegalArgumentException ie) {
return null;
}
String authStr = new String(Base64.getDecoder().decode(pwdsplit[1]), UTF8);
String[] splitStr = authStr.split(PASSWORD_DELIMITER);
if (splitStr.length != 4 || !PASSWORD_PREFIX.equals(splitStr[0])) {
logger.warn(
......@@ -76,11 +82,11 @@ public class BasicAuthPBean extends ApiAuth implements AuthenticationFormat {
ApiApplicationInstance appInstance = verifyAppInstance(appId, userId, event);
if (appInstance != null && appKey != null && !appKey.isEmpty() && appKey.equals(appInstance.getSecretKey())) {
ret.setUsername(getUsername(appInstance) + '@' + domain);
ret.setUsername(username);
}
} catch (Exception e) {
ret = null;
logger.warn("Invalid base64 string on Rest Basic auth: " + password, e);
}
}
return ret;
......
......@@ -35,7 +35,10 @@ public class RestMacAuthPBean extends ApiAuth implements AuthenticationFormat {
if ((username == null || username.isEmpty()) && password.startsWith(JaasBeanLocal.REST_PREFIX)) {
ret = new AuthenticationResult();
ret.setUsertype(UserType.REST.name());
ret.setUsername(restAuth(password, event) + '@'+domain);
if(restAuth(password, event) != null) {
ret.setUsername(jaasUsername);
}
//ret.setUsername(restAuth(password, event) + '@'+domain);
}
return ret;
}
......
......@@ -21,6 +21,7 @@ package fi.codecrew.moya;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.Principal;
import java.util.Base64;
import javax.ejb.EJB;
import javax.faces.application.ProjectStage;
......@@ -36,15 +37,12 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import fi.codecrew.moya.beans.*;
import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import fi.codecrew.moya.beans.JaasBeanLocal;
import fi.codecrew.moya.beans.LoggingBeanLocal;
import fi.codecrew.moya.beans.RestBeanLocal;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal;
import fi.codecrew.moya.clientutils.BortalLocalContextHolder;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.rest.RestApplicationEntrypoint;
......@@ -67,6 +65,9 @@ public class HostnameFilter implements Filter {
@EJB
private LoggingBeanLocal logbean;
@EJB
private ApiApplicationBeanLocal apibean;
@Override
public void init(FilterConfig config) throws ServletException {
// check if software is in development -mode
......@@ -170,12 +171,14 @@ public class HostnameFilter implements Filter {
try {
httpRequest = (HttpServletRequest) request;
insertServerLoggingContext(httpRequest, authtype);
logger.info("Logging in with username {} and password {}, remote {}, authtype: {}", httpRequest.getUserPrincipal(), httpRequest.getRemoteUser(), httpRequest.getAuthType());
String hostname = parseHostname(httpRequest);
if (httpRequest.getUserPrincipal() == null) {
// Check if we are logging in with rest
if (RestApplicationEntrypoint.REST_PATH.equals(httpRequest.getServletPath())) {
// Check if we are can login in with rest alternative methods ( appkey, basic auth, etc.. )
if (RestApplicationEntrypoint.REST_PATH.equals(httpRequest.getServletPath())
|| "/dydata".equals(httpRequest.getServletPath())) {
authtype = AuthType.REST;
if (!restAuth(httpRequest, response)) {
......@@ -246,12 +249,26 @@ public class HostnameFilter implements Filter {
restAuthStr = httpRequest.getHeader("Authorization");
// }
if (restAuthStr == null && httpRequest.getParameter("appkey") != null) {
String userkey = null;
String appkey = null;
// Payara got updated, and does not allow changing of username anymore, so we must send
// username and domain to initial jaas-login query...
if (restAuthStr != null) {
String decodedStr = new String(Base64.getDecoder().decode(restAuthStr.split(" ")[1]), UTF8);
String[] splitStr = decodedStr.split(":");
appkey = splitStr[1];
userkey = splitStr[2];
// final String appKey = splitStr[3];
} else if (httpRequest.getParameter("appkey") != null) {
appkey = httpRequest.getParameter("appkey");
userkey = httpRequest.getParameter("appuser");
StringBuilder hashBuilder = new StringBuilder();
hashBuilder.append(JaasBeanLocal.REST_PREFIX);
hashBuilder.append(httpRequest.getParameter("appkey")).append(":");
hashBuilder.append(httpRequest.getParameter("appuser")).append(":");
hashBuilder.append(appkey).append(":");
hashBuilder.append(userkey).append(":");
hashBuilder.append(httpRequest.getParameter("appstamp")).append(":");
hashBuilder.append(httpRequest.getParameter("appmac")).append(":");
hashBuilder.append(httpRequest.getPathInfo());
......@@ -259,13 +276,18 @@ public class HostnameFilter implements Filter {
}
boolean ret = true;
String domain = parseHostname(httpRequest);
try {
if (restAuthStr == null) {
throw new ServletException("No auth data");
}
final String username = "@" + parseHostname(httpRequest);
logger.info("Logging in with username {} and password {}", username, restAuthStr);
httpRequest.login(username, restAuthStr);
//final String username = "@" + parseHostname(httpRequest);
String userLogin = apibean.findUsernameForApikey(appkey, userkey, domain);
if (userLogin != null) {
httpRequest.login(userLogin + '@' + domain, restAuthStr);
}
Principal p = httpRequest.getUserPrincipal();
logger.warn("Logged in with rest:{}, ", (p == null) ? null : p.getName());
} catch (ServletException loginEx) {
ret = false;
logger.info("Rest api authentication failed for path " + httpRequest.getPathInfo() + " "
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!