Skip to content

Commit

Permalink
Merge pull request #1645 from akto-api-security/feature/google_saml_s…
Browse files Browse the repository at this point in the history
…so_saas

Feature/google saml sso saas
  • Loading branch information
avneesh-akto authored Oct 21, 2024
2 parents ca9b2af + 2466899 commit eafe109
Show file tree
Hide file tree
Showing 32 changed files with 968 additions and 426 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ public String updateUsernameAndOrganization() {
return Action.SUCCESS.toUpperCase();
}

private String userEmail;

public Map<Integer, Integer> getRiskScoreCountMap() {
return riskScoreCountMap;
}
Expand Down Expand Up @@ -404,4 +406,8 @@ public String getOrganization() {
public void setOrganization(String organization) {
this.organization = organization;
}

public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
}
3 changes: 0 additions & 3 deletions apps/dashboard/src/main/java/com/akto/action/HomeAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ public String execute() {
if(OktaLogin.getAuthorisationUrl() != null){
servletRequest.setAttribute("oktaAuthUrl", new String(Base64.getEncoder().encode(OktaLogin.getAuthorisationUrl().getBytes())));
}
if(AzureLogin.getSamlSettings() != null){
servletRequest.setAttribute("azureRequestUrl", new String(Base64.getEncoder().encode((AzureLogin.getInstance().getAzureConfig().getApplicationIdentifier() + "/signup-azure-request").getBytes())));
}
if (InitializerListener.aktoVersion != null && InitializerListener.aktoVersion.contains("akto-release-version")) {
servletRequest.setAttribute("AktoVersionGlobal", "");
} else {
Expand Down
136 changes: 106 additions & 30 deletions apps/dashboard/src/main/java/com/akto/action/SignupAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import com.akto.dao.*;
import com.akto.dao.billing.OrganizationsDao;
import com.akto.dto.*;
import com.akto.dto.Config.ConfigType;
import com.akto.dto.billing.Organization;
import com.akto.dto.sso.SAMLConfig;
import com.akto.listener.InitializerListener;
import com.akto.mixpanel.AktoMixpanel;
import com.akto.log.LoggerMaker;
Expand All @@ -13,14 +15,13 @@
import com.akto.notifications.slack.SlackSender;
import com.akto.util.http_request.CustomHttpRequest;
import com.akto.utils.Auth0;
import com.akto.utils.AzureLogin;
import com.akto.utils.GithubLogin;
import com.akto.utils.JWT;
import com.akto.utils.OktaLogin;
import com.akto.utils.sso.CustomSamlSettings;
import com.akto.utils.sso.SsoUtils;
import com.akto.util.DashboardMode;
import com.akto.utils.GithubLogin;
import com.akto.utils.JWT;
import com.akto.util.Util;
import com.akto.utils.billing.OrganizationUtils;
import com.auth0.Tokens;
import com.auth0.jwk.Jwk;
Expand All @@ -40,7 +41,6 @@
import com.mongodb.client.model.Filters;
import com.onelogin.saml2.Auth;
import com.onelogin.saml2.settings.Saml2Settings;
import com.onelogin.saml2.settings.SettingsBuilder;
import com.opensymphony.xwork2.Action;
import com.slack.api.Slack;
import com.slack.api.methods.SlackApiException;
Expand Down Expand Up @@ -553,39 +553,56 @@ public String registerViaOkta() throws IOException{
return SUCCESS.toUpperCase();
}

public String sendRequestToAzure () throws IOException{
if(AzureLogin.getInstance() == null){
private int accountId;
private String userEmail;

public String sendRequestToSamlIdP() throws IOException{
String queryString = servletRequest.getQueryString();
String emailId = Util.getValueFromQueryString(queryString, "email");
if(emailId.length() == 0){
code = "Error, user email cannot be empty";
servletResponse.sendRedirect("/login");
return ERROR.toUpperCase();
}
setUserEmail(emailId);
SAMLConfig samlConfig = SSOConfigsDao.instance.getSSOConfig(userEmail);
if(samlConfig == null){
code = "Error, cannot login via SSO, redirecting to login";
servletResponse.sendRedirect("/login");
return ERROR.toUpperCase();
}
Saml2Settings settings = AzureLogin.getSamlSettings();
int tempAccountId = Integer.parseInt(samlConfig.getId());
setAccountId(tempAccountId);

Saml2Settings settings = null;
settings = CustomSamlSettings.getSamlSettings(samlConfig);

if(settings == null){
code= "Error, cannot find sso for this organization, redirecting to login";
return ERROR.toUpperCase();
}
try {
Auth auth = new Auth(settings, servletRequest, servletResponse);
auth.login( AzureLogin.getInstance().getAzureConfig().getApplicationIdentifier() + "/dashboard/onboarding");
String relayState = String.valueOf(tempAccountId);
auth.login(relayState);
} catch (Exception e) {
loggerMaker.errorAndAddToDb("Error while getting response of azure sso \n" + e.getMessage(), LogDb.DASHBOARD);
servletResponse.sendRedirect("/login");
return ERROR.toUpperCase();
}


return SUCCESS.toUpperCase();
}

public String registerViaAzure() throws Exception{
if (!DashboardMode.isOnPremDeployment()) return Action.ERROR.toUpperCase();
if(AzureLogin.getInstance() == null){
return ERROR.toUpperCase();
}
Saml2Settings settings = AzureLogin.getSamlSettings();
if(settings == null){
return ERROR.toUpperCase();
}

Auth auth;
try {
HttpServletRequest wrappedRequest = SsoUtils.getWrappedRequest(servletRequest);
String tempAccountId = servletRequest.getParameter("RelayState");
if(tempAccountId == null || tempAccountId.isEmpty()){
loggerMaker.errorAndAddToDb("Account id not found");
return ERROR.toUpperCase();
}
setAccountId(Integer.parseInt(tempAccountId));
Saml2Settings settings = CustomSamlSettings.getSamlSettings(ConfigType.AZURE, this.accountId);
HttpServletRequest wrappedRequest = SsoUtils.getWrappedRequest(servletRequest,ConfigType.AZURE, this.accountId);
auth = new Auth(settings, wrappedRequest, servletResponse);
auth.processResponse();
if (!auth.isAuthenticated()) {
Expand All @@ -609,15 +626,65 @@ public String registerViaAzure() throws Exception{
username = nameId;
}
shouldLogin = "true";
SignupInfo.AzureSignupInfo signUpInfo = new SignupInfo.AzureSignupInfo(username, useremail);
createUserAndRedirect(useremail, username, signUpInfo, 1000000, Config.ConfigType.AZURE.toString());
SignupInfo.SamlSsoSignupInfo signUpInfo = new SignupInfo.SamlSsoSignupInfo(username, useremail, Config.ConfigType.AZURE);
createUserAndRedirect(useremail, username, signUpInfo, this.accountId, Config.ConfigType.AZURE.toString(), RBAC.Role.MEMBER);
} catch (Exception e1) {
loggerMaker.errorAndAddToDb("Error while signing in via azure sso \n" + e1.getMessage(), LogDb.DASHBOARD);
servletResponse.sendRedirect("/login");
}

return SUCCESS.toUpperCase();
}

public String registerViaGoogleSamlSso() throws IOException{
Auth auth;
try {
String tempAccountId = servletRequest.getParameter("RelayState");
if(tempAccountId == null || tempAccountId.isEmpty()){
loggerMaker.errorAndAddToDb("Account id not found");
return ERROR.toUpperCase();
}
setAccountId(Integer.parseInt(tempAccountId));
Saml2Settings settings = CustomSamlSettings.getSamlSettings(ConfigType.GOOGLE_SAML, this.accountId);
HttpServletRequest wrappedRequest = SsoUtils.getWrappedRequest(servletRequest, ConfigType.GOOGLE_SAML, this.accountId);
auth = new Auth(settings, wrappedRequest, servletResponse);
auth.processResponse();
if (!auth.isAuthenticated()) {
return ERROR.toUpperCase();
}
String userEmail = null;
String username = null;
List<String> errors = auth.getErrors();
if (!errors.isEmpty()) {
loggerMaker.errorAndAddToDb("Error in authenticating user from google sso \n" + auth.getLastErrorReason(), LogDb.DASHBOARD);
return ERROR.toUpperCase();
}
Map<String, List<String>> attributes = auth.getAttributes();
String nameId = "";
if (!attributes.isEmpty()) {
List<String> emails = attributes.get("email");
if(!emails.isEmpty()){
nameId = emails.get(0);
}else{
nameId = auth.getNameId();
}
}else{
nameId = auth.getNameId();
}
userEmail = nameId;
username = nameId;

shouldLogin = "true";
SignupInfo.SamlSsoSignupInfo signUpInfo = new SignupInfo.SamlSsoSignupInfo(username, userEmail, Config.ConfigType.GOOGLE_SAML);
createUserAndRedirect(userEmail, username, signUpInfo, this.accountId, Config.ConfigType.GOOGLE_SAML.toString(), RBAC.Role.MEMBER);
} catch (Exception e1) {
loggerMaker.errorAndAddToDb("Error while signing in via google workspace sso \n" + e1.getMessage(), LogDb.DASHBOARD);
servletResponse.sendRedirect("/login");
}

return SUCCESS.toUpperCase();
}

public static final String MINIMUM_PASSWORD_ERROR = "Minimum of 8 characters required";
public static final String MAXIMUM_PASSWORD_ERROR = "Maximum of 40 characters allowed";
public static final String INVALID_CHAR = "Invalid character";
Expand Down Expand Up @@ -717,6 +784,8 @@ private void createUserAndRedirect(String userEmail, String username, SignupInfo
}
}

boolean isSSOLogin = Config.isConfigSSOType(signupInfo.getConfigType());

if (user == null) {

if (accountId == 0) {
Expand All @@ -742,17 +811,16 @@ private void createUserAndRedirect(String userEmail, String username, SignupInfo
user = UsersDao.instance.insertSignUp(userEmail, username, signupInfo, accountId);
loggerMaker.infoAndAddToDb("new user: " + user.getId());

} else if (StringUtils.isEmpty(code)) {
} else if (StringUtils.isEmpty(code) && !isSSOLogin) {
if (accountId == 0) {
throw new IllegalStateException("The account doesn't exist.");
}
} else {

// insert rbac entry here
RBACDao.instance.insertOne(
new RBAC(user.getId(), invitedRole, accountId)
);

if(!isSSOLogin){
RBACDao.instance.insertOne(
new RBAC(user.getId(), invitedRole, accountId)
);
}
LoginAction.loginUser(user, servletResponse, true, servletRequest);
servletResponse.sendRedirect("/dashboard/observe/inventory");
return;
Expand Down Expand Up @@ -846,4 +914,12 @@ public void setAllEmails(List<String> allEmails) {
public void setInvitationCode(String invitationCode) {
this.invitationCode = invitationCode;
}

public void setAccountId(int accountId) {
this.accountId = accountId;
}

public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
}
Loading

0 comments on commit eafe109

Please sign in to comment.