-
-
Save asafb-wix/826d124d8cb5e4c8875f16195590a463 to your computer and use it in GitHub Desktop.
Answers SSO java example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test; | |
import com.google.common.io.BaseEncoding; | |
import javax.crypto.Cipher; | |
import javax.crypto.spec.SecretKeySpec; | |
import java.io.UnsupportedEncodingException; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.util.Arrays; | |
public class CryptographyUtil { | |
public static String encrypt(String secret, String data) { | |
try { | |
SecretKeySpec secretKey = getKey(secret, "SHA"); | |
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); | |
cipher.init(Cipher.ENCRYPT_MODE, secretKey); | |
return BaseEncoding.base64Url().omitPadding().encode(cipher.doFinal(data.getBytes("UTF-8"))); | |
} catch (Exception ignored) { | |
} | |
return null; | |
} | |
private static SecretKeySpec getKey(String secret, String algorithm) { | |
try { | |
byte[] key = secret.getBytes("UTF-8"); | |
key = Arrays.copyOf(MessageDigest.getInstance(algorithm).digest(key), 16); | |
return new SecretKeySpec(key, "AES"); | |
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test; | |
import org.joda.time.DateTime; | |
import org.joda.time.DateTimeZone; | |
/** | |
* @author asafb | |
* @since 08/06/2016 | |
* | |
* The SSO login flow is as follows: | |
* | |
* 1. The tenant generates an api key and secret in his Wix Answers account settings - the secret will be used to encrypt the sso token by the | |
* the tenants' user system. The tenant then configures in his Wix Answers account settings his sso form url and sso logout url. | |
* | |
* 2. When a user clicks on the login button in Wix Answers, he is redirected to the tenants' login page (sso form url). | |
* Before performing the redirect to the the tenants' login form, Wix Answers appends a redirectUrl parameter to the request - this is the | |
* Wix Answers callback url the tenant's user system should redirect back after the user is authenticated. | |
* | |
* 3. After the user is authenticated by the tenants' user system, the tenants' user system should create an encrypted sso token for | |
* that user using his api secret (see example code below), append the encrypted token parameter to the Wix Answers call back url and | |
* the key id attached to the secret used for the token encryption and redirect back to Wix Answers. | |
* | |
* 4. The SSO token is an encrypted json string (see SSOParams.java) containing the authenticated user data. | |
* | |
* The required fields in the json are: | |
* | |
* id - the user id in the tenants' user system | |
* | |
* email - the user email | |
* | |
* timestamp - current timestamp (UTC) in milliseconds (Unix/Epoch time) | |
* | |
* Optional fields in the json are: | |
* | |
* firstName | |
* lastName | |
* displayName | |
* profileImage - full url to the users' profile image | |
* | |
* | |
* e.g.: | |
* | |
* The tenants' user system login page configured in Wix Answers is: https://labworm.com/login | |
* | |
* Answers will redirect the user to https://labworm.com/login?redirectUrl=<answers-sso-callback-url> | |
* | |
* After user is authenticated by tenants' user system, the tenants' user system builds the encrypted sso token for the authenticated user | |
* and redirects the user back to Wix Answers with the token and key id appended to the callback url (answers-sso-callback-url): | |
* | |
* <answers-sso-callback-url>?token=<encrypted sso token>&key=<api key id> | |
* | |
*/ | |
public class Main { | |
private static String KEY_ID = "<your api key id>"; | |
private static String SECRET = "<your api key secret>"; | |
public static void main(String[] args) { | |
SSOParams params = new SSOParams(); | |
params.setDisplayName("<the user name>"); | |
// set the users' external user id from tenants external user system | |
params.setId("<the user id in tenants' user system>"); | |
params.setEmail("<the user email>"); | |
params.setTimestamp(new DateTime().withZone(DateTimeZone.UTC).getMillis()); | |
// this token should be sent as a request parameter back to Wix Answers after user is authenticated along with the | |
// api key id: token=<encrypted sso token>&key=KEY_ID | |
String ssoToken = getSSOToken(params); | |
} | |
private static String getSSOToken(SSOParams params) { | |
// create json string from params object | |
String serializedParams = toJson(params); | |
return CryptographyUtil.encrypt(SECRET, serializedParams); | |
} | |
private static String toJson(SSOParams params) { | |
String json = null; | |
// json = .... serialize params to json string | |
return json; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test; | |
import javax.validation.constraints.NotNull; | |
/** | |
* @author asafb | |
* @since 6/22/15 | |
* | |
* This class represents the generic json for sso sign in. | |
*/ | |
public class SSOParams { | |
@NotNull | |
private String id; | |
@NotNull | |
private String email; | |
@NotNull | |
private Long timestamp; | |
private String firstName; | |
private String lastName; | |
private String displayName; | |
private String profileImage; | |
public String getId() { | |
return id; | |
} | |
public void setId(String id) { | |
this.id = id; | |
} | |
public String getEmail() { | |
return email; | |
} | |
public void setEmail(String email) { | |
this.email = email; | |
} | |
public Long getTimestamp() { | |
return timestamp; | |
} | |
public void setTimestamp(Long timestamp) { | |
this.timestamp = timestamp; | |
} | |
public String getFirstName() { | |
return firstName; | |
} | |
public void setFirstName(String firstName) { | |
this.firstName = firstName; | |
} | |
public String getLastName() { | |
return lastName; | |
} | |
public void setLastName(String lastName) { | |
this.lastName = lastName; | |
} | |
public String getDisplayName() { | |
return displayName; | |
} | |
public void setDisplayName(String displayName) { | |
this.displayName = displayName; | |
} | |
public String getProfileImage() { | |
return profileImage; | |
} | |
public void setProfileImage(String profileImage) { | |
this.profileImage = profileImage; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment