diff --git a/jans-auth-server/server/integrations/Migration_stepts_to_3.1.x.txt b/jans-auth-server/server/integrations/Migration_stepts_to_3.1.x.txt deleted file mode 100644 index 4545f536ea4..00000000000 --- a/jans-auth-server/server/integrations/Migration_stepts_to_3.1.x.txt +++ /dev/null @@ -1,72 +0,0 @@ -1. Replace: -from org.jboss.seam import Component -from org.jboss.seam.security import Identity - -with: -from org.xdi.service.cdi.util import CdiUtil -from org.xdi.oxauth.security import Identity - -2. Replace: -Component.getInstance(Bean) - -with: -CdiUtil.bean(Bean) - -3. Remove: -from org.jboss.seam.contexts import Contexts - -4. Replace: -FacesContext.getCurrentInstance() - -with: -CdiUtil.bean(FacesContext) - -5. Instead of: -from org.jboss.seam.contexts import Contexts -... -context = Contexts.getEventContext() -context.set(param, value) -context.get(param) - -use: -from org.xdi.oxauth.security import Identity -... -identity = CdiUtil.bean(Identity) -identity.setWorkingParameter(param, value) -identity.getWorkingParameter(param) - -6. Replace: -context = Contexts.getEventContext() -context.get("sessionAttributes") - -with: -identity = CdiUtil.bean(Identity) -identity.getSessionId().getSessionAttributes() - -7. To add faces messages instead of: -from org.jboss.seam.faces import FacesMessages -from org.jboss.seam.international import StatusMessage -... -facesMessages = FacesMessages.instance() -facesMessages.add(StatusMessage.Severity.ERROR, "Error message") -FacesContext.getCurrentInstance().getExternalContext().getExternalContext().getFlash().setKeepMessages(True) - -use: -from io.jans.jsf2.message import FacesMessages -from javax.faces.application import FacesMessage -... -facesMessages = CdiUtil.bean(FacesMessages) -facesMessages.add(FacesMessage.SEVERITY_ERROR, "Error message") -facesMessages.setKeepMessages() - -8. To authenticate user instead of: -from org.xdi.oxauth.service import UserService -... -userService = CdiUtil.bean(UserService) -logged_in = userService.authenticate(user_name, user_password) - -use -from org.xdi.oxauth.service import AuthenticationService -... -authenticationService = CdiUtil.bean(AuthenticationService) -logged_in = authenticationService.authenticate(user_name, user_password) diff --git a/jans-auth-server/server/integrations/Migration_stepts_to_4.0.txt b/jans-auth-server/server/integrations/Migration_stepts_to_4.0.txt deleted file mode 100644 index 56a9aa50bbe..00000000000 --- a/jans-auth-server/server/integrations/Migration_stepts_to_4.0.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Steps to upgrade custom scripts to cope with new structure. - -## Packages renamed - 1. All packages starting **org.xdi** has been renamed to start with **org.gluu**. -## Packages moved - 1. The class named **GluuStatus** has been move from **org.gluu.ldap.model** to **io.jans.model** diff --git a/jans-auth-server/server/integrations/ThumbSignIn/README.md b/jans-auth-server/server/integrations/ThumbSignIn/README.md deleted file mode 100644 index aba6a825a9b..00000000000 --- a/jans-auth-server/server/integrations/ThumbSignIn/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# ThumbSignIn - -ThumbSignIn can be integrated with Gluu Server to achieve strong authentication for enterprise applications. The administrator of an organization can deploy the ThumbSignIn Java SDK, UI components and custom Jython script in the Gluu server. Here, ThumbSignIn is integrated with Gluu server as a primary authenticator to achieve passwordless login. The user will be able to login to the Gluu server with just his/her biometrics and there is no need for the password. For the first time user, the user can login with his/her LDAP credentials and then can register through ThumbSignIn mobile app. For the subsequent logins, the user can directly login to Gluu server with his/her biometric. - -- [Steps to perform Integration](https://thumbsignin.com/download/thumbsigninGluuIntegrationDoc) - -For more information about ThumbSignIn, see their [website](http://thumbsignin.com) diff --git a/jans-auth-server/server/integrations/ThumbSignIn/ThumbSignInExternalAuthenticator.py b/jans-auth-server/server/integrations/ThumbSignIn/ThumbSignInExternalAuthenticator.py deleted file mode 100644 index eeeb39bc9e1..00000000000 --- a/jans-auth-server/server/integrations/ThumbSignIn/ThumbSignInExternalAuthenticator.py +++ /dev/null @@ -1,319 +0,0 @@ -# Author: ThumbSignIn - -from io.jans.service.cdi.util import CdiUtil -from io.jans.as.server.security import Identity -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.server.service import AuthenticationService -from io.jans.util import StringHelper -from io.jans.as.server.util import ServerUtil -from com.pramati.ts.thumbsignin_java_sdk import ThumbsigninApiController -from org.json import JSONObject -from org.gluu.oxauth.model.util import Base64Util -from java.lang import String - -import java - - -class PersonAuthentication(PersonAuthenticationType): - - def __init__(self, current_time_millis): - self.currentTimeMillis = current_time_millis - self.thumbsigninApiController = ThumbsigninApiController() - - def init(self, customScript, configuration_attributes): - print "ThumbSignIn. Initialization" - - global ts_host - ts_host = configuration_attributes.get("ts_host").getValue2() - print "ThumbSignIn. Initialization. Value of ts_host is %s" % ts_host - - global ts_api_key - ts_api_key = configuration_attributes.get("ts_apiKey").getValue2() - print "ThumbSignIn. Initialization. Value of ts_api_key is %s" % ts_api_key - - global ts_api_secret - ts_api_secret = configuration_attributes.get("ts_apiSecret").getValue2() - - global ts_statusPath - ts_statusPath = "/ts/secure/txn-status/" - - global AUTHENTICATE - AUTHENTICATE = "authenticate" - - global REGISTER - REGISTER = "register" - - global TRANSACTION_ID - TRANSACTION_ID = "transactionId" - - global USER_ID - USER_ID = "userId" - - global USER_LOGIN_FLOW - USER_LOGIN_FLOW = "userLoginFlow" - - global THUMBSIGNIN_AUTHENTICATION - THUMBSIGNIN_AUTHENTICATION = "ThumbSignIn_Authentication" - - global THUMBSIGNIN_REGISTRATION - THUMBSIGNIN_REGISTRATION = "ThumbSignIn_Registration" - - global THUMBSIGNIN_LOGIN_POST_REGISTRATION - THUMBSIGNIN_LOGIN_POST_REGISTRATION = "ThumbSignIn_RegistrationSucess" - - global RELYING_PARTY_ID - RELYING_PARTY_ID = "relyingPartyId" - - global RELYING_PARTY_LOGIN_URL - RELYING_PARTY_LOGIN_URL = "relyingPartyLoginUrl" - - global TSI_LOGIN_PAGE - TSI_LOGIN_PAGE = "/auth/thumbsignin/tsLogin.xhtml" - - global TSI_REGISTER_PAGE - TSI_REGISTER_PAGE = "/auth/thumbsignin/tsRegister.xhtml" - - global TSI_LOGIN_POST_REGISTRATION_PAGE - TSI_LOGIN_POST_REGISTRATION_PAGE = "/auth/thumbsignin/tsRegistrationSuccess.xhtml" - - print "ThumbSignIn. Initialized successfully" - return True - - @staticmethod - def set_relying_party_login_url(identity): - print "ThumbSignIn. Inside set_relying_party_login_url..." - session_id = identity.getSessionId() - session_attribute = session_id.getSessionAttributes() - state_jwt_token = session_attribute.get("state") - print "ThumbSignIn. Value of state_jwt_token is %s" % state_jwt_token - relying_party_login_url = "" - if (state_jwt_token is None) or ("." not in state_jwt_token): - print "ThumbSignIn. Value of state parameter is not in the format of JWT Token" - identity.setWorkingParameter(RELYING_PARTY_LOGIN_URL, relying_party_login_url) - return None - - state_jwt_token_array = String(state_jwt_token).split("\\.") - state_jwt_token_payload = state_jwt_token_array[1] - state_payload_str = String(Base64Util.base64urldecode(state_jwt_token_payload), "UTF-8") - state_payload_json = JSONObject(state_payload_str) - print "ThumbSignIn. Value of state JWT token Payload is %s" % state_payload_json - if state_payload_json.has("additional_claims"): - additional_claims = state_payload_json.get("additional_claims") - relying_party_id = additional_claims.get(RELYING_PARTY_ID) - print "ThumbSignIn. Value of relying_party_id is %s" % relying_party_id - identity.setWorkingParameter(RELYING_PARTY_ID, relying_party_id) - - if String(relying_party_id).startsWith("google.com"): - # google.com/a/unphishableenterprise.com - relying_party_id_array = String(relying_party_id).split("/") - google_domain = relying_party_id_array[2] - print "ThumbSignIn. Value of google_domain is %s" % google_domain - relying_party_login_url = "https://www.google.com/accounts/AccountChooser?hd="+ google_domain + "%26continue=https://apps.google.com/user/hub" - # elif (String(relying_party_id).startsWith("xyz")): - # relying_party_login_url = "xyz.com" - else: - # If relying_party_login_url is empty, Gluu's default login URL will be used - relying_party_login_url = "" - - print "ThumbSignIn. Value of relying_party_login_url is %s" % relying_party_login_url - identity.setWorkingParameter(RELYING_PARTY_LOGIN_URL, relying_party_login_url) - return None - - def initialize_thumbsignin(self, identity, request_path): - # Invoking the authenticate/register ThumbSignIn API via the Java SDK - thumbsignin_response = self.thumbsigninApiController.handleThumbSigninRequest(request_path, ts_api_key, ts_api_secret) - print "ThumbSignIn. Value of thumbsignin_response is %s" % thumbsignin_response - - thumbsignin_response_json = JSONObject(thumbsignin_response) - transaction_id = thumbsignin_response_json.get(TRANSACTION_ID) - status_request_type = "authStatus" if request_path == AUTHENTICATE else "regStatus" - status_request = status_request_type + "/" + transaction_id - print "ThumbSignIn. Value of status_request is %s" % status_request - - authorization_header = self.thumbsigninApiController.getAuthorizationHeaderJsonStr(status_request, ts_api_key, ts_api_secret) - print "ThumbSignIn. Value of authorization_header is %s" % authorization_header - # {"authHeader":"HmacSHA256 Credential=X,SignedHeaders=accept;content-type;x-ts-date,Signature=X","XTsDate":"X"} - authorization_header_json = JSONObject(authorization_header) - auth_header = authorization_header_json.get("authHeader") - x_ts_date = authorization_header_json.get("XTsDate") - - tsi_response_key = "authenticateResponseJsonStr" if request_path == AUTHENTICATE else "registerResponseJsonStr" - identity.setWorkingParameter(tsi_response_key, thumbsignin_response) - identity.setWorkingParameter("authorizationHeader", auth_header) - identity.setWorkingParameter("xTsDate", x_ts_date) - return None - - def prepareForStep(self, configuration_attributes, request_parameters, step): - print "ThumbSignIn. Inside prepareForStep. Step %d" % step - identity = CdiUtil.bean(Identity) - authentication_service = CdiUtil.bean(AuthenticationService) - - identity.setWorkingParameter("ts_host", ts_host) - identity.setWorkingParameter("ts_statusPath", ts_statusPath) - - self.set_relying_party_login_url(identity) - - if step == 1 or step == 3: - print "ThumbSignIn. Prepare for step 1" - self.initialize_thumbsignin(identity, AUTHENTICATE) - return True - - elif step == 2: - print "ThumbSignIn. Prepare for step 2" - if identity.isSetWorkingParameter(USER_LOGIN_FLOW): - user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW) - print "ThumbSignIn. Value of user_login_flow is %s" % user_login_flow - user = authentication_service.getAuthenticatedUser() - if user is None: - print "ThumbSignIn. Prepare for step 2. Failed to determine user name" - return False - user_name = user.getUserId() - print "ThumbSignIn. Prepare for step 2. user_name: " + user_name - if user_name is None: - return False - identity.setWorkingParameter(USER_ID, user_name) - self.initialize_thumbsignin(identity, REGISTER + "/" + user_name) - return True - else: - return False - - def get_user_id_from_thumbsignin(self, request_parameters): - transaction_id = ServerUtil.getFirstValue(request_parameters, TRANSACTION_ID) - print "ThumbSignIn. Value of transaction_id is %s" % transaction_id - get_user_request = "getUser/" + transaction_id - print "ThumbSignIn. Value of get_user_request is %s" % get_user_request - - get_user_response = self.thumbsigninApiController.handleThumbSigninRequest(get_user_request, ts_api_key, ts_api_secret) - print "ThumbSignIn. Value of get_user_response is %s" % get_user_response - get_user_response_json = JSONObject(get_user_response) - thumbsignin_user_id = get_user_response_json.get(USER_ID) - print "ThumbSignIn. Value of thumbsignin_user_id is %s" % thumbsignin_user_id - return thumbsignin_user_id - - def authenticate(self, configuration_attributes, request_parameters, step): - print "ThumbSignIn. Inside authenticate. Step %d" % step - authentication_service = CdiUtil.bean(AuthenticationService) - identity = CdiUtil.bean(Identity) - - identity.setWorkingParameter("ts_host", ts_host) - identity.setWorkingParameter("ts_statusPath", ts_statusPath) - - if step == 1 or step == 3: - print "ThumbSignIn. Authenticate for Step %d" % step - - login_flow = ServerUtil.getFirstValue(request_parameters, "login_flow") - print "ThumbSignIn. Value of login_flow parameter is %s" % login_flow - - # Logic for ThumbSignIn Authentication Flow (Either step 1 or step 3) - if login_flow == THUMBSIGNIN_AUTHENTICATION or login_flow == THUMBSIGNIN_LOGIN_POST_REGISTRATION: - identity.setWorkingParameter(USER_LOGIN_FLOW, login_flow) - print "ThumbSignIn. Value of userLoginFlow is %s" % identity.getWorkingParameter(USER_LOGIN_FLOW) - logged_in_status = authentication_service.authenticate(self.get_user_id_from_thumbsignin(request_parameters)) - print "ThumbSignIn. logged_in status : %r" % logged_in_status - return logged_in_status - - # Logic for traditional login flow (step 1) - print "ThumbSignIn. User credentials login flow" - identity.setWorkingParameter(USER_LOGIN_FLOW, THUMBSIGNIN_REGISTRATION) - print "ThumbSignIn. Value of userLoginFlow is %s" % identity.getWorkingParameter(USER_LOGIN_FLOW) - logged_in = self.authenticate_user_credentials(identity, authentication_service) - print "ThumbSignIn. Status of User Credentials based Authentication : %r" % logged_in - - # When the traditional login fails, reinitialize the ThumbSignIn data before sending error response to UI - if not logged_in: - self.initialize_thumbsignin(identity, AUTHENTICATE) - return False - - print "ThumbSignIn. Authenticate successful for step %d" % step - return True - - elif step == 2: - print "ThumbSignIn. Registration flow (step 2)" - self.verify_user_login_flow(identity) - - user = self.get_authenticated_user_from_gluu(authentication_service) - if user is None: - print "ThumbSignIn. Registration flow (step 2). Failed to determine user name" - return False - - user_name = user.getUserId() - print "ThumbSignIn. Registration flow (step 2) successful. user_name: %s" % user_name - return True - - else: - return False - - def authenticate_user_credentials(self, identity, authentication_service): - credentials = identity.getCredentials() - user_name = credentials.getUsername() - user_password = credentials.getPassword() - print "ThumbSignIn. user_name: " + user_name - logged_in = False - if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password): - logged_in = self.authenticate_user_in_gluu_ldap(authentication_service, user_name, user_password) - return logged_in - - @staticmethod - def authenticate_user_in_gluu_ldap(authentication_service, user_name, user_password): - return authentication_service.authenticate(user_name, user_password) - - @staticmethod - def get_authenticated_user_from_gluu(authentication_service): - return authentication_service.getAuthenticatedUser() - - @staticmethod - def verify_user_login_flow(identity): - if identity.isSetWorkingParameter(USER_LOGIN_FLOW): - user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW) - print "ThumbSignIn. Value of user_login_flow is %s" % user_login_flow - else: - identity.setWorkingParameter(USER_LOGIN_FLOW, THUMBSIGNIN_REGISTRATION) - print "ThumbSignIn. Setting the value of user_login_flow to %s" % identity.getWorkingParameter(USER_LOGIN_FLOW) - - def getExtraParametersForStep(self, configuration_attributes, step): - return None - - def getCountAuthenticationSteps(self, configuration_attributes): - print "ThumbSignIn. Inside getCountAuthenticationSteps.." - identity = CdiUtil.bean(Identity) - - user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW) - print "ThumbSignIn. Value of userLoginFlow is %s" % user_login_flow - if user_login_flow == THUMBSIGNIN_AUTHENTICATION: - print "ThumbSignIn. Total Authentication Steps is: 1" - return 1 - print "ThumbSignIn. Total Authentication Steps is: 3" - return 3 - - def getPageForStep(self, configuration_attributes, step): - print "ThumbSignIn. Inside getPageForStep. Step %d" % step - if step == 3: - return TSI_LOGIN_POST_REGISTRATION_PAGE - thumbsignin_page = TSI_REGISTER_PAGE if step == 2 else TSI_LOGIN_PAGE - return thumbsignin_page - - def destroy(self, configurationAttributes): - print "ThumbSignIn. Destroy" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True diff --git a/jans-auth-server/server/integrations/basic.lock.account/BasicLockAccountExternalAuthenticator.py b/jans-auth-server/server/integrations/basic.lock.account/BasicLockAccountExternalAuthenticator.py deleted file mode 100644 index f683d972541..00000000000 --- a/jans-auth-server/server/integrations/basic.lock.account/BasicLockAccountExternalAuthenticator.py +++ /dev/null @@ -1,271 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan -# Author: Gasmyr Mougang -# - -from io.jans.service.cdi.util import CdiUtil -from io.jans.as.server.security import Identity -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.server.service import AuthenticationService -from io.jans.as.server.service.common import UserService -from io.jans.service import CacheService -from io.jans.util import StringHelper -from io.jans.orm.exception import AuthenticationException -from javax.faces.application import FacesMessage -from io.jans.jsf2.message import FacesMessages -from java.time import LocalDateTime, Duration -from java.time.format import DateTimeFormatter - -import java -import datetime -import json - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "Basic (lock account). Initialization" - - self.invalidLoginCountAttribute = "oxCountInvalidLogin" - if configurationAttributes.containsKey("invalid_login_count_attribute"): - self.invalidLoginCountAttribute = configurationAttributes.get("invalid_login_count_attribute").getValue2() - else: - print "Basic (lock account). Initialization. Using default attribute" - - self.maximumInvalidLoginAttemps = 3 - if configurationAttributes.containsKey("maximum_invalid_login_attemps"): - self.maximumInvalidLoginAttemps = StringHelper.toInteger(configurationAttributes.get("maximum_invalid_login_attemps").getValue2()) - else: - print "Basic (lock account). Initialization. Using default number attempts" - - self.lockExpirationTime = 180 - if configurationAttributes.containsKey("lock_expiration_time"): - self.lockExpirationTime = StringHelper.toInteger(configurationAttributes.get("lock_expiration_time").getValue2()) - else: - print "Basic (lock account). Initialization. Using default lock expiration time" - - - print "Basic (lock account). Initialized successfully. invalid_login_count_attribute: '%s', maximum_invalid_login_attemps: '%s', lock_expiration_time: '%s'" % (self.invalidLoginCountAttribute, self.maximumInvalidLoginAttemps, self.lockExpirationTime) - - return True - - def destroy(self, configurationAttributes): - print "Basic (lock account). Destroy" - print "Basic (lock account). Destroyed successfully" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - authenticationService = CdiUtil.bean(AuthenticationService) - - if step == 1: - print "Basic (lock account). Authenticate for step 1" - facesMessages = CdiUtil.bean(FacesMessages) - facesMessages.setKeepMessages() - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - user_name = credentials.getUsername() - user_password = credentials.getPassword() - cacheService = CdiUtil.bean(CacheService) - userService = CdiUtil.bean(UserService) - - - logged_in = False - if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): - try: - logged_in = authenticationService.authenticate(user_name, user_password) - except AuthenticationException: - print "Basic (lock account). Authenticate. Failed to authenticate user '%s'" % user_name - - if logged_in: - self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(0)) - else: - countInvalidLoginArributeValue = self.getUserAttributeValue(user_name, self.invalidLoginCountAttribute) - userSatus = self.getUserAttributeValue(user_name, "gluuStatus") - print "Current user '%s' status is '%s'" % ( user_name, userSatus ) - - countInvalidLogin = StringHelper.toInteger(countInvalidLoginArributeValue, 0) - - if countInvalidLogin < self.maximumInvalidLoginAttemps: - countInvalidLogin = countInvalidLogin + 1 - remainingAttempts = self.maximumInvalidLoginAttemps - countInvalidLogin - - print "Remaining login count attempts '%s' for user '%s'" % ( remainingAttempts, user_name ) - - self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(countInvalidLogin)) - if remainingAttempts > 0 and userSatus == "active": - facesMessages.add(FacesMessage.SEVERITY_INFO, StringHelper.toString(remainingAttempts)+" more attempt(s) before account is LOCKED!") - - if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and ((userSatus == None) or (userSatus == "active")): - print "Basic (lock account). Locking '%s' for '%s' seconds" % ( user_name, self.lockExpirationTime) - self.lockUser(user_name) - return False - - if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and userSatus == "inactive": - print "Basic (lock account). User '%s' is locked. Checking if we can unlock him" % user_name - - unlock_and_authenticate = False - - object_from_store = cacheService.get(None, "lock_user_" + user_name) - if object_from_store == None: - # Object in cache was expired. We need to unlock user - print "Basic (lock account). User locking details for user '%s' not exists" % user_name - unlock_and_authenticate = True - else: - # Analyze object from cache - user_lock_details = json.loads(object_from_store) - - user_lock_details_locked = user_lock_details['locked'] - user_lock_details_created = user_lock_details['created'] - user_lock_details_created_date = LocalDateTime.parse(user_lock_details_created, DateTimeFormatter.ISO_LOCAL_DATE_TIME) - user_lock_details_created_diff = Duration.between(user_lock_details_created_date, LocalDateTime.now()).getSeconds() - print "Basic (lock account). Get user '%s' locking details. locked: '%s', Created: '%s', Difference in seconds: '%s'" % ( user_name, user_lock_details_locked, user_lock_details_created, user_lock_details_created_diff ) - - if user_lock_details_locked and user_lock_details_created_diff >= self.lockExpirationTime: - print "Basic (lock account). Unlocking user '%s' after lock expiration" % user_name - unlock_and_authenticate = True - - if unlock_and_authenticate: - self.unLockUser(user_name) - self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(0)) - logged_in = authenticationService.authenticate(user_name, user_password) - if not logged_in: - # Update number of attempts - self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(1)) - if self.maximumInvalidLoginAttemps == 1: - # Lock user if maximum count login attempts is 1 - self.lockUser(user_name) - return False - - - return logged_in - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - if step == 1: - print "Basic (lock account). Prepare for Step 1" - return True - else: - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - return 1 - - def getPageForStep(self, configurationAttributes, step): - return "" - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True - - def getUserAttributeValue(self, user_name, attribute_name): - if StringHelper.isEmpty(user_name): - return None - - userService = CdiUtil.bean(UserService) - - find_user_by_uid = userService.getUser(user_name, attribute_name) - if find_user_by_uid == None: - return None - - custom_attribute_value = userService.getCustomAttribute(find_user_by_uid, attribute_name) - if custom_attribute_value == None: - return None - - attribute_value = custom_attribute_value.getValue() - - print "Basic (lock account). Get user attribute. User's '%s' attribute '%s' value is '%s'" % (user_name, attribute_name, attribute_value) - - return attribute_value - - def setUserAttributeValue(self, user_name, attribute_name, attribute_value): - if StringHelper.isEmpty(user_name): - return None - - userService = CdiUtil.bean(UserService) - - find_user_by_uid = userService.getUser(user_name) - if find_user_by_uid == None: - return None - - userService.setCustomAttribute(find_user_by_uid, attribute_name, attribute_value) - updated_user = userService.updateUser(find_user_by_uid) - - print "Basic (lock account). Set user attribute. User's '%s' attribute '%s' value is '%s'" % (user_name, attribute_name, attribute_value) - - return updated_user - - def lockUser(self, user_name): - if StringHelper.isEmpty(user_name): - return None - - userService = CdiUtil.bean(UserService) - cacheService= CdiUtil.bean(CacheService) - facesMessages = CdiUtil.bean(FacesMessages) - facesMessages.setKeepMessages() - - find_user_by_uid = userService.getUser(user_name) - if (find_user_by_uid == None): - return None - - status_attribute_value = userService.getCustomAttribute(find_user_by_uid, "gluuStatus") - if status_attribute_value != None: - user_status = status_attribute_value.getValue() - if StringHelper.equals(user_status, "inactive"): - print "Basic (lock account). Lock user. User '%s' locked already" % user_name - return - - userService.setCustomAttribute(find_user_by_uid, "gluuStatus", "inactive") - updated_user = userService.updateUser(find_user_by_uid) - - object_to_store = json.dumps({'locked': True, 'created': LocalDateTime.now().toString()}, separators=(',',':')) - - cacheService.put(StringHelper.toString(self.lockExpirationTime), "lock_user_"+user_name, object_to_store); - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Your account is locked. Please try again after " + StringHelper.toString(self.lockExpirationTime) + " secs") - - print "Basic (lock account). Lock user. User '%s' locked" % user_name - - def unLockUser(self, user_name): - if StringHelper.isEmpty(user_name): - return None - - userService = CdiUtil.bean(UserService) - cacheService= CdiUtil.bean(CacheService) - - find_user_by_uid = userService.getUser(user_name) - if (find_user_by_uid == None): - return None - - object_to_store = json.dumps({'locked': False, 'created': LocalDateTime.now().toString()}, separators=(',',':')) - cacheService.put(StringHelper.toString(self.lockExpirationTime), "lock_user_"+user_name, object_to_store); - - userService.setCustomAttribute(find_user_by_uid, "gluuStatus", "active") - userService.setCustomAttribute(find_user_by_uid, self.invalidLoginCountAttribute, None) - updated_user = userService.updateUser(find_user_by_uid) - - - print "Basic (lock account). Lock user. User '%s' unlocked" % user_name diff --git a/jans-auth-server/server/integrations/basic/BasicExternalAuthenticator.py b/jans-auth-server/server/integrations/basic/BasicExternalAuthenticator.py deleted file mode 100644 index 1b489da2fea..00000000000 --- a/jans-auth-server/server/integrations/basic/BasicExternalAuthenticator.py +++ /dev/null @@ -1,88 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan -# - -from io.jans.service.cdi.util import CdiUtil -from io.jans.as.server.security import Identity -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.server.service import AuthenticationService -from io.jans.util import StringHelper - -import java - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "Basic. Initialization" - print "Basic. Initialized successfully" - return True - - def destroy(self, configurationAttributes): - print "Basic. Destroy" - print "Basic. Destroyed successfully" - return True - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def getApiVersion(self): - return 11 - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - authenticationService = CdiUtil.bean(AuthenticationService) - - if (step == 1): - print "Basic. Authenticate for step 1" - - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - - user_name = credentials.getUsername() - user_password = credentials.getPassword() - - logged_in = False - if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): - logged_in = authenticationService.authenticate(user_name, user_password) - - if (not logged_in): - return False - - return True - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - if (step == 1): - print "Basic. Prepare for Step 1" - return True - else: - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - return 1 - - def getPageForStep(self, configurationAttributes, step): - return "" - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True diff --git a/jans-auth-server/server/integrations/basic/INSTALLATION.txt b/jans-auth-server/server/integrations/basic/INSTALLATION.txt deleted file mode 100644 index 50962805b49..00000000000 --- a/jans-auth-server/server/integrations/basic/INSTALLATION.txt +++ /dev/null @@ -1,27 +0,0 @@ -This list of steps needed to do to enable Basic person authentication module. - -1. Confire new custom module in oxTrust: - - Log into oxTrust with administrative permissions. - - Open "Configuration→Manage Custom Scripts" page. - - Select "Person Authentication" tab. - - Click on "Add custom script configuration" link. - - Enter name = basic - - Enter level = 0-100 (priority of this method). - - Select usage type "Interactive". - - Add custom required and optional properties which specified in README.txt. - - Copy/paste script from BasicExternalAuthenticator.py. - - Activate it via "Enabled" checkbox. - - Click "Update" button at the bottom of this page. - -2. Configure oxAuth to use Basic authentication by default: - - Log into oxTrust with administrative permissions. - - Open "Configuration→Manage Authentication" page. - - Scroll to "Default Authentication Method" panel. Select "basic" authentication mode. - - Click "Update" button at the bottom of this page. - -3. Try to log in using Basic authentication method: - - Wait 30 seconds and try to log in again. During this time oxAuth reload list of available person authentication modules. - - Open second browser or second browsing session and try to log in again. It's better to try to do that from another browser session because we can return back to previous authentication method if something will go wrong. - -There are log messages in this custom authentication script. In order to debug this module we can use command like this: -tail -f /opt/tomcat/logs/wrapper.log | grep "Basic" diff --git a/jans-auth-server/server/integrations/basic/README.txt b/jans-auth-server/server/integrations/basic/README.txt deleted file mode 100644 index 8368ad13ee4..00000000000 --- a/jans-auth-server/server/integrations/basic/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -This is person authentication module for oxAuth which do basic authentication. - -This module hasn't properties. \ No newline at end of file diff --git a/jans-auth-server/server/integrations/cert/UserCertExternalAuthenticator.py b/jans-auth-server/server/integrations/cert/UserCertExternalAuthenticator.py deleted file mode 100644 index 6fbf86d37e2..00000000000 --- a/jans-auth-server/server/integrations/cert/UserCertExternalAuthenticator.py +++ /dev/null @@ -1,482 +0,0 @@ -# -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan -# - -from io.jans.service.cdi.util import CdiUtil -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from javax.faces.context import FacesContext -from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService -from io.jans.as.server.service.common import UserService -from io.jans.util import StringHelper -from io.jans.as.server.util import ServerUtil -from io.jans.as.server.service.common import EncryptionService -from java.util import Arrays -from org.gluu.oxauth.cert.fingerprint import FingerprintHelper -from org.gluu.oxauth.cert.validation import GenericCertificateVerifier, PathCertificateVerifier, OCSPCertificateVerifier, CRLCertificateVerifier -from org.gluu.oxauth.cert.validation.model import ValidationStatus -from io.jans.as.server.util import CertUtil -from org.gluu.oxauth.model.util import CertUtils -from io.jans.as.server.service.net import HttpService -from org.apache.http.params import CoreConnectionPNames - -import sys -import base64 -import urllib - -import java -import json - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "Cert. Initialization" - - if not (configurationAttributes.containsKey("chain_cert_file_path")): - print "Cert. Initialization. Property chain_cert_file_path is mandatory" - return False - - if not (configurationAttributes.containsKey("map_user_cert")): - print "Cert. Initialization. Property map_user_cert is mandatory" - return False - - chain_cert_file_path = configurationAttributes.get("chain_cert_file_path").getValue2() - - self.chain_certs = CertUtil.loadX509CertificateFromFile(chain_cert_file_path) - if self.chain_certs == None: - print "Cert. Initialization. Failed to load chain certificates from '%s'" % chain_cert_file_path - return False - - print "Cert. Initialization. Loaded '%d' chain certificates" % self.chain_certs.size() - - crl_max_response_size = 5 * 1024 * 1024 # 10Mb - if configurationAttributes.containsKey("crl_max_response_size"): - crl_max_response_size = StringHelper.toInteger(configurationAttributes.get("crl_max_response_size").getValue2(), crl_max_response_size) - print "Cert. Initialization. CRL max response size is '%d'" % crl_max_response_size - - # Define array to order methods correctly - self.validator_types = [ 'generic', 'path', 'ocsp', 'crl'] - self.validators = { 'generic' : [GenericCertificateVerifier(), False], - 'path' : [PathCertificateVerifier(False), False], - 'ocsp' : [OCSPCertificateVerifier(), False], - 'crl' : [CRLCertificateVerifier(crl_max_response_size), False] } - - for type in self.validator_types: - validator_param_name = "use_%s_validator" % type - if configurationAttributes.containsKey(validator_param_name): - validator_status = StringHelper.toBoolean(configurationAttributes.get(validator_param_name).getValue2(), False) - self.validators[type][1] = validator_status - - print "Cert. Initialization. Validation method '%s' status: '%s'" % (type, self.validators[type][1]) - - self.map_user_cert = StringHelper.toBoolean(configurationAttributes.get("map_user_cert").getValue2(), False) - print "Cert. Initialization. map_user_cert: '%s'" % self.map_user_cert - - self.enabled_recaptcha = self.initRecaptcha(configurationAttributes) - print "Cert. Initialization. enabled_recaptcha: '%s'" % self.enabled_recaptcha - - print "Cert. Initialized successfully" - - return True - - def destroy(self, configurationAttributes): - print "Cert. Destroy" - - for type in self.validator_types: - self.validators[type][0].destroy() - - print "Cert. Destroyed successfully" - - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - - user_name = credentials.getUsername() - - userService = CdiUtil.bean(UserService) - authenticationService = CdiUtil.bean(AuthenticationService) - - if step == 1: - print "Cert. Authenticate for step 1" - login_button = ServerUtil.getFirstValue(requestParameters, "loginForm:loginButton") - if StringHelper.isEmpty(login_button): - print "Cert. Authenticate for step 1. Form were submitted incorrectly" - return False - if self.enabled_recaptcha: - print "Cert. Authenticate for step 1. Validating recaptcha response" - recaptcha_response = ServerUtil.getFirstValue(requestParameters, "g-recaptcha-response") - - recaptcha_result = self.validateRecaptcha(recaptcha_response) - print "Cert. Authenticate for step 1. recaptcha_result: '%s'" % recaptcha_result - - return recaptcha_result - - return True - elif step == 2: - print "Cert. Authenticate for step 2" - - # Validate if user selected certificate - cert_x509 = self.getSessionAttribute("cert_x509") - if cert_x509 == None: - print "Cert. Authenticate for step 2. User not selected any certs" - identity.setWorkingParameter("cert_selected", False) - - # Return True to inform user how to reset workflow - return True - else: - identity.setWorkingParameter("cert_selected", True) - x509Certificate = self.certFromString(cert_x509) - - subjectX500Principal = x509Certificate.getSubjectX500Principal() - print "Cert. Authenticate for step 2. User selected certificate with DN '%s'" % subjectX500Principal - - # Validate certificates which user selected - valid = self.validateCertificate(x509Certificate) - if not valid: - print "Cert. Authenticate for step 2. Certificate DN '%s' is not valid" % subjectX500Principal - identity.setWorkingParameter("cert_valid", False) - - # Return True to inform user how to reset workflow - return True - - identity.setWorkingParameter("cert_valid", True) - - # Calculate certificate fingerprint - x509CertificateFingerprint = self.calculateCertificateFingerprint(x509Certificate) - identity.setWorkingParameter("cert_x509_fingerprint", x509CertificateFingerprint) - print "Cert. Authenticate for step 2. Fingerprint is '%s' of certificate with DN '%s'" % (x509CertificateFingerprint, subjectX500Principal) - - # Attempt to find user by certificate fingerprint - cert_user_external_uid = "cert:%s" % x509CertificateFingerprint - print "Cert. Authenticate for step 2. Attempting to find user by oxExternalUid attribute value %s" % cert_user_external_uid - - find_user_by_external_uid = userService.getUserByAttribute("oxExternalUid", cert_user_external_uid, True) - if find_user_by_external_uid == None: - print "Cert. Authenticate for step 2. Failed to find user" - - if self.map_user_cert: - print "Cert. Authenticate for step 2. Storing cert_user_external_uid for step 3" - identity.setWorkingParameter("cert_user_external_uid", cert_user_external_uid) - return True - else: - print "Cert. Authenticate for step 2. Mapping cert to user account is not allowed" - identity.setWorkingParameter("cert_count_login_steps", 2) - return False - - foundUserName = find_user_by_external_uid.getUserId() - print "Cert. Authenticate for step 2. foundUserName: " + foundUserName - - logged_in = False - userService = CdiUtil.bean(UserService) - logged_in = authenticationService.authenticate(foundUserName) - - print "Cert. Authenticate for step 2. Setting count steps to 2" - identity.setWorkingParameter("cert_count_login_steps", 2) - - return logged_in - elif step == 3: - print "Cert. Authenticate for step 3" - - cert_user_external_uid = self.getSessionAttribute("cert_user_external_uid") - if cert_user_external_uid == None: - print "Cert. Authenticate for step 3. cert_user_external_uid is empty" - return False - - user_password = credentials.getPassword() - - logged_in = False - if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): - logged_in = authenticationService.authenticate(user_name, user_password) - - if (not logged_in): - return False - - # Double check just to make sure. We did checking in previous step - # Check if there is user which has cert_user_external_uid - # Avoid mapping user cert to more than one IDP account - find_user_by_external_uid = userService.getUserByAttribute("oxExternalUid", cert_user_external_uid, True) - if find_user_by_external_uid == None: - # Add cert_user_external_uid to user's external GUID list - find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", cert_user_external_uid, True) - if find_user_by_external_uid == None: - print "Cert. Authenticate for step 3. Failed to update current user" - return False - - return True - - return True - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - print "Cert. Prepare for step %d" % step - identity = CdiUtil.bean(Identity) - - if step == 1: - if self.enabled_recaptcha: - identity.setWorkingParameter("recaptcha_site_key", self.recaptcha_creds['site_key']) - elif step == 2: - # Store certificate in session - facesContext = CdiUtil.bean(FacesContext) - externalContext = facesContext.getExternalContext() - request = externalContext.getRequest() - - # Try to get certificate from header X-ClientCert - clientCertificate = externalContext.getRequestHeaderMap().get("X-ClientCert") - if clientCertificate != None: - x509Certificate = self.certFromPemString(clientCertificate) - identity.setWorkingParameter("cert_x509", self.certToString(x509Certificate)) - print "Cert. Prepare for step 2. Storing user certificate obtained from 'X-ClientCert' header" - return True - - # Try to get certificate from attribute javax.servlet.request.X509Certificate - x509Certificates = request.getAttribute('javax.servlet.request.X509Certificate') - if (x509Certificates != None) and (len(x509Certificates) > 0): - identity.setWorkingParameter("cert_x509", self.certToString(x509Certificates[0])) - print "Cert. Prepare for step 2. Storing user certificate obtained from 'javax.servlet.request.X509Certificate' attribute" - return True - - if step < 4: - return True - else: - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - return Arrays.asList("cert_selected", "cert_valid", "cert_x509", "cert_x509_fingerprint", "cert_count_login_steps", "cert_user_external_uid") - - def getCountAuthenticationSteps(self, configurationAttributes): - cert_count_login_steps = self.getSessionAttribute("cert_count_login_steps") - if cert_count_login_steps != None: - return cert_count_login_steps - else: - return 3 - - def getPageForStep(self, configurationAttributes, step): - if step == 1: - return "/auth/cert/login.xhtml" - if step == 2: - return "/auth/cert/cert-login.xhtml" - elif step == 3: - cert_selected = self.getSessionAttribute("cert_selected") - if True != cert_selected: - return "/auth/cert/cert-not-selected.xhtml" - - cert_valid = self.getSessionAttribute("cert_valid") - if True != cert_valid: - return "/auth/cert/cert-invalid.xhtml" - - return "/login.xhtml" - - return "" - - def logout(self, configurationAttributes, requestParameters): - return True - - def processBasicAuthentication(self, credentials): - userService = CdiUtil.bean(UserService) - authenticationService = CdiUtil.bean(AuthenticationService) - - user_name = credentials.getUsername() - user_password = credentials.getPassword() - - logged_in = False - if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): - logged_in = authenticationService.authenticate(user_name, user_password) - - if (not logged_in): - return None - - find_user_by_uid = authenticationService.getAuthenticatedUser() - if (find_user_by_uid == None): - print "Cert. Process basic authentication. Failed to find user '%s'" % user_name - return None - - return find_user_by_uid - - def getSessionAttribute(self, attribute_name): - identity = CdiUtil.bean(Identity) - - # Try to get attribute value from Seam event context - if identity.isSetWorkingParameter(attribute_name): - return identity.getWorkingParameter(attribute_name) - - # Try to get attribute from persistent session - session_id = identity.getSessionId() - if session_id == None: - return None - - session_attributes = session_id.getSessionAttributes() - if session_attributes == None: - return None - - if session_attributes.containsKey(attribute_name): - return session_attributes.get(attribute_name) - - return None - - def calculateCertificateFingerprint(self, x509Certificate): - print "Cert. Calculate fingerprint for certificate DN '%s'" % x509Certificate.getSubjectX500Principal() - - publicKey = x509Certificate.getPublicKey() - - # Use oxAuth implementation - fingerprint = FingerprintHelper.getPublicKeySshFingerprint(publicKey) - - return fingerprint - - def validateCertificate(self, x509Certificate): - subjectX500Principal = x509Certificate.getSubjectX500Principal() - - print "Cert. Validating certificate with DN '%s'" % subjectX500Principal - - validation_date = java.util.Date() - - for type in self.validator_types: - if self.validators[type][1]: - result = self.validators[type][0].validate(x509Certificate, self.chain_certs, validation_date) - print "Cert. Validate certificate: '%s'. Validation method '%s' result: '%s'" % (subjectX500Principal, type, result) - - if (result.getValidity() != ValidationStatus.CertificateValidity.VALID): - print "Cert. Certificate: '%s' is invalid" % subjectX500Principal - return False - - return True - - def certToString(self, x509Certificate): - if x509Certificate == None: - return None - return base64.b64encode(x509Certificate.getEncoded()) - - def certFromString(self, x509CertificateEncoded): - x509CertificateDecoded = base64.b64decode(x509CertificateEncoded) - return CertUtils.x509CertificateFromBytes(x509CertificateDecoded) - - def certFromPemString(self, pemCertificate): - x509CertificateEncoded = pemCertificate.replace("-----BEGIN CERTIFICATE-----", "").replace("-----END CERTIFICATE-----", "").strip() - return self.certFromString(x509CertificateEncoded) - - def initRecaptcha(self, configurationAttributes): - print "Cert. Initialize recaptcha" - if not configurationAttributes.containsKey("credentials_file"): - return False - - cert_creds_file = configurationAttributes.get("credentials_file").getValue2() - - # Load credentials from file - f = open(cert_creds_file, 'r') - try: - creds = json.loads(f.read()) - except: - print "Cert. Initialize recaptcha. Failed to load credentials from file: %s" % cert_creds_file - return False - finally: - f.close() - - try: - recaptcha_creds = creds["recaptcha"] - except: - print "Cert. Initialize recaptcha. Invalid credentials file '%s' format:" % cert_creds_file - return False - - self.recaptcha_creds = None - if recaptcha_creds["enabled"]: - print "Cert. Initialize recaptcha. Recaptcha is enabled" - - encryptionService = CdiUtil.bean(EncryptionService) - - site_key = recaptcha_creds["site_key"] - secret_key = recaptcha_creds["secret_key"] - - try: - site_key = encryptionService.decrypt(site_key) - except: - # Ignore exception. Value is not encrypted - print "Cert. Initialize recaptcha. Assuming that 'site_key' in not encrypted" - - try: - secret_key = encryptionService.decrypt(secret_key) - except: - # Ignore exception. Value is not encrypted - print "Cert. Initialize recaptcha. Assuming that 'secret_key' in not encrypted" - - - self.recaptcha_creds = { 'site_key' : site_key, "secret_key" : secret_key } - print "Cert. Initialize recaptcha. Recaptcha is configured correctly" - - return True - else: - print "Cert. Initialize recaptcha. Recaptcha is disabled" - - return False - - def validateRecaptcha(self, recaptcha_response): - print "Cert. Validate recaptcha response" - - facesContext = CdiUtil.bean(FacesContext) - request = facesContext.getExternalContext().getRequest() - - remoteip = ServerUtil.getIpAddress(request) - print "Cert. Validate recaptcha response. remoteip: '%s'" % remoteip - - httpService = CdiUtil.bean(HttpService) - - http_client = httpService.getHttpsClient() - http_client_params = http_client.getParams() - http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000) - - recaptcha_validation_url = "https://www.google.com/recaptcha/api/siteverify" - recaptcha_validation_request = urllib.urlencode({ "secret" : self.recaptcha_creds['secret_key'], "response" : recaptcha_response, "remoteip" : remoteip }) - recaptcha_validation_headers = { "Content-type" : "application/x-www-form-urlencoded", "Accept" : "application/json" } - - try: - http_service_response = httpService.executePost(http_client, recaptcha_validation_url, None, recaptcha_validation_headers, recaptcha_validation_request) - http_response = http_service_response.getHttpResponse() - except: - print "Cert. Validate recaptcha response. Exception: ", sys.exc_info()[1] - return False - - try: - if not httpService.isResponseStastusCodeOk(http_response): - print "Cert. Validate recaptcha response. Get invalid response from validation server: ", str(http_response.getStatusLine().getStatusCode()) - httpService.consume(http_response) - return False - - response_bytes = httpService.getResponseContent(http_response) - response_string = httpService.convertEntityToString(response_bytes) - httpService.consume(http_response) - finally: - http_service_response.closeConnection() - - if response_string == None: - print "Cert. Validate recaptcha response. Get empty response from validation server" - return False - - response = json.loads(response_string) - - return response["success"] - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None \ No newline at end of file diff --git a/jans-auth-server/server/integrations/duo/DuoExternalAuthenticator.py b/jans-auth-server/server/integrations/duo/DuoExternalAuthenticator.py deleted file mode 100644 index e5c57200311..00000000000 --- a/jans-auth-server/server/integrations/duo/DuoExternalAuthenticator.py +++ /dev/null @@ -1,239 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan -# - -from io.jans.service.cdi.util import CdiUtil -from io.jans.as.server.security import Identity -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.server.service import AuthenticationService -from io.jans.as.server.service.common import UserService -from io.jans.service import MailService -from io.jans.util import ArrayHelper -from io.jans.util import StringHelper -from java.util import Arrays - -import duo_web -import json - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "Duo. Initialization" - - duo_creds_file = configurationAttributes.get("duo_creds_file").getValue2() - # Load credentials from file - f = open(duo_creds_file, 'r') - try: - creds = json.loads(f.read()) - except: - print "Duo. Initialization. Failed to load creds from file:", duo_creds_file - return False - finally: - f.close() - - self.ikey = str(creds["ikey"]) - self.skey = str(creds["skey"]) - self.akey = str(creds["akey"]) - - self.use_duo_group = False - if (configurationAttributes.containsKey("duo_group")): - self.duo_group = configurationAttributes.get("duo_group").getValue2() - self.use_duo_group = True - print "Duo. Initialization. Using Duo only if user belong to group:", self.duo_group - - self.use_audit_group = False - if (configurationAttributes.containsKey("audit_group")): - self.audit_group = configurationAttributes.get("audit_group").getValue2() - - if (not configurationAttributes.containsKey("audit_group_email")): - print "Duo. Initialization. Property audit_group_email is not specified" - return False - - self.audit_email = configurationAttributes.get("audit_group_email").getValue2() - self.use_audit_group = True - - print "Duo. Initialization. Using audito group:", self.audit_group - - if (self.use_duo_group or self.use_audit_group): - if (not configurationAttributes.containsKey("audit_attribute")): - print "Duo. Initialization. Property audit_attribute is not specified" - return False - else: - self.audit_attribute = configurationAttributes.get("audit_attribute").getValue2() - - print "Duo. Initialized successfully" - return True - - def destroy(self, configurationAttributes): - print "Duo. Destroy" - print "Duo. Destroyed successfully" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - duo_host = configurationAttributes.get("duo_host").getValue2() - - authenticationService = CdiUtil.bean(AuthenticationService) - - identity = CdiUtil.bean(Identity) - - if (step == 1): - print "Duo. Authenticate for step 1" - - # Check if user authenticated already in another custom script - user = authenticationService.getAuthenticatedUser() - if user == None: - credentials = identity.getCredentials() - user_name = credentials.getUsername() - user_password = credentials.getPassword() - - logged_in = False - if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): - userService = CdiUtil.bean(UserService) - logged_in = authenticationService.authenticate(user_name, user_password) - - if (not logged_in): - return False - - user = authenticationService.getAuthenticatedUser() - - if (self.use_duo_group): - print "Duo. Authenticate for step 1. Checking if user belong to Duo group" - is_member_duo_group = self.isUserMemberOfGroup(user, self.audit_attribute, self.duo_group) - if (is_member_duo_group): - print "Duo. Authenticate for step 1. User '" + user.getUserId() + "' member of Duo group" - duo_count_login_steps = 2 - else: - self.processAuditGroup(user) - duo_count_login_steps = 1 - - identity.setWorkingParameter("duo_count_login_steps", duo_count_login_steps) - - return True - elif (step == 2): - print "Duo. Authenticate for step 2" - user = authenticationService.getAuthenticatedUser() - if user == None: - print "Duo. Authenticate for step 2. Failed to determine user name" - return False - - user_name = user.getUserId() - - sig_response_array = requestParameters.get("sig_response") - if ArrayHelper.isEmpty(sig_response_array): - print "Duo. Authenticate for step 2. sig_response is empty" - return False - - duo_sig_response = sig_response_array[0] - - print "Duo. Authenticate for step 2. duo_sig_response: " + duo_sig_response - - authenticated_username = duo_web.verify_response(self.ikey, self.skey, self.akey, duo_sig_response) - - print "Duo. Authenticate for step 2. authenticated_username: " + authenticated_username + ", expected user_name: " + user_name - - if (not StringHelper.equals(user_name, authenticated_username)): - return False - - self.processAuditGroup(user) - - return True - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - identity = CdiUtil.bean(Identity) - authenticationService = CdiUtil.bean(AuthenticationService) - - duo_host = configurationAttributes.get("duo_host").getValue2() - - if (step == 1): - print "Duo. Prepare for step 1" - - return True - elif (step == 2): - print "Duo. Prepare for step 2" - - user = authenticationService.getAuthenticatedUser() - if (user == None): - print "Duo. Prepare for step 2. Failed to determine user name" - return False - user_name = user.getUserId() - - duo_sig_request = duo_web.sign_request(self.ikey, self.skey, self.akey, user_name) - print "Duo. Prepare for step 2. duo_sig_request: " + duo_sig_request - - identity.setWorkingParameter("duo_host", duo_host) - identity.setWorkingParameter("duo_sig_request", duo_sig_request) - - return True - else: - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - if step == 2: - return Arrays.asList("duo_count_login_steps", "cas2_user_uid") - - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - identity = CdiUtil.bean(Identity) - if (identity.isSetWorkingParameter("duo_count_login_steps")): - return int(identity.getWorkingParameter("duo_count_login_steps")) - - return 2 - - def getPageForStep(self, configurationAttributes, step): - if (step == 2): - return "/auth/duo/duologin.xhtml" - return "" - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True - - def isUserMemberOfGroup(self, user, attribute, group): - is_member = False - member_of_list = user.getAttributeValues(attribute) - if (member_of_list != None): - for member_of in member_of_list: - if StringHelper.equalsIgnoreCase(group, member_of) or member_of.endswith(group): - is_member = True - break - - return is_member - - def processAuditGroup(self, user): - if (self.use_audit_group): - is_member = self.isUserMemberOfGroup(user, self.audit_attribute, self.audit_group) - if (is_member): - print "Duo. Authenticate for processAuditGroup. User '" + user.getUserId() + "' member of audit group" - print "Duo. Authenticate for processAuditGroup. Sending e-mail about user '" + user.getUserId() + "' login to", self.audit_email - - # Send e-mail to administrator - user_id = user.getUserId() - mailService = CdiUtil.bean(MailService) - subject = "User log in: " + user_id - body = "User log in: " + user_id - mailService.sendMail(self.audit_email, subject, body) diff --git a/jans-auth-server/server/integrations/duo/INSTALLATION.txt b/jans-auth-server/server/integrations/duo/INSTALLATION.txt deleted file mode 100644 index 051f6ae6d81..00000000000 --- a/jans-auth-server/server/integrations/duo/INSTALLATION.txt +++ /dev/null @@ -1,44 +0,0 @@ -This list of steps needed to do to enable DUO person authentication module. - -1. This module depends on python libraries. In order to use it we need to install Jython. Please use next articles to proper Jython installation: - - Installation notest: http://ox.gluu.org/doku.php?id=oxtauth:customauthscript#jython_installation_optional - - Jython integration: http://ox.gluu.org/doku.php?id=oxtauth:customauthscript#jython_python_integration - -2. Copy required python libraries from ./lib folder to $CATALINA_HOME/conf/python folder. - -3. Prepare DUO creds file /etc/certs/duo_creds.json with ikey, akey, skey - -4. Confire new custom module in oxTrust: - - Log into oxTrust with administrative permissions. - - Open "Configuration→Manage Custom Scripts" page. - - Select "Person Authentication" tab. - - Click on "Add custom script configuration" link. - - Enter name = duo - - Enter level = 0-100 (priority of this method). - - Select usage type "Interactive". - - Add custom required and optional properties which specified in README.txt. - - Copy/paste script from DuoPersonAuthentication.py. - - Activate it via "Enabled" checkbox. - - Click "Update" button at the bottom of this page. - -5. Configure oxAuth to use DUO authentication by default: - - Log into oxTrust with administrative permissions. - - Open "Configuration→Manage Authentication" page. - - Scroll to "Default Authentication Method" panel. Select "duo" authentication mode. - - Click "Update" button at the bottom of this page. - -6. Try to log in using DUO authentication method: - - Wait 30 seconds and try to log in again. During this time oxAuth reload list of available person authentication modules. - - Open second browser or second browsing session and try to log in again. It's better to try to do that from another browser session because we can return back to previous authentication method if something will go wrong. - -7. This step is an optional. We need to define SMTP configuration if we are plaaning to use audit_group property. In order to set SMTP configuration - we need to do: - - Open "Configuration"->"Organization configuration" page. - - Scroll down to "SMTP Server Configuration" section. - - Fill SMTP configuration parameters. - - Click "Test Configuration" in order to verify SMTP configuration. - - Click "Update" button at the bottom of this page. - - Restart tomcat in order to instruct oxAuth to use new SMTP configuration. - -There are log messages in this custom authentication script. In order to debug this module we can use command like this: -tail -f /opt/tomcat/logs/wrapper.log | grep "Duo" diff --git a/jans-auth-server/server/integrations/duo/lib/duo_web.py b/jans-auth-server/server/integrations/duo/lib/duo_web.py deleted file mode 100644 index 7bdfb6dde4a..00000000000 --- a/jans-auth-server/server/integrations/duo/lib/duo_web.py +++ /dev/null @@ -1,175 +0,0 @@ -# -# duo_web.py -# -# Copyright (c) 2011 Duo Security -# All rights reserved, all wrongs reversed. -# - -import base64 -import hashlib -import hmac -import time - -DUO_PREFIX = 'TX' -APP_PREFIX = 'APP' -AUTH_PREFIX = 'AUTH' -ENROLL_PREFIX = 'ENROLL' -ENROLL_REQUEST_PREFIX = 'ENROLL_REQUEST' - -DUO_EXPIRE = 300 -APP_EXPIRE = 3600 - -IKEY_LEN = 20 -SKEY_LEN = 40 -AKEY_LEN = 40 - -ERR_USER = 'ERR|The username passed to sign_request() is invalid.' -ERR_IKEY = 'ERR|The Duo integration key passed to sign_request() is invalid.' -ERR_SKEY = 'ERR|The Duo secret key passed to sign_request() is invalid.' -ERR_AKEY = 'ERR|The application secret key passed to sign_request() must be at least %s characters.' % AKEY_LEN -ERR_UNKNOWN = 'ERR|An unknown error has occurred.' - -def _hmac_sha1(key, msg): - ctx = hmac.new(key, msg, hashlib.sha1) - return ctx.hexdigest() - -def _sign_vals(key, vals, prefix, expire): - exp = str(int(time.time()) + expire) - - val = '|'.join(vals + [ exp ]) - b64 = base64.b64encode(val.encode('utf-8')).decode('utf-8') - cookie = '%s|%s' % (prefix, b64) - - sig = _hmac_sha1(key.encode('utf-8'), cookie.encode('utf-8')) - return '%s|%s' % (cookie, sig) - -def _parse_vals(key, val, prefix, ikey): - ts = int(time.time()) - u_prefix, u_b64, u_sig = val.split('|') - cookie = '%s|%s' % (u_prefix, u_b64) - e_key = key.encode('utf-8') - e_cookie = cookie.encode('utf-8') - - sig = _hmac_sha1(e_key, e_cookie) - if _hmac_sha1(e_key, sig.encode('utf-8')) != _hmac_sha1(e_key, u_sig.encode('utf-8')): - return None - - if u_prefix != prefix: - return None - - decoded = base64.b64decode(u_b64).decode('utf-8') - user, u_ikey, exp = decoded.split('|') - - if u_ikey != ikey: - return None - - if ts >= int(exp): - return None - - return user - -def _sign_request(ikey, skey, akey, username, prefix): - """Generate a signed request for Duo authentication. - The returned value should be passed into the Duo.init() call - in the rendered web page used for Duo authentication. - Arguments: - ikey -- Duo integration key - skey -- Duo secret key - akey -- Application secret key - username -- Primary-authenticated username - prefix -- DUO_PREFIX or ENROLL_REQUEST_PREFIX - """ - if not username: - return ERR_USER - if '|' in username: - return ERR_USER - if not ikey or len(ikey) != IKEY_LEN: - return ERR_IKEY - if not skey or len(skey) != SKEY_LEN: - return ERR_SKEY - if not akey or len(akey) < AKEY_LEN: - return ERR_AKEY - - vals = [ username, ikey ] - - try: - duo_sig = _sign_vals(skey, vals, prefix, DUO_EXPIRE) - app_sig = _sign_vals(akey, vals, APP_PREFIX, APP_EXPIRE) - except Exception: - return ERR_UNKNOWN - - return '%s:%s' % (duo_sig, app_sig) - - -def sign_request(ikey, skey, akey, username): - """Generate a signed request for Duo authentication. - The returned value should be passed into the Duo.init() call - in the rendered web page used for Duo authentication. - Arguments: - ikey -- Duo integration key - skey -- Duo secret key - akey -- Application secret key - username -- Primary-authenticated username - """ - return _sign_request(ikey, skey, akey, username, DUO_PREFIX) - - -def sign_enroll_request(ikey, skey, akey, username): - """Generate a signed request for Duo authentication. - The returned value should be passed into the Duo.init() call - in the rendered web page used for Duo authentication. - Arguments: - ikey -- Duo integration key - skey -- Duo secret key - akey -- Application secret key - username -- Primary-authenticated username - """ - return _sign_request(ikey, skey, akey, username, ENROLL_REQUEST_PREFIX) - - -def _verify_response(ikey, skey, akey, prefix, sig_response): - """Validate the signed response returned from Duo. - Returns the username of the authenticated user, or None. - Arguments: - ikey -- Duo integration key - skey -- Duo secret key - akey -- Application secret key - prefix -- AUTH_PREFIX or ENROLL_PREFIX that sig_response - must match - sig_response -- The signed response POST'ed to the server - """ - try: - auth_sig, app_sig = sig_response.split(':') - auth_user = _parse_vals(skey, auth_sig, AUTH_PREFIX, ikey) - app_user = _parse_vals(akey, app_sig, APP_PREFIX, ikey) - except Exception: - return None - - if auth_user != app_user: - return None - - return auth_user - - -def verify_response(ikey, skey, akey, sig_response): - """Validate the signed response returned from Duo. - Returns the username of the authenticated user, or None. - Arguments: - ikey -- Duo integration key - skey -- Duo secret key - akey -- Application secret key - sig_response -- The signed response POST'ed to the server - """ - return _verify_response(ikey, skey, akey, AUTH_PREFIX, sig_response) - - -def verify_enroll_response(ikey, skey, akey, sig_response): - """Validate the signed response returned from Duo. - Returns the username of the enrolled user, or None. - Arguments: - ikey -- Duo integration key - skey -- Duo secret key - akey -- Application secret key - sig_response -- The signed response POST'ed to the server - """ - return _verify_response(ikey, skey, akey, ENROLL_PREFIX, sig_response) diff --git a/jans-auth-server/server/integrations/fido2/Fido2ExternalAuthenticator.py b/jans-auth-server/server/integrations/fido2/Fido2ExternalAuthenticator.py deleted file mode 100644 index 52bf945b85e..00000000000 --- a/jans-auth-server/server/integrations/fido2/Fido2ExternalAuthenticator.py +++ /dev/null @@ -1,263 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan -# - -from javax.ws.rs.core import Response -from org.jboss.resteasy.client import ClientResponseFailure -from org.jboss.resteasy.client.exception import ResteasyClientException -from javax.ws.rs.core import Response -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from org.gluu.fido2.client import Fido2ClientFactory -from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService, SessionIdService -from io.jans.as.server.service.common import UserService -from io.jans.as.server.util import ServerUtil -from io.jans.service.cdi.util import CdiUtil -from io.jans.util import StringHelper - -from java.util.concurrent.locks import ReentrantLock - -import java -import sys -try: - import json -except ImportError: - import simplejson as json - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "Fido2. Initialization" - - if not configurationAttributes.containsKey("fido2_server_uri"): - print "fido2_server_uri. Initialization. Property fido2_server_uri is not specified" - return False - - self.fido2_server_uri = configurationAttributes.get("fido2_server_uri").getValue2() - - self.fido2_domain = None - if configurationAttributes.containsKey("fido2_domain"): - self.fido2_domain = configurationAttributes.get("fido2_domain").getValue2() - - self.metaDataLoaderLock = ReentrantLock() - self.metaDataConfiguration = None - - print "Fido2. Initialized successfully" - return True - - def destroy(self, configurationAttributes): - print "Fido2. Destroy" - print "Fido2. Destroyed successfully" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - authenticationService = CdiUtil.bean(AuthenticationService) - - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - - user_name = credentials.getUsername() - - if step == 1: - print "Fido2. Authenticate for step 1" - - user_password = credentials.getPassword() - logged_in = False - if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password): - userService = CdiUtil.bean(UserService) - logged_in = authenticationService.authenticate(user_name, user_password) - - if not logged_in: - return False - - return True - elif step == 2: - print "Fido2. Authenticate for step 2" - - token_response = ServerUtil.getFirstValue(requestParameters, "tokenResponse") - if token_response == None: - print "Fido2. Authenticate for step 2. tokenResponse is empty" - return False - - auth_method = ServerUtil.getFirstValue(requestParameters, "authMethod") - if auth_method == None: - print "Fido2. Authenticate for step 2. authMethod is empty" - return False - - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - if user == None: - print "Fido2. Prepare for step 2. Failed to determine user name" - return False - - if auth_method == 'authenticate': - print "Fido2. Prepare for step 2. Call Fido2 in order to finish authentication flow" - assertionService = Fido2ClientFactory.instance().createAssertionService(self.metaDataConfiguration) - assertionStatus = assertionService.verify(token_response) - authenticationStatusEntity = assertionStatus.readEntity(java.lang.String) - - if assertionStatus.getStatus() != Response.Status.OK.getStatusCode(): - print "Fido2. Authenticate for step 2. Get invalid authentication status from Fido2 server" - return False - - return True - elif auth_method == 'enroll': - print "Fido2. Prepare for step 2. Call Fido2 in order to finish registration flow" - attestationService = Fido2ClientFactory.instance().createAttestationService(self.metaDataConfiguration) - attestationStatus = attestationService.verify(token_response) - - if attestationStatus.getStatus() != Response.Status.OK.getStatusCode(): - print "Fido2. Authenticate for step 2. Get invalid registration status from Fido2 server" - return False - - return True - else: - print "Fido2. Prepare for step 2. Authentication method is invalid" - return False - - return False - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - identity = CdiUtil.bean(Identity) - - if step == 1: - return True - elif step == 2: - print "Fido2. Prepare for step 2" - - session = CdiUtil.bean(SessionIdService).getSessionId() - if session == None: - print "Fido2. Prepare for step 2. Failed to determine session_id" - return False - - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - if user == None: - print "Fido2. Prepare for step 2. Failed to determine user name" - return False - - userName = user.getUserId() - - metaDataConfiguration = self.getMetaDataConfiguration() - - assertionResponse = None - attestationResponse = None - - # Check if user have registered devices - userService = CdiUtil.bean(UserService) - countFido2Devices = userService.countFidoAndFido2Devices(userName, self.fido2_domain) - if countFido2Devices > 0: - print "Fido2. Prepare for step 2. Call Fido2 endpoint in order to start assertion flow" - - try: - assertionService = Fido2ClientFactory.instance().createAssertionService(metaDataConfiguration) - assertionRequest = json.dumps({'username': userName}, separators=(',', ':')) - assertionResponse = assertionService.authenticate(assertionRequest).readEntity(java.lang.String) - except ClientResponseFailure, ex: - print "Fido2. Prepare for step 2. Failed to start assertion flow. Exception:", sys.exc_info()[1] - return False - else: - print "Fido2. Prepare for step 2. Call Fido2 endpoint in order to start attestation flow" - - try: - attestationService = Fido2ClientFactory.instance().createAttestationService(metaDataConfiguration) - attestationRequest = json.dumps({'username': userName, 'displayName': userName, 'attestation' : 'direct'}, separators=(',', ':')) - attestationResponse = attestationService.register(attestationRequest).readEntity(java.lang.String) - except ClientResponseFailure, ex: - print "Fido2. Prepare for step 2. Failed to start attestation flow. Exception:", sys.exc_info()[1] - return False - - identity.setWorkingParameter("fido2_assertion_request", ServerUtil.asJson(assertionResponse)) - identity.setWorkingParameter("fido2_attestation_request", ServerUtil.asJson(attestationResponse)) - print "Fido2. Prepare for step 2. Successfully start flow with next requests.\nfido2_assertion_request: '%s'\nfido2_attestation_request: '%s'" % ( assertionResponse, attestationResponse ) - - return True - elif step == 3: - print "Fido2. Prepare for step 3" - - return True - else: - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - return 2 - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getPageForStep(self, configurationAttributes, step): - if step == 2: - return "/auth/fido2/login.xhtml" - - return "" - - def logout(self, configurationAttributes, requestParameters): - return True - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - - def getMetaDataConfiguration(self): - if self.metaDataConfiguration != None: - return self.metaDataConfiguration - - self.metaDataLoaderLock.lock() - # Make sure that another thread not loaded configuration already - if self.metaDataConfiguration != None: - return self.metaDataConfiguration - - try: - print "Fido2. Initialization. Downloading Fido2 metadata" - self.fido2_server_metadata_uri = self.fido2_server_uri + "/.well-known/fido2-configuration" - #self.fido2_server_metadata_uri = self.fido2_server_uri + "/fido2/restv1/fido2/configuration" - - metaDataConfigurationService = Fido2ClientFactory.instance().createMetaDataConfigurationService(self.fido2_server_metadata_uri) - - max_attempts = 10 - for attempt in range(1, max_attempts + 1): - try: - self.metaDataConfiguration = metaDataConfigurationService.getMetadataConfiguration().readEntity(java.lang.String) - return self.metaDataConfiguration - except ClientResponseFailure, ex: - # Detect if last try or we still get Service Unavailable HTTP error - if (attempt == max_attempts) or (ex.getResponse().getResponseStatus() != Response.Status.SERVICE_UNAVAILABLE): - raise ex - - java.lang.Thread.sleep(3000) - print "Attempting to load metadata: %d" % attempt - except ResteasyClientException, ex: - # Detect if last try or we still get Service Unavailable HTTP error - if attempt == max_attempts: - raise ex - - java.lang.Thread.sleep(3000) - print "Attempting to load metadata: %d" % attempt - finally: - self.metaDataLoaderLock.unlock() - diff --git a/jans-auth-server/server/integrations/otp/Installation.md b/jans-auth-server/server/integrations/otp/Installation.md deleted file mode 100644 index 69d455a854b..00000000000 --- a/jans-auth-server/server/integrations/otp/Installation.md +++ /dev/null @@ -1,27 +0,0 @@ -This list of steps needed to do to enable SAML person authentication module. - -1. Confire new custom module in oxTrust: - - Log into oxTrust with administrative permissions. - - Open "Configuration→Manage Custom Scripts" page. - - Select "Person Authentication" tab. - - Click on "Add custom script configuration" link. - - Enter name = otp - - Enter level = 0-100 (priority of this method). - - Select usage type "Interactive". - - Add custom required and optional properties which specified in "Properties description.md". - - Copy/paste script from TotpExternalAuthenticator.py. - - Activate it via "Enabled" checkbox. - - Click "Update" button at the bottom of this page. - -2. Configure oxAuth to use OTP authentication by default: - - Log into oxTrust with administrative permissions. - - Open "Configuration→Manage Authentication" page. - - Scroll to "Default Authentication Method" panel. Select "otp" authentication mode. - - Click "Update" button at the bottom of this page. - -3. Try to log in using OTP authentication method: - - Wait 30 seconds and try to log in again. During this time oxAuth reload list of available person authentication modules. - - Open second browser or second browsing session and try to log in again. It's better to try to do that from another browser session because we can return back to previous authentication method if something will go wrong. - -There are log messages in this custom authentication script. In order to debug this module we can use command like this: -tail -f /opt/tomcat/logs/wrapper.log | grep "OTP" diff --git a/jans-auth-server/server/integrations/otp/OtpExternalAuthenticator.py b/jans-auth-server/server/integrations/otp/OtpExternalAuthenticator.py deleted file mode 100644 index 20405cfc9f0..00000000000 --- a/jans-auth-server/server/integrations/otp/OtpExternalAuthenticator.py +++ /dev/null @@ -1,617 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan -# - -# Requires the following custom properties and values: -# otp_type: totp/hotp -# issuer: Gluu Inc -# otp_conf_file: /etc/certs/otp_configuration.json -# -# These are non mandatory custom properties and values: -# label: Gluu OTP -# qr_options: { width: 400, height: 400 } -# registration_uri: https://ce-dev.gluu.org/identity/register - -import jarray -import json -import sys -from com.google.common.io import BaseEncoding -from com.lochbridge.oath.otp import HOTP -from com.lochbridge.oath.otp import HOTPValidator -from com.lochbridge.oath.otp import HmacShaAlgorithm -from com.lochbridge.oath.otp import TOTP -from com.lochbridge.oath.otp.keyprovisioning import OTPAuthURIBuilder -from com.lochbridge.oath.otp.keyprovisioning import OTPKey -from com.lochbridge.oath.otp.keyprovisioning.OTPKey import OTPType -from java.security import SecureRandom -from java.util import Arrays -from java.util.concurrent import TimeUnit -from javax.faces.application import FacesMessage -from io.jans.jsf2.message import FacesMessages -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService, SessionIdService -from io.jans.as.server.service.common import UserService -from io.jans.as.server.util import ServerUtil -from io.jans.service.cdi.util import CdiUtil -from io.jans.util import StringHelper - - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "OTP. Initialization" - - if not configurationAttributes.containsKey("otp_type"): - print "OTP. Initialization. Property otp_type is mandatory" - return False - self.otpType = configurationAttributes.get("otp_type").getValue2() - - if not self.otpType in ["hotp", "totp"]: - print "OTP. Initialization. Property value otp_type is invalid" - return False - - if not configurationAttributes.containsKey("issuer"): - print "OTP. Initialization. Property issuer is mandatory" - return False - self.otpIssuer = configurationAttributes.get("issuer").getValue2() - - self.customLabel = None - if configurationAttributes.containsKey("label"): - self.customLabel = configurationAttributes.get("label").getValue2() - - self.customQrOptions = {} - if configurationAttributes.containsKey("qr_options"): - self.customQrOptions = configurationAttributes.get("qr_options").getValue2() - - self.registrationUri = None - if configurationAttributes.containsKey("registration_uri"): - self.registrationUri = configurationAttributes.get("registration_uri").getValue2() - - validOtpConfiguration = self.loadOtpConfiguration(configurationAttributes) - if not validOtpConfiguration: - return False - - print "OTP. Initialized successfully" - return True - - def destroy(self, configurationAttributes): - print "OTP. Destroy" - print "OTP. Destroyed successfully" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def getNextStep(self, configurationAttributes, requestParameters, step): - print "getNextStep Invoked" - # If user not pass current step change step to previous - identity = CdiUtil.bean(Identity) - retry_current_step = identity.getWorkingParameter("retry_current_step") - if retry_current_step: - print "OTP. Get next step. Retrying current step %s" % step - # Remove old QR code - #identity.setWorkingParameter("super_gluu_request", "timeout") - resultStep = step - return resultStep - return -1 - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - authenticationService = CdiUtil.bean(AuthenticationService) - - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - - self.setRequestScopedParameters(identity) - - if step == 1: - print "OTP. Authenticate for step 1" - authenticated_user = self.processBasicAuthentication(credentials) - if authenticated_user == None: - return False - - otp_auth_method = "authenticate" - # Uncomment this block if you need to allow user second OTP registration - #enrollment_mode = ServerUtil.getFirstValue(requestParameters, "loginForm:registerButton") - #if StringHelper.isNotEmpty(enrollment_mode): - # otp_auth_method = "enroll" - - if otp_auth_method == "authenticate": - user_enrollments = self.findEnrollments(authenticated_user.getUserId()) - if len(user_enrollments) == 0: - otp_auth_method = "enroll" - print "OTP. Authenticate for step 1. There is no OTP enrollment for user '%s'. Changing otp_auth_method to '%s'" % (authenticated_user.getUserId(), otp_auth_method) - - if otp_auth_method == "enroll": - print "OTP. Authenticate for step 1. Setting count steps: '%s'" % 3 - identity.setWorkingParameter("otp_count_login_steps", 3) - - print "OTP. Authenticate for step 1. otp_auth_method: '%s'" % otp_auth_method - identity.setWorkingParameter("otp_auth_method", otp_auth_method) - - return True - elif step == 2: - print "OTP. Authenticate for step 2" - - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - if user == None: - print "OTP. Authenticate for step 2. Failed to determine user name" - return False - - session_id_validation = self.validateSessionId(identity) - if not session_id_validation: - return False - - # Restore state from session - identity.setWorkingParameter("retry_current_step", False) - otp_auth_method = identity.getWorkingParameter("otp_auth_method") - if otp_auth_method == 'enroll': - auth_result = ServerUtil.getFirstValue(requestParameters, "auth_result") - if not StringHelper.isEmpty(auth_result): - # defect fix #1225 - Retry the step, show QR code again - if auth_result == 'timeout': - print "OTP. QR-code timeout. Authenticate for step %s. Reinitializing current step" % step - identity.setWorkingParameter("retry_current_step", True) - return True - - print "OTP. Authenticate for step 2. User not enrolled OTP" - return False - - print "OTP. Authenticate for step 2. Skipping this step during enrollment" - return True - - otp_auth_result = self.processOtpAuthentication(requestParameters, user.getUserId(), identity, otp_auth_method) - print "OTP. Authenticate for step 2. OTP authentication result: '%s'" % otp_auth_result - - return otp_auth_result - elif step == 3: - print "OTP. Authenticate for step 3" - - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - if user == None: - print "OTP. Authenticate for step 2. Failed to determine user name" - return False - - session_id_validation = self.validateSessionId(identity) - if not session_id_validation: - return False - - # Restore state from session - otp_auth_method = identity.getWorkingParameter("otp_auth_method") - if otp_auth_method != 'enroll': - return False - - otp_auth_result = self.processOtpAuthentication(requestParameters, user.getUserId(), identity, otp_auth_method) - print "OTP. Authenticate for step 3. OTP authentication result: '%s'" % otp_auth_result - - return otp_auth_result - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - - self.setRequestScopedParameters(identity) - - if step == 1: - print "OTP. Prepare for step 1" - - return True - elif step == 2: - print "OTP. Prepare for step 2" - - session_id_validation = self.validateSessionId(identity) - if not session_id_validation: - return False - - otp_auth_method = identity.getWorkingParameter("otp_auth_method") - print "OTP. Prepare for step 2. otp_auth_method: '%s'" % otp_auth_method - - if otp_auth_method == 'enroll': - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - if user == None: - print "OTP. Prepare for step 2. Failed to load user enty" - return False - - if self.otpType == "hotp": - otp_secret_key = self.generateSecretHotpKey() - otp_enrollment_request = self.generateHotpSecretKeyUri(otp_secret_key, self.otpIssuer, user.getAttribute("displayName")) - elif self.otpType == "totp": - otp_secret_key = self.generateSecretTotpKey() - otp_enrollment_request = self.generateTotpSecretKeyUri(otp_secret_key, self.otpIssuer, user.getAttribute("displayName")) - else: - print "OTP. Prepare for step 2. Unknown OTP type: '%s'" % self.otpType - return False - - print "OTP. Prepare for step 2. Prepared enrollment request for user: '%s'" % user.getUserId() - identity.setWorkingParameter("otp_secret_key", self.toBase64Url(otp_secret_key)) - identity.setWorkingParameter("otp_enrollment_request", otp_enrollment_request) - - return True - elif step == 3: - print "OTP. Prepare for step 3" - - session_id_validation = self.validateSessionId(identity) - if not session_id_validation: - return False - - otp_auth_method = identity.getWorkingParameter("otp_auth_method") - print "OTP. Prepare for step 3. otp_auth_method: '%s'" % otp_auth_method - - if otp_auth_method == 'enroll': - return True - - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - return Arrays.asList("otp_auth_method", "otp_count_login_steps", "otp_secret_key", "otp_enrollment_request","retry_current_step") - - def getCountAuthenticationSteps(self, configurationAttributes): - identity = CdiUtil.bean(Identity) - - if identity.isSetWorkingParameter("otp_count_login_steps"): - return StringHelper.toInteger("%s" % identity.getWorkingParameter("otp_count_login_steps")) - else: - return 2 - - def getPageForStep(self, configurationAttributes, step): - if step == 2: - identity = CdiUtil.bean(Identity) - - otp_auth_method = identity.getWorkingParameter("otp_auth_method") - print "OTP. Gep page for step 2. otp_auth_method: '%s'" % otp_auth_method - - if otp_auth_method == 'enroll': - return "/auth/otp/enroll.xhtml" - else: - return "/auth/otp/otplogin.xhtml" - elif step == 3: - return "/auth/otp/otplogin.xhtml" - - return "" - - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True - - def setRequestScopedParameters(self, identity): - if self.registrationUri != None: - identity.setWorkingParameter("external_registration_uri", self.registrationUri) - - if self.customLabel != None: - identity.setWorkingParameter("qr_label", self.customLabel) - - identity.setWorkingParameter("qr_options", self.customQrOptions) - - def loadOtpConfiguration(self, configurationAttributes): - print "OTP. Load OTP configuration" - if not configurationAttributes.containsKey("otp_conf_file"): - return False - - otp_conf_file = configurationAttributes.get("otp_conf_file").getValue2() - - # Load configuration from file - f = open(otp_conf_file, 'r') - try: - otpConfiguration = json.loads(f.read()) - except: - print "OTP. Load OTP configuration. Failed to load configuration from file:", otp_conf_file - return False - finally: - f.close() - - # Check configuration file settings - try: - self.hotpConfiguration = otpConfiguration["hotp"] - self.totpConfiguration = otpConfiguration["totp"] - - hmacShaAlgorithm = self.totpConfiguration["hmacShaAlgorithm"] - hmacShaAlgorithmType = None - - if StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha1"): - hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_1 - elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha256"): - hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_256 - elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha512"): - hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_512 - else: - print "OTP. Load OTP configuration. Invalid TOTP HMAC SHA algorithm: '%s'" % hmacShaAlgorithm - - self.totpConfiguration["hmacShaAlgorithmType"] = hmacShaAlgorithmType - except: - print "OTP. Load OTP configuration. Invalid configuration file '%s' format. Exception: '%s'" % (otp_conf_file, sys.exc_info()[1]) - return False - - - return True - - def processBasicAuthentication(self, credentials): - userService = CdiUtil.bean(UserService) - authenticationService = CdiUtil.bean(AuthenticationService) - - user_name = credentials.getUsername() - user_password = credentials.getPassword() - - logged_in = False - if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password): - logged_in = authenticationService.authenticate(user_name, user_password) - - if not logged_in: - return None - - find_user_by_uid = authenticationService.getAuthenticatedUser() - if find_user_by_uid == None: - print "OTP. Process basic authentication. Failed to find user '%s'" % user_name - return None - - return find_user_by_uid - - def findEnrollments(self, user_name, skipPrefix = True): - result = [] - - userService = CdiUtil.bean(UserService) - user = userService.getUser(user_name, "oxExternalUid") - if user == None: - print "OTP. Find enrollments. Failed to find user" - return result - - user_custom_ext_attribute = userService.getCustomAttribute(user, "oxExternalUid") - if user_custom_ext_attribute == None: - return result - - otp_prefix = "%s:" % self.otpType - - otp_prefix_length = len(otp_prefix) - for user_external_uid in user_custom_ext_attribute.getValues(): - index = user_external_uid.find(otp_prefix) - if index != -1: - if skipPrefix: - enrollment_uid = user_external_uid[otp_prefix_length:] - else: - enrollment_uid = user_external_uid - - result.append(enrollment_uid) - - return result - - def validateSessionId(self, identity): - session = CdiUtil.bean(SessionIdService).getSessionId() - if session == None: - print "OTP. Validate session id. Failed to determine session_id" - return False - - otp_auth_method = identity.getWorkingParameter("otp_auth_method") - if not otp_auth_method in ['enroll', 'authenticate']: - print "OTP. Validate session id. Failed to authenticate user. otp_auth_method: '%s'" % otp_auth_method - return False - - return True - - def processOtpAuthentication(self, requestParameters, user_name, identity, otp_auth_method): - facesMessages = CdiUtil.bean(FacesMessages) - facesMessages.setKeepMessages() - - userService = CdiUtil.bean(UserService) - - otpCode = ServerUtil.getFirstValue(requestParameters, "loginForm:otpCode") - if StringHelper.isEmpty(otpCode): - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to authenticate. OTP code is empty") - print "OTP. Process OTP authentication. otpCode is empty" - - return False - - if otp_auth_method == "enroll": - # Get key from session - otp_secret_key_encoded = identity.getWorkingParameter("otp_secret_key") - if otp_secret_key_encoded == None: - print "OTP. Process OTP authentication. OTP secret key is invalid" - return False - - otp_secret_key = self.fromBase64Url(otp_secret_key_encoded) - - if self.otpType == "hotp": - validation_result = self.validateHotpKey(otp_secret_key, 1, otpCode) - - if (validation_result != None) and validation_result["result"]: - print "OTP. Process HOTP authentication during enrollment. otpCode is valid" - # Store HOTP Secret Key and moving factor in user entry - otp_user_external_uid = "hotp:%s;%s" % ( otp_secret_key_encoded, validation_result["movingFactor"] ) - - # Add otp_user_external_uid to user's external GUID list - find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", otp_user_external_uid, True) - if find_user_by_external_uid != None: - return True - - print "OTP. Process HOTP authentication during enrollment. Failed to update user entry" - elif self.otpType == "totp": - validation_result = self.validateTotpKey(otp_secret_key, otpCode,user_name) - if (validation_result != None) and validation_result["result"]: - print "OTP. Process TOTP authentication during enrollment. otpCode is valid" - # Store TOTP Secret Key and moving factor in user entry - otp_user_external_uid = "totp:%s" % otp_secret_key_encoded - - # Add otp_user_external_uid to user's external GUID list - find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", otp_user_external_uid, True) - if find_user_by_external_uid != None: - return True - - print "OTP. Process TOTP authentication during enrollment. Failed to update user entry" - elif otp_auth_method == "authenticate": - user_enrollments = self.findEnrollments(user_name) - - if len(user_enrollments) == 0: - print "OTP. Process OTP authentication. There is no OTP enrollment for user '%s'" % user_name - facesMessages.add(FacesMessage.SEVERITY_ERROR, "There is no valid OTP user enrollments") - return False - - if self.otpType == "hotp": - for user_enrollment in user_enrollments: - user_enrollment_data = user_enrollment.split(";") - otp_secret_key_encoded = user_enrollment_data[0] - - # Get current moving factor from user entry - moving_factor = StringHelper.toInteger(user_enrollment_data[1]) - otp_secret_key = self.fromBase64Url(otp_secret_key_encoded) - - # Validate TOTP - validation_result = self.validateHotpKey(otp_secret_key, moving_factor, otpCode) - if (validation_result != None) and validation_result["result"]: - print "OTP. Process HOTP authentication during authentication. otpCode is valid" - otp_user_external_uid = "hotp:%s;%s" % ( otp_secret_key_encoded, moving_factor ) - new_otp_user_external_uid = "hotp:%s;%s" % ( otp_secret_key_encoded, validation_result["movingFactor"] ) - - # Update moving factor in user entry - find_user_by_external_uid = userService.replaceUserAttribute(user_name, "oxExternalUid", otp_user_external_uid, new_otp_user_external_uid, True) - if find_user_by_external_uid != None: - return True - - print "OTP. Process HOTP authentication during authentication. Failed to update user entry" - elif self.otpType == "totp": - for user_enrollment in user_enrollments: - otp_secret_key = self.fromBase64Url(user_enrollment) - - # Validate TOTP - validation_result = self.validateTotpKey(otp_secret_key, otpCode, user_name) - if (validation_result != None) and validation_result["result"]: - print "OTP. Process TOTP authentication during authentication. otpCode is valid" - return True - - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to authenticate. OTP code is invalid") - print "OTP. Process OTP authentication. OTP code is invalid" - - return False - - # Shared HOTP/TOTP methods - def generateSecretKey(self, keyLength): - bytes = jarray.zeros(keyLength, "b") - secureRandom = SecureRandom() - secureRandom.nextBytes(bytes) - - return bytes - - # HOTP methods - def generateSecretHotpKey(self): - keyLength = self.hotpConfiguration["keyLength"] - - return self.generateSecretKey(keyLength) - - def generateHotpKey(self, secretKey, movingFactor): - digits = self.hotpConfiguration["digits"] - - hotp = HOTP.key(secretKey).digits(digits).movingFactor(movingFactor).build() - - return hotp.value() - - def validateHotpKey(self, secretKey, movingFactor, totpKey): - lookAheadWindow = self.hotpConfiguration["lookAheadWindow"] - digits = self.hotpConfiguration["digits"] - - htopValidationResult = HOTPValidator.lookAheadWindow(lookAheadWindow).validate(secretKey, movingFactor, digits, totpKey) - if htopValidationResult.isValid(): - return { "result": True, "movingFactor": htopValidationResult.getNewMovingFactor() } - - return { "result": False, "movingFactor": None } - - def generateHotpSecretKeyUri(self, secretKey, issuer, userDisplayName): - digits = self.hotpConfiguration["digits"] - - secretKeyBase32 = self.toBase32(secretKey) - otpKey = OTPKey(secretKeyBase32, OTPType.HOTP) - label = issuer + " %s" % userDisplayName - - otpAuthURI = OTPAuthURIBuilder.fromKey(otpKey).label(label).issuer(issuer).digits(digits).build() - - return otpAuthURI.toUriString() - - # TOTP methods - def generateSecretTotpKey(self): - keyLength = self.totpConfiguration["keyLength"] - - return self.generateSecretKey(keyLength) - - def generateTotpKey(self, secretKey): - digits = self.totpConfiguration["digits"] - timeStep = self.totpConfiguration["timeStep"] - hmacShaAlgorithmType = self.totpConfiguration["hmacShaAlgorithmType"] - - totp = TOTP.key(secretKey).digits(digits).timeStep(TimeUnit.SECONDS.toMillis(timeStep)).hmacSha(hmacShaAlgorithmType).build() - - return totp.value() - - def validateTotpKey(self, secretKey, totpKey, user_name): - localTotpKey = self.generateTotpKey(secretKey) - cachedOTP = self.getCachedOTP(user_name) - - if StringHelper.equals(localTotpKey, totpKey) and not StringHelper.equals(localTotpKey, cachedOTP): - userService = CdiUtil.bean(UserService) - if cachedOTP is None: - userService.addUserAttribute(user_name, "oxOTPCache",localTotpKey) - else : - userService.replaceUserAttribute(user_name, "oxOTPCache", cachedOTP, localTotpKey) - print "OTP. Caching OTP: '%s'" % localTotpKey - return { "result": True } - return { "result": False } - - def getCachedOTP(self, user_name): - userService = CdiUtil.bean(UserService) - user = userService.getUser(user_name, "oxOTPCache") - if user is None: - print "OTP. Get Cached OTP. Failed to find OTP" - return None - customAttribute = userService.getCustomAttribute(user, "oxOTPCache") - - if customAttribute is None: - print "OTP. Custom attribute is null" - return None - user_cached_OTP = customAttribute.getValue() - if user_cached_OTP is None: - print "OTP. no OTP is present in LDAP" - return None - - print "OTP.Cached OTP: '%s'" % user_cached_OTP - return user_cached_OTP - - def generateTotpSecretKeyUri(self, secretKey, issuer, userDisplayName): - digits = self.totpConfiguration["digits"] - timeStep = self.totpConfiguration["timeStep"] - - secretKeyBase32 = self.toBase32(secretKey) - otpKey = OTPKey(secretKeyBase32, OTPType.TOTP) - label = issuer + " %s" % userDisplayName - - otpAuthURI = OTPAuthURIBuilder.fromKey(otpKey).label(label).issuer(issuer).digits(digits).timeStep(TimeUnit.SECONDS.toMillis(timeStep)).build() - - return otpAuthURI.toUriString() - - # Utility methods - def toBase32(self, bytes): - return BaseEncoding.base32().omitPadding().encode(bytes) - - def toBase64Url(self, bytes): - return BaseEncoding.base64Url().encode(bytes) - - def fromBase64Url(self, chars): - return BaseEncoding.base64Url().decode(chars) - - diff --git a/jans-auth-server/server/integrations/otp/Readme.md b/jans-auth-server/server/integrations/otp/Readme.md deleted file mode 100644 index 4928b36398f..00000000000 --- a/jans-auth-server/server/integrations/otp/Readme.md +++ /dev/null @@ -1,5 +0,0 @@ -# One-Time Password (OTP) Authentication - -Gluu's OTP interception script uses the two-factor event/counter-based HOTP algorithm [RFC4226](https://tools.ietf.org/html/rfc4226) and the time-based TOTP algorithm [RFC6238](https://tools.ietf.org/html/rfc6238). - -In order to use this authentication mechanism users will need to install a mobile authenticator, like [Google Authenticator 2](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2), that supports HOTP/TOTP. diff --git a/jans-auth-server/server/integrations/smpp/smpp2FA.py b/jans-auth-server/server/integrations/smpp/smpp2FA.py deleted file mode 100644 index 828550264cd..00000000000 --- a/jans-auth-server/server/integrations/smpp/smpp2FA.py +++ /dev/null @@ -1,434 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# Copyright (c) 2019, Tele2 - -# Author: Jose Gonzalez -# Author: Gasmyr Mougang -# Author: Stefan Andersson - -from java.util import Arrays, Date -from java.io import IOException -from java.lang import Enum - -from io.jans.service.cdi.util import CdiUtil -from io.jans.as.server.security import Identity -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.server.service import AuthenticationService -from io.jans.as.server.service.common import UserService -from io.jans.as.server.util import ServerUtil -from io.jans.util import StringHelper, ArrayHelper -from javax.faces.application import FacesMessage -from io.jans.jsf2.message import FacesMessages - -from org.jsmpp import InvalidResponseException, PDUException -from org.jsmpp.bean import Alphabet, BindType, ESMClass, GeneralDataCoding, MessageClass, NumberingPlanIndicator, RegisteredDelivery, SMSCDeliveryReceipt, TypeOfNumber -from org.jsmpp.extra import NegativeResponseException, ResponseTimeoutException -from org.jsmpp.session import BindParameter, SMPPSession -from org.jsmpp.util import AbsoluteTimeFormatter, TimeFormatter -import random - - -class SmppAttributeError(Exception): - pass - - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - self.identity = CdiUtil.bean(Identity) - - def get_and_parse_smpp_config(self, config, attribute, _type = None, convert = False, optional = False, default_desc = None): - try: - value = config.get(attribute).getValue2() - except: - if default_desc: - default_desc = " using default '{}'".format(default_desc) - else: - default_desc = "" - - if optional: - raise SmppAttributeError("SMPP missing optional configuration attribute '{}'{}".format(attribute, default_desc)) - else: - raise SmppAttributeError("SMPP missing required configuration attribute '{}'".format(attribute)) - - if _type and issubclass(_type, Enum): - try: - return getattr(_type, value) - except AttributeError: - raise SmppAttributeError("SMPP could not find attribute '{}' in {}".format(attribute, _type)) - - if convert: - try: - value = int(value) - except AttributeError: - try: - value = int(value, 16) - except AttributeError: - raise SmppAttributeError("SMPP could not parse value '{}' of attribute '{}'".format(value, attribute)) - - return value - - def init(self, customScript, configurationAttributes): - print("SMPP Initialization") - - self.TIME_FORMATTER = AbsoluteTimeFormatter() - - self.SMPP_SERVER = None - self.SMPP_PORT = None - - self.SYSTEM_ID = None - self.PASSWORD = None - - # Setup some good defaults for TON, NPI and source (from) address - # TON (Type of Number), NPI (Number Plan Indicator) - self.SRC_ADDR_TON = TypeOfNumber.ALPHANUMERIC # Alphanumeric - self.SRC_ADDR_NPI = NumberingPlanIndicator.ISDN # ISDN (E163/E164) - self.SRC_ADDR = "Gluu OTP" - - # Don't touch these unless you know what your doing, we don't handle number reformatting for - # any other type than international. - self.DST_ADDR_TON = TypeOfNumber.INTERNATIONAL # International - self.DST_ADDR_NPI = NumberingPlanIndicator.ISDN # ISDN (E163/E164) - - # Priority flag and data_coding bits - self.PRIORITY_FLAG = 3 # Very Urgent (ANSI-136), Emergency (IS-95) - self.DATA_CODING_ALPHABET = Alphabet.ALPHA_DEFAULT # SMS default alphabet - self.DATA_CODING_MESSAGE_CLASS = MessageClass.CLASS1 # EM (Mobile Equipment (mobile memory), normal message - - # Required server settings - try: - self.SMPP_SERVER = self.get_and_parse_smpp_config(configurationAttributes, "smpp_server") - except SmppAttributeError as e: - print(e) - - try: - self.SMPP_PORT = self.get_and_parse_smpp_config(configurationAttributes, "smpp_port", convert = True) - except SmppAttributeError as e: - print(e) - - if None in (self.SMPP_SERVER, self.SMPP_PORT): - print("SMPP smpp_server and smpp_port is empty, will not enable SMPP service") - return False - - # Optional system_id and password for bind auth - try: - self.SYSTEM_ID = self.get_and_parse_smpp_config(configurationAttributes, "system_id", optional = True) - except SmppAttributeError as e: - print(e) - - try: - self.PASSWORD = self.get_and_parse_smpp_config(configurationAttributes, "password", optional = True) - except SmppAttributeError as e: - print(e) - - if None in (self.SYSTEM_ID, self.PASSWORD): - print("SMPP Authentication disabled") - - # From number and to number settings - try: - self.SRC_ADDR_TON = self.get_and_parse_smpp_config( - configurationAttributes, - "source_addr_ton", - _type = TypeOfNumber, - optional = True, - default_desc = self.SRC_ADDR_TON - ) - except SmppAttributeError as e: - print(e) - - try: - self.SRC_ADDR_NPI = self.get_and_parse_smpp_config( - configurationAttributes, - "source_addr_npi", - _type = NumberingPlanIndicator, - optional = True, - default_desc = self.SRC_ADDR_NPI - ) - except SmppAttributeError as e: - print(e) - - try: - self.SRC_ADDR = self.get_and_parse_smpp_config( - configurationAttributes, - "source_addr", - optional = True, - default_desc = self.SRC_ADDR - ) - except SmppAttributeError as e: - print(e) - - try: - self.DST_ADDR_TON = self.get_and_parse_smpp_config( - configurationAttributes, - "dest_addr_ton", - _type = TypeOfNumber, - optional = True, - default_desc = self.DST_ADDR_TON - ) - except SmppAttributeError as e: - print(e) - - try: - self.DST_ADDR_NPI = self.get_and_parse_smpp_config( - configurationAttributes, - "dest_addr_npi", - _type = NumberingPlanIndicator, - optional = True, - default_desc = self.DST_ADDR_NPI - ) - except SmppAttributeError as e: - print(e) - - # Priority flag and data coding, don't touch these unless you know what your doing... - try: - self.PRIORITY_FLAG = self.get_and_parse_smpp_config( - configurationAttributes, - "priority_flag", - convert = True, - optional = True, - default_desc = "3 (Very Urgent, Emergency)" - ) - except SmppAttributeError as e: - print(e) - - try: - self.DATA_CODING_ALPHABET = self.get_and_parse_smpp_config( - configurationAttributes, - "data_coding_alphabet", - _type = Alphabet, - optional = True, - default_desc = self.DATA_CODING_ALPHABET - ) - except SmppAttributeError as e: - print(e) - - try: - self.DATA_CODING_MESSAGE_CLASS = self.get_and_parse_smpp_config( - configurationAttributes, - "data_coding_alphabet", - _type = MessageClass, - optional = True, - default_desc = self.DATA_CODING_MESSAGE_CLASS - ) - except SmppAttributeError as e: - print(e) - - print("SMPP Initialized successfully") - return True - - def destroy(self, configurationAttributes): - print("SMPP Destroy") - print("SMPP Destroyed successfully") - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - userService = CdiUtil.bean(UserService) - authenticationService = CdiUtil.bean(AuthenticationService) - - facesMessages = CdiUtil.bean(FacesMessages) - facesMessages.setKeepMessages() - - session_attributes = self.identity.getSessionId().getSessionAttributes() - form_passcode = ServerUtil.getFirstValue(requestParameters, "passcode") - - print("SMPP form_response_passcode: {}".format(str(form_passcode))) - - if step == 1: - print("SMPP Step 1 Password Authentication") - credentials = self.identity.getCredentials() - - user_name = credentials.getUsername() - user_password = credentials.getPassword() - - logged_in = False - if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password): - logged_in = authenticationService.authenticate(user_name, user_password) - - if not logged_in: - return False - - # Get the Person's number and generate a code - foundUser = None - try: - foundUser = authenticationService.getAuthenticatedUser() - except: - print("SMPP Error retrieving user {} from LDAP".format(user_name)) - return False - - mobile_number = None - try: - isVerified = foundUser.getAttribute("phoneNumberVerified") - if isVerified: - mobile_number = foundUser.getAttribute("employeeNumber") - if not mobile_number: - mobile_number = foundUser.getAttribute("mobile") - if not mobile_number: - mobile_number = foundUser.getAttribute("telephoneNumber") - if not mobile_number: - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to determine mobile phone number") - print("SMPP Error finding mobile number for user '{}'".format(user_name)) - return False - except Exception as e: - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to determine mobile phone number") - print("SMPP Error finding mobile number for {}: {}".format(user_name, e)) - return False - - # Generate Random six digit code - code = random.randint(100000, 999999) - - # Get code and save it in LDAP temporarily with special session entry - self.identity.setWorkingParameter("code", code) - - self.identity.setWorkingParameter("mobile_number", mobile_number) - self.identity.getSessionId().getSessionAttributes().put("mobile_number", mobile_number) - if not self.sendMessage(mobile_number, str(code)): - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to send message to mobile phone") - return False - - return True - elif step == 2: - # Retrieve the session attribute - print("SMPP Step 2 SMS/OTP Authentication") - code = session_attributes.get("code") - print("SMPP Code: {}".format(str(code))) - - if code is None: - print("SMPP Failed to find previously sent code") - return False - - if form_passcode is None: - print("SMPP Passcode is empty") - return False - - if len(form_passcode) != 6: - print("SMPP Passcode from response is not 6 digits: {}".format(form_passcode)) - return False - - if form_passcode == code: - print("SMPP SUCCESS! User entered the same code!") - return True - - print("SMPP failed, user entered the wrong code! {} != {}".format(form_passcode, code)) - facesMessages.add(facesMessage.SEVERITY_ERROR, "Incorrect SMS code, please try again.") - return False - - print("SMPP ERROR: step param not found or != (1|2)") - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - if step == 1: - print("SMPP Prepare for Step 1") - return True - elif step == 2: - print("SMPP Prepare for Step 2") - return True - - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - if step == 2: - return Arrays.asList("code") - - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - return 2 - - def getPageForStep(self, configurationAttributes, step): - if step == 2: - return "/auth/otp_sms/otp_sms.xhtml" - - return "" - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True - - def sendMessage(self, number, code): - status = False - session = SMPPSession() - session.setTransactionTimer(10000) - - # We only handle international destination number reformatting. - # All others may vary by configuration decisions taken on SMPP - # server side which we have no clue about. - if self.DST_ADDR_TON == TypeOfNumber.INTERNATIONAL and number.startswith("+"): - number = number[1:] - - try: - print("SMPP Connecting") - reference_id = session.connectAndBind( - self.SMPP_SERVER, - self.SMPP_PORT, - BindParameter( - BindType.BIND_TX, - self.SYSTEM_ID, - self.PASSWORD, - None, - self.SRC_ADDR_TON, - self.SRC_ADDR_NPI, - None - ) - ) - print("SMPP Connected to server with system id {}".format(reference_id)) - - try: - message_id = session.submitShortMessage( - "CMT", - self.SRC_ADDR_TON, - self.SRC_ADDR_NPI, - self.SRC_ADDR, - self.DST_ADDR_TON, - self.DST_ADDR_NPI, - number, - ESMClass(), - 0, - self.PRIORITY_FLAG, - self.TIME_FORMATTER.format(Date()), - None, - RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT), - 0, - GeneralDataCoding( - self.DATA_CODING_ALPHABET, - self.DATA_CODING_MESSAGE_CLASS, - False - ), - 0, - code - ) - print("SMPP Message '{}' sent to #{} with message id {}".format(code, number, message_id)) - status = True - except PDUException as e: - print("SMPP Invalid PDU parameter: {}".format(e)) - except ResponseTimeoutException as e: - print("SMPP Response timeout: {}".format(e)) - except InvalidResponseException as e: - print("SMPP Receive invalid response: {}".format(e)) - except NegativeResponseException as e: - print("SMPP Receive negative response: {}".format(e)) - except IOException as e: - print("SMPP IO error occured: {}".format(e)) - finally: - session.unbindAndClose() - except IOException as e: - print("SMPP Failed connect and bind to host: {}".format(e)) - - return status diff --git a/jans-auth-server/server/integrations/super_gluu/SuperGluuExternalAuthenticator.py b/jans-auth-server/server/integrations/super_gluu/SuperGluuExternalAuthenticator.py deleted file mode 100644 index 07d4644f98f..00000000000 --- a/jans-auth-server/server/integrations/super_gluu/SuperGluuExternalAuthenticator.py +++ /dev/null @@ -1,1073 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan -# - -from com.google.android.gcm.server import Sender, Message -from com.notnoop.apns import APNS -from java.util import Arrays -from org.apache.http.params import CoreConnectionPNames -from io.jans.service.cdi.util import CdiUtil -from io.jans.as.server.security import Identity -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from org.gluu.oxauth.model.config import ConfigurationFactory -from io.jans.as.server.service import AuthenticationService, SessionIdService -from io.jans.as.server.service.fido.u2f import DeviceRegistrationService -from io.jans.as.server.service.net import HttpService -from io.jans.as.server.util import ServerUtil -from io.jans.util import StringHelper -from io.jans.as.server.service.common import EncryptionService, UserService -from io.jans.service import MailService -from io.jans.as.server.service.push.sns import PushPlatform, PushSnsService -from org.gluu.oxnotify.client import NotifyClientFactory -from java.util import Arrays, HashMap, IdentityHashMap, Date -from java.time import ZonedDateTime -from java.time.format import DateTimeFormatter - -try: - from org.gluu.oxd.license.client.js import Product - from org.gluu.oxd.license.validator import LicenseValidator - has_license_api = True -except ImportError: - print "Super-Gluu. Load. Failed to load licensing API" - has_license_api = False - -import datetime -import urllib - -import sys -import json - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "Super-Gluu. Initialization" - - if not configurationAttributes.containsKey("authentication_mode"): - print "Super-Gluu. Initialization. Property authentication_mode is mandatory" - return False - - self.applicationId = None - if configurationAttributes.containsKey("application_id"): - self.applicationId = configurationAttributes.get("application_id").getValue2() - - self.registrationUri = None - if configurationAttributes.containsKey("registration_uri"): - self.registrationUri = configurationAttributes.get("registration_uri").getValue2() - - authentication_mode = configurationAttributes.get("authentication_mode").getValue2() - if StringHelper.isEmpty(authentication_mode): - print "Super-Gluu. Initialization. Failed to determine authentication_mode. authentication_mode configuration parameter is empty" - return False - - self.oneStep = StringHelper.equalsIgnoreCase(authentication_mode, "one_step") - self.twoStep = StringHelper.equalsIgnoreCase(authentication_mode, "two_step") - - if not (self.oneStep or self.twoStep): - print "Super-Gluu. Initialization. Valid authentication_mode values are one_step and two_step" - return False - - self.enabledPushNotifications = self.initPushNotificationService(configurationAttributes) - - self.androidUrl = None - if configurationAttributes.containsKey("supergluu_android_download_url"): - self.androidUrl = configurationAttributes.get("supergluu_android_download_url").getValue2() - - self.IOSUrl = None - if configurationAttributes.containsKey("supergluu_ios_download_url"): - self.IOSUrl = configurationAttributes.get("supergluu_ios_download_url").getValue2() - - self.customLabel = None - if configurationAttributes.containsKey("label"): - self.customLabel = configurationAttributes.get("label").getValue2() - - self.customQrOptions = {} - if configurationAttributes.containsKey("qr_options"): - self.customQrOptions = configurationAttributes.get("qr_options").getValue2() - - self.use_super_gluu_group = False - if configurationAttributes.containsKey("super_gluu_group"): - self.super_gluu_group = configurationAttributes.get("super_gluu_group").getValue2() - self.use_super_gluu_group = True - print "Super-Gluu. Initialization. Using super_gluu only if user belong to group: %s" % self.super_gluu_group - - self.use_audit_group = False - if configurationAttributes.containsKey("audit_group"): - self.audit_group = configurationAttributes.get("audit_group").getValue2() - - if (not configurationAttributes.containsKey("audit_group_email")): - print "Super-Gluu. Initialization. Property audit_group_email is not specified" - return False - - self.audit_email = configurationAttributes.get("audit_group_email").getValue2() - self.use_audit_group = True - - print "Super-Gluu. Initialization. Using audit group: %s" % self.audit_group - - if self.use_super_gluu_group or self.use_audit_group: - if not configurationAttributes.containsKey("audit_attribute"): - print "Super-Gluu. Initialization. Property audit_attribute is not specified" - return False - else: - self.audit_attribute = configurationAttributes.get("audit_attribute").getValue2() - - self.valid_license = False - # Removing or altering this block validation is against the terms of the license. - if has_license_api and configurationAttributes.containsKey("license_file"): - license_file = configurationAttributes.get("license_file").getValue2() - - # Load license from file - f = open(license_file, 'r') - try: - license = json.loads(f.read()) - except: - print "Super-Gluu. Initialization. Failed to load license from file: %s" % license_file - return False - finally: - f.close() - - # Validate license - try: - self.license_content = LicenseValidator.validate(license["public_key"], license["public_password"], license["license_password"], license["license"], - Product.SUPER_GLUU, Date()) - self.valid_license = self.license_content.isValid() - except: - print "Super-Gluu. Initialization. Failed to validate license. Exception: ", sys.exc_info()[1] - return False - - print "Super-Gluu. Initialization. License status: '%s'. License metadata: '%s'" % (self.valid_license, self.license_content.getMetadata()) - - print "Super-Gluu. Initialized successfully. oneStep: '%s', twoStep: '%s', pushNotifications: '%s', customLabel: '%s'" % (self.oneStep, self.twoStep, self.enabledPushNotifications, self.customLabel) - - return True - - def destroy(self, configurationAttributes): - print "Super-Gluu. Destroy" - - self.pushAndroidService = None - self.pushAppleService = None - - print "Super-Gluu. Destroyed successfully" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - authenticationService = CdiUtil.bean(AuthenticationService) - - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - - session_attributes = identity.getSessionId().getSessionAttributes() - - client_redirect_uri = self.getApplicationUri(session_attributes) - if client_redirect_uri == None: - print "Super-Gluu. Authenticate. redirect_uri is not set" - return False - - self.setRequestScopedParameters(identity, step) - - # Validate form result code and initialize QR code regeneration if needed (retry_current_step = True) - identity.setWorkingParameter("retry_current_step", False) - form_auth_result = ServerUtil.getFirstValue(requestParameters, "auth_result") - if StringHelper.isNotEmpty(form_auth_result): - print "Super-Gluu. Authenticate for step %s. Get auth_result: '%s'" % (step, form_auth_result) - if form_auth_result in ['error']: - return False - - if form_auth_result in ['timeout']: - if ((step == 1) and self.oneStep) or ((step == 2) and self.twoStep): - print "Super-Gluu. Authenticate for step %s. Reinitializing current step" % step - identity.setWorkingParameter("retry_current_step", True) - return False - - userService = CdiUtil.bean(UserService) - deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService) - if step == 1: - print "Super-Gluu. Authenticate for step 1" - - user_name = credentials.getUsername() - if self.oneStep: - session_device_status = self.getSessionDeviceStatus(session_attributes, user_name) - if session_device_status == None: - return False - - u2f_device_id = session_device_status['device_id'] - - validation_result = self.validateSessionDeviceStatus(client_redirect_uri, session_device_status) - if validation_result: - print "Super-Gluu. Authenticate for step 1. User successfully authenticated with u2f_device '%s'" % u2f_device_id - else: - return False - - if not session_device_status['one_step']: - print "Super-Gluu. Authenticate for step 1. u2f_device '%s' is not one step device" % u2f_device_id - return False - - # There are two steps only in enrollment mode - if session_device_status['enroll']: - return validation_result - - identity.setWorkingParameter("super_gluu_count_login_steps", 1) - - user_inum = session_device_status['user_inum'] - - u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id, "oxId") - if u2f_device == None: - print "Super-Gluu. Authenticate for step 1. Failed to load u2f_device '%s'" % u2f_device_id - return False - - logged_in = authenticationService.authenticate(user_name) - if not logged_in: - print "Super-Gluu. Authenticate for step 1. Failed to authenticate user '%s'" % user_name - return False - - print "Super-Gluu. Authenticate for step 1. User '%s' successfully authenticated with u2f_device '%s'" % (user_name, u2f_device_id) - - return True - elif self.twoStep: - authenticated_user = self.processBasicAuthentication(credentials) - if authenticated_user == None: - return False - - if (self.use_super_gluu_group): - print "Super-Gluu. Authenticate for step 1. Checking if user belong to super_gluu group" - is_member_super_gluu_group = self.isUserMemberOfGroup(authenticated_user, self.audit_attribute, self.super_gluu_group) - if (is_member_super_gluu_group): - print "Super-Gluu. Authenticate for step 1. User '%s' member of super_gluu group" % authenticated_user.getUserId() - super_gluu_count_login_steps = 2 - else: - if self.use_audit_group: - self.processAuditGroup(authenticated_user, self.audit_attribute, self.audit_group) - super_gluu_count_login_steps = 1 - - identity.setWorkingParameter("super_gluu_count_login_steps", super_gluu_count_login_steps) - - if super_gluu_count_login_steps == 1: - return True - - auth_method = 'authenticate' - enrollment_mode = ServerUtil.getFirstValue(requestParameters, "loginForm:registerButton") - if StringHelper.isNotEmpty(enrollment_mode): - auth_method = 'enroll' - - if auth_method == 'authenticate': - user_inum = userService.getUserInum(authenticated_user) - u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, "oxId") - if u2f_devices_list.size() == 0: - auth_method = 'enroll' - print "Super-Gluu. Authenticate for step 1. There is no U2F '%s' user devices associated with application '%s'. Changing auth_method to '%s'" % (user_name, client_redirect_uri, auth_method) - - print "Super-Gluu. Authenticate for step 1. auth_method: '%s'" % auth_method - - identity.setWorkingParameter("super_gluu_auth_method", auth_method) - - return True - - return False - elif step == 2: - print "Super-Gluu. Authenticate for step 2" - - user = authenticationService.getAuthenticatedUser() - if (user == None): - print "Super-Gluu. Authenticate for step 2. Failed to determine user name" - return False - user_name = user.getUserId() - - session_attributes = identity.getSessionId().getSessionAttributes() - - session_device_status = self.getSessionDeviceStatus(session_attributes, user_name) - if session_device_status == None: - return False - - u2f_device_id = session_device_status['device_id'] - - # There are two steps only in enrollment mode - if self.oneStep and session_device_status['enroll']: - authenticated_user = self.processBasicAuthentication(credentials) - if authenticated_user == None: - return False - - user_inum = userService.getUserInum(authenticated_user) - - attach_result = deviceRegistrationService.attachUserDeviceRegistration(user_inum, u2f_device_id) - - print "Super-Gluu. Authenticate for step 2. Result after attaching u2f_device '%s' to user '%s': '%s'" % (u2f_device_id, user_name, attach_result) - - return attach_result - elif self.twoStep: - if user_name == None: - print "Super-Gluu. Authenticate for step 2. Failed to determine user name" - return False - - validation_result = self.validateSessionDeviceStatus(client_redirect_uri, session_device_status, user_name) - if validation_result: - print "Super-Gluu. Authenticate for step 2. User '%s' successfully authenticated with u2f_device '%s'" % (user_name, u2f_device_id) - else: - return False - - super_gluu_request = json.loads(session_device_status['super_gluu_request']) - auth_method = super_gluu_request['method'] - if auth_method in ['enroll', 'authenticate']: - if validation_result and self.use_audit_group: - user = authenticationService.getAuthenticatedUser() - self.processAuditGroup(user, self.audit_attribute, self.audit_group) - - return validation_result - - print "Super-Gluu. Authenticate for step 2. U2F auth_method is invalid" - - return False - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - identity = CdiUtil.bean(Identity) - session_attributes = identity.getSessionId().getSessionAttributes() - - client_redirect_uri = self.getApplicationUri(session_attributes) - if client_redirect_uri == None: - print "Super-Gluu. Prepare for step. redirect_uri is not set" - return False - - self.setRequestScopedParameters(identity, step) - - if step == 1: - print "Super-Gluu. Prepare for step 1" - if self.oneStep: - session = CdiUtil.bean(SessionIdService).getSessionId() - if session == None: - print "Super-Gluu. Prepare for step 2. Failed to determine session_id" - return False - - issuer = CdiUtil.bean(ConfigurationFactory).getConfiguration().getIssuer() - super_gluu_request_dictionary = {'app': client_redirect_uri, - 'issuer': issuer, - 'state': session.getId(), - 'licensed': self.valid_license, - 'created': DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().withNano(0))} - - self.addGeolocationData(session_attributes, super_gluu_request_dictionary) - - super_gluu_request = json.dumps(super_gluu_request_dictionary, separators=(',',':')) - print "Super-Gluu. Prepare for step 1. Prepared super_gluu_request:", super_gluu_request - - identity.setWorkingParameter("super_gluu_request", super_gluu_request) - elif self.twoStep: - identity.setWorkingParameter("display_register_action", True) - - return True - elif step == 2: - print "Super-Gluu. Prepare for step 2" - if self.oneStep: - return True - - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - if user == None: - print "Super-Gluu. Prepare for step 2. Failed to determine user name" - return False - - if session_attributes.containsKey("super_gluu_request"): - super_gluu_request = session_attributes.get("super_gluu_request") - if not StringHelper.equalsIgnoreCase(super_gluu_request, "timeout"): - print "Super-Gluu. Prepare for step 2. Request was generated already" - return True - - session = CdiUtil.bean(SessionIdService).getSessionId() - if session == None: - print "Super-Gluu. Prepare for step 2. Failed to determine session_id" - return False - - auth_method = session_attributes.get("super_gluu_auth_method") - if StringHelper.isEmpty(auth_method): - print "Super-Gluu. Prepare for step 2. Failed to determine auth_method" - return False - - print "Super-Gluu. Prepare for step 2. auth_method: '%s'" % auth_method - - issuer = CdiUtil.bean(ConfigurationFactory).getAppConfiguration().getIssuer() - super_gluu_request_dictionary = {'username': user.getUserId(), - 'app': client_redirect_uri, - 'issuer': issuer, - 'method': auth_method, - 'state': session.getId(), - 'licensed': self.valid_license, - 'created': DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().withNano(0))} - - self.addGeolocationData(session_attributes, super_gluu_request_dictionary) - - super_gluu_request = json.dumps(super_gluu_request_dictionary, separators=(',',':')) - print "Super-Gluu. Prepare for step 2. Prepared super_gluu_request:", super_gluu_request - - identity.setWorkingParameter("super_gluu_request", super_gluu_request) - identity.setWorkingParameter("super_gluu_auth_method", auth_method) - - if auth_method in ['authenticate']: - self.sendPushNotification(client_redirect_uri, user, super_gluu_request) - - return True - else: - return False - - def getNextStep(self, configurationAttributes, requestParameters, step): - # If user not pass current step change step to previous - identity = CdiUtil.bean(Identity) - retry_current_step = identity.getWorkingParameter("retry_current_step") - if retry_current_step: - print "Super-Gluu. Get next step. Retrying current step" - - # Remove old QR code - identity.setWorkingParameter("super_gluu_request", "timeout") - - resultStep = step - return resultStep - - return -1 - - def getExtraParametersForStep(self, configurationAttributes, step): - if step == 1: - if self.oneStep: - return Arrays.asList("super_gluu_request") - elif self.twoStep: - return Arrays.asList("display_register_action") - elif step == 2: - return Arrays.asList("super_gluu_auth_method", "super_gluu_request") - - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - identity = CdiUtil.bean(Identity) - if identity.isSetWorkingParameter("super_gluu_count_login_steps"): - return identity.getWorkingParameter("super_gluu_count_login_steps") - else: - return 2 - - def getPageForStep(self, configurationAttributes, step): - if step == 1: - if self.oneStep: - return "/auth/super-gluu/login.xhtml" - elif step == 2: - if self.oneStep: - return "/login.xhtml" - else: - identity = CdiUtil.bean(Identity) - authmethod = identity.getWorkingParameter("super_gluu_auth_method") - print "Super-Gluu. authmethod '%s'" % authmethod - if authmethod == "enroll": - return "/auth/super-gluu/login.xhtml" - else: - return "/auth/super-gluu/login.xhtml" - - return "" - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True - - def processBasicAuthentication(self, credentials): - authenticationService = CdiUtil.bean(AuthenticationService) - - user_name = credentials.getUsername() - user_password = credentials.getPassword() - - logged_in = False - if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password): - logged_in = authenticationService.authenticate(user_name, user_password) - - if not logged_in: - return None - - find_user_by_uid = authenticationService.getAuthenticatedUser() - if find_user_by_uid == None: - print "Super-Gluu. Process basic authentication. Failed to find user '%s'" % user_name - return None - - return find_user_by_uid - - def validateSessionDeviceStatus(self, client_redirect_uri, session_device_status, user_name = None): - userService = CdiUtil.bean(UserService) - deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService) - - u2f_device_id = session_device_status['device_id'] - - u2f_device = None - if session_device_status['enroll'] and session_device_status['one_step']: - u2f_device = deviceRegistrationService.findOneStepUserDeviceRegistration(u2f_device_id) - if u2f_device == None: - print "Super-Gluu. Validate session device status. There is no one step u2f_device '%s'" % u2f_device_id - return False - else: - # Validate if user has specified device_id enrollment - user_inum = userService.getUserInum(user_name) - - if session_device_status['one_step']: - user_inum = session_device_status['user_inum'] - - u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id) - if u2f_device == None: - print "Super-Gluu. Validate session device status. There is no u2f_device '%s' associated with user '%s'" % (u2f_device_id, user_inum) - return False - - if not StringHelper.equalsIgnoreCase(client_redirect_uri, u2f_device.application): - print "Super-Gluu. Validate session device status. u2f_device '%s' associated with other application '%s'" % (u2f_device_id, u2f_device.application) - return False - - return True - - def getSessionDeviceStatus(self, session_attributes, user_name): - print "Super-Gluu. Get session device status" - - if not session_attributes.containsKey("super_gluu_request"): - print "Super-Gluu. Get session device status. There is no Super-Gluu request in session attributes" - return None - - # Check session state extended - if not session_attributes.containsKey("session_custom_state"): - print "Super-Gluu. Get session device status. There is no session_custom_state in session attributes" - return None - - session_custom_state = session_attributes.get("session_custom_state") - if not StringHelper.equalsIgnoreCase("approved", session_custom_state): - print "Super-Gluu. Get session device status. User '%s' not approve or not pass U2F authentication. session_custom_state: '%s'" % (user_name, session_custom_state) - return None - - # Try to find device_id in session attribute - if not session_attributes.containsKey("oxpush2_u2f_device_id"): - print "Super-Gluu. Get session device status. There is no u2f_device associated with this request" - return None - - # Try to find user_inum in session attribute - if not session_attributes.containsKey("oxpush2_u2f_device_user_inum"): - print "Super-Gluu. Get session device status. There is no user_inum associated with this request" - return None - - enroll = False - if session_attributes.containsKey("oxpush2_u2f_device_enroll"): - enroll = StringHelper.equalsIgnoreCase("true", session_attributes.get("oxpush2_u2f_device_enroll")) - - one_step = False - if session_attributes.containsKey("oxpush2_u2f_device_one_step"): - one_step = StringHelper.equalsIgnoreCase("true", session_attributes.get("oxpush2_u2f_device_one_step")) - - super_gluu_request = session_attributes.get("super_gluu_request") - u2f_device_id = session_attributes.get("oxpush2_u2f_device_id") - user_inum = session_attributes.get("oxpush2_u2f_device_user_inum") - - session_device_status = {"super_gluu_request": super_gluu_request, "device_id": u2f_device_id, "user_inum" : user_inum, "enroll" : enroll, "one_step" : one_step} - print "Super-Gluu. Get session device status. session_device_status: '%s'" % (session_device_status) - - return session_device_status - - def initPushNotificationService(self, configurationAttributes): - print "Super-Gluu. Initialize Native/SNS/Gluu notification services" - - self.pushSnsMode = False - self.pushGluuMode = False - if configurationAttributes.containsKey("notification_service_mode"): - notificationServiceMode = configurationAttributes.get("notification_service_mode").getValue2() - if StringHelper.equalsIgnoreCase(notificationServiceMode, "sns"): - return self.initSnsPushNotificationService(configurationAttributes) - elif StringHelper.equalsIgnoreCase(notificationServiceMode, "gluu"): - return self.initGluuPushNotificationService(configurationAttributes) - - return self.initNativePushNotificationService(configurationAttributes) - - def initNativePushNotificationService(self, configurationAttributes): - print "Super-Gluu. Initialize native notification services" - - creds = self.loadPushNotificationCreds(configurationAttributes) - if creds == None: - return False - - try: - android_creds = creds["android"]["gcm"] - ios_creds = creds["ios"]["apns"] - except: - print "Super-Gluu. Initialize native notification services. Invalid credentials file format" - return False - - self.pushAndroidService = None - self.pushAppleService = None - if android_creds["enabled"]: - self.pushAndroidService = Sender(android_creds["api_key"]) - print "Super-Gluu. Initialize native notification services. Created Android notification service" - - if ios_creds["enabled"]: - p12_file_path = ios_creds["p12_file_path"] - p12_password = ios_creds["p12_password"] - - try: - encryptionService = CdiUtil.bean(EncryptionService) - p12_password = encryptionService.decrypt(p12_password) - except: - # Ignore exception. Password is not encrypted - print "Super-Gluu. Initialize native notification services. Assuming that 'p12_password' password in not encrypted" - - apnsServiceBuilder = APNS.newService().withCert(p12_file_path, p12_password) - if ios_creds["production"]: - self.pushAppleService = apnsServiceBuilder.withProductionDestination().build() - else: - self.pushAppleService = apnsServiceBuilder.withSandboxDestination().build() - - self.pushAppleServiceProduction = ios_creds["production"] - - print "Super-Gluu. Initialize native notification services. Created iOS notification service" - - enabled = self.pushAndroidService != None or self.pushAppleService != None - - return enabled - - def initSnsPushNotificationService(self, configurationAttributes): - print "Super-Gluu. Initialize SNS notification services" - self.pushSnsMode = True - - creds = self.loadPushNotificationCreds(configurationAttributes) - if creds == None: - return False - - try: - sns_creds = creds["sns"] - android_creds = creds["android"]["sns"] - ios_creds = creds["ios"]["sns"] - except: - print "Super-Gluu. Initialize SNS notification services. Invalid credentials file format" - return False - - self.pushAndroidService = None - self.pushAppleService = None - if not (android_creds["enabled"] or ios_creds["enabled"]): - print "Super-Gluu. Initialize SNS notification services. SNS disabled for all platforms" - return False - - sns_access_key = sns_creds["access_key"] - sns_secret_access_key = sns_creds["secret_access_key"] - sns_region = sns_creds["region"] - - encryptionService = CdiUtil.bean(EncryptionService) - - try: - sns_secret_access_key = encryptionService.decrypt(sns_secret_access_key) - except: - # Ignore exception. Password is not encrypted - print "Super-Gluu. Initialize SNS notification services. Assuming that 'sns_secret_access_key' in not encrypted" - - pushSnsService = CdiUtil.bean(PushSnsService) - pushClient = pushSnsService.createSnsClient(sns_access_key, sns_secret_access_key, sns_region) - - if android_creds["enabled"]: - self.pushAndroidService = pushClient - self.pushAndroidPlatformArn = android_creds["platform_arn"] - print "Super-Gluu. Initialize SNS notification services. Created Android notification service" - - if ios_creds["enabled"]: - self.pushAppleService = pushClient - self.pushApplePlatformArn = ios_creds["platform_arn"] - self.pushAppleServiceProduction = ios_creds["production"] - print "Super-Gluu. Initialize SNS notification services. Created iOS notification service" - - enabled = self.pushAndroidService != None or self.pushAppleService != None - - return enabled - - def initGluuPushNotificationService(self, configurationAttributes): - print "Super-Gluu. Initialize Gluu notification services" - - self.pushGluuMode = True - - creds = self.loadPushNotificationCreds(configurationAttributes) - if creds == None: - return False - - try: - gluu_conf = creds["gluu"] - android_creds = creds["android"]["gluu"] - ios_creds = creds["ios"]["gluu"] - except: - print "Super-Gluu. Initialize Gluu notification services. Invalid credentials file format" - return False - - self.pushAndroidService = None - self.pushAppleService = None - if not (android_creds["enabled"] or ios_creds["enabled"]): - print "Super-Gluu. Initialize Gluu notification services. Gluu disabled for all platforms" - return False - - gluu_server_uri = gluu_conf["server_uri"] - notifyClientFactory = NotifyClientFactory.instance() - metadataConfiguration = None - try: - metadataConfiguration = notifyClientFactory.createMetaDataConfigurationService(gluu_server_uri).getMetadataConfiguration() - except: - print "Super-Gluu. Initialize Gluu notification services. Failed to load metadata. Exception: ", sys.exc_info()[1] - return False - - gluuClient = notifyClientFactory.createNotifyService(metadataConfiguration) - encryptionService = CdiUtil.bean(EncryptionService) - - if android_creds["enabled"]: - gluu_access_key = android_creds["access_key"] - gluu_secret_access_key = android_creds["secret_access_key"] - - try: - gluu_secret_access_key = encryptionService.decrypt(gluu_secret_access_key) - except: - # Ignore exception. Password is not encrypted - print "Super-Gluu. Initialize Gluu notification services. Assuming that 'gluu_secret_access_key' in not encrypted" - - self.pushAndroidService = gluuClient - self.pushAndroidServiceAuth = notifyClientFactory.getAuthorization(gluu_access_key, gluu_secret_access_key); - print "Super-Gluu. Initialize Gluu notification services. Created Android notification service" - - if ios_creds["enabled"]: - gluu_access_key = ios_creds["access_key"] - gluu_secret_access_key = ios_creds["secret_access_key"] - - try: - gluu_secret_access_key = encryptionService.decrypt(gluu_secret_access_key) - except: - # Ignore exception. Password is not encrypted - print "Super-Gluu. Initialize Gluu notification services. Assuming that 'gluu_secret_access_key' in not encrypted" - - self.pushAppleService = gluuClient - self.pushAppleServiceAuth = notifyClientFactory.getAuthorization(gluu_access_key, gluu_secret_access_key); - print "Super-Gluu. Initialize Gluu notification services. Created iOS notification service" - - enabled = self.pushAndroidService != None or self.pushAppleService != None - - return enabled - - def loadPushNotificationCreds(self, configurationAttributes): - print "Super-Gluu. Initialize notification services" - if not configurationAttributes.containsKey("credentials_file"): - return None - - super_gluu_creds_file = configurationAttributes.get("credentials_file").getValue2() - - # Load credentials from file - f = open(super_gluu_creds_file, 'r') - try: - creds = json.loads(f.read()) - except: - print "Super-Gluu. Initialize notification services. Failed to load credentials from file:", super_gluu_creds_file - return None - finally: - f.close() - - return creds - - def sendPushNotification(self, client_redirect_uri, user, super_gluu_request): - try: - self.sendPushNotificationImpl(client_redirect_uri, user, super_gluu_request) - except: - print "Super-Gluu. Send push notification. Failed to send push notification: ", sys.exc_info()[1] - - def sendPushNotificationImpl(self, client_redirect_uri, user, super_gluu_request): - if not self.enabledPushNotifications: - return - - user_name = user.getUserId() - print "Super-Gluu. Send push notification. Loading user '%s' devices" % user_name - - send_notification = False - send_notification_result = True - - userService = CdiUtil.bean(UserService) - deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService) - - user_inum = userService.getUserInum(user_name) - - send_android = 0 - send_ios = 0 - u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, "oxId", "oxDeviceData", "oxDeviceNotificationConf") - if u2f_devices_list.size() > 0: - for u2f_device in u2f_devices_list: - device_data = u2f_device.getDeviceData() - - # Device data which Super-Gluu gets during enrollment - if device_data == None: - continue - - platform = device_data.getPlatform() - push_token = device_data.getPushToken() - debug = False - - if StringHelper.equalsIgnoreCase(platform, "ios") and StringHelper.isNotEmpty(push_token): - # Sending notification to iOS user's device - if self.pushAppleService == None: - print "Super-Gluu. Send push notification. Apple native push notification service is not enabled" - else: - send_notification = True - - title = "Super Gluu" - message = "Confirm your sign in request to: %s" % client_redirect_uri - - if self.pushSnsMode or self.pushGluuMode: - pushSnsService = CdiUtil.bean(PushSnsService) - targetEndpointArn = self.getTargetEndpointArn(deviceRegistrationService, pushSnsService, PushPlatform.APNS, user, u2f_device) - if targetEndpointArn == None: - return - - send_notification = True - - sns_push_request_dictionary = { "aps": - { "badge": 0, - "alert" : {"body": message, "title" : title}, - "category": "ACTIONABLE", - "content-available": "1", - "sound": 'default' - }, - "request" : super_gluu_request - } - push_message = json.dumps(sns_push_request_dictionary, separators=(',',':')) - - if self.pushSnsMode: - apple_push_platform = PushPlatform.APNS - if not self.pushAppleServiceProduction: - apple_push_platform = PushPlatform.APNS_SANDBOX - - send_notification_result = pushSnsService.sendPushMessage(self.pushAppleService, apple_push_platform, targetEndpointArn, push_message, None) - if debug: - print "Super-Gluu. Send iOS SNS push notification. token: '%s', message: '%s', send_notification_result: '%s', apple_push_platform: '%s'" % (push_token, push_message, send_notification_result, apple_push_platform) - elif self.pushGluuMode: - send_notification_result = self.pushAppleService.sendNotification(self.pushAppleServiceAuth, targetEndpointArn, push_message) - if debug: - print "Super-Gluu. Send iOS Gluu push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) - else: - additional_fields = { "request" : super_gluu_request } - - msgBuilder = APNS.newPayload().alertBody(message).alertTitle(title).sound("default") - msgBuilder.category('ACTIONABLE').badge(0) - msgBuilder.forNewsstand() - msgBuilder.customFields(additional_fields) - push_message = msgBuilder.build() - - send_notification_result = self.pushAppleService.push(push_token, push_message) - if debug: - print "Super-Gluu. Send iOS Native push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) - send_ios = send_ios + 1 - - if StringHelper.equalsIgnoreCase(platform, "android") and StringHelper.isNotEmpty(push_token): - # Sending notification to Android user's device - if self.pushAndroidService == None: - print "Super-Gluu. Send native push notification. Android native push notification service is not enabled" - else: - send_notification = True - - title = "Super-Gluu" - if self.pushSnsMode or self.pushGluuMode: - pushSnsService = CdiUtil.bean(PushSnsService) - targetEndpointArn = self.getTargetEndpointArn(deviceRegistrationService, pushSnsService, PushPlatform.GCM, user, u2f_device) - if targetEndpointArn == None: - return - - send_notification = True - - sns_push_request_dictionary = { "collapse_key": "single", - "content_available": True, - "time_to_live": 60, - "data": - { "message" : super_gluu_request, - "title" : title } - } - push_message = json.dumps(sns_push_request_dictionary, separators=(',',':')) - - if self.pushSnsMode: - send_notification_result = pushSnsService.sendPushMessage(self.pushAndroidService, PushPlatform.GCM, targetEndpointArn, push_message, None) - if debug: - print "Super-Gluu. Send Android SNS push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) - elif self.pushGluuMode: - send_notification_result = self.pushAndroidService.sendNotification(self.pushAndroidServiceAuth, targetEndpointArn, push_message) - if debug: - print "Super-Gluu. Send Android Gluu push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) - else: - msgBuilder = Message.Builder().addData("message", super_gluu_request).addData("title", title).collapseKey("single").contentAvailable(True) - push_message = msgBuilder.build() - - send_notification_result = self.pushAndroidService.send(push_message, push_token, 3) - if debug: - print "Super-Gluu. Send Android Native push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) - send_android = send_android + 1 - - print "Super-Gluu. Send push notification. send_android: '%s', send_ios: '%s'" % (send_android, send_ios) - - def getTargetEndpointArn(self, deviceRegistrationService, pushSnsService, platform, user, u2fDevice): - targetEndpointArn = None - - # Return endpoint ARN if it created already - notificationConf = u2fDevice.getDeviceNotificationConf() - if StringHelper.isNotEmpty(notificationConf): - notificationConfJson = json.loads(notificationConf) - targetEndpointArn = notificationConfJson['sns_endpoint_arn'] - if StringHelper.isNotEmpty(targetEndpointArn): - print "Super-Gluu. Get target endpoint ARN. There is already created target endpoint ARN" - return targetEndpointArn - - # Create endpoint ARN - pushClient = None - pushClientAuth = None - platformApplicationArn = None - if platform == PushPlatform.GCM: - pushClient = self.pushAndroidService - if self.pushSnsMode: - platformApplicationArn = self.pushAndroidPlatformArn - if self.pushGluuMode: - pushClientAuth = self.pushAndroidServiceAuth - elif platform == PushPlatform.APNS: - pushClient = self.pushAppleService - if self.pushSnsMode: - platformApplicationArn = self.pushApplePlatformArn - if self.pushGluuMode: - pushClientAuth = self.pushAppleServiceAuth - else: - return None - - deviceData = u2fDevice.getDeviceData() - pushToken = deviceData.getPushToken() - - print "Super-Gluu. Get target endpoint ARN. Attempting to create target endpoint ARN for user: '%s'" % user.getUserId() - if self.pushSnsMode: - targetEndpointArn = pushSnsService.createPlatformArn(pushClient, platformApplicationArn, pushToken, user) - else: - customUserData = pushSnsService.getCustomUserData(user) - registerDeviceResponse = pushClient.registerDevice(pushClientAuth, pushToken, customUserData); - if registerDeviceResponse != None and registerDeviceResponse.getStatusCode() == 200: - targetEndpointArn = registerDeviceResponse.getEndpointArn() - - if StringHelper.isEmpty(targetEndpointArn): - print "Super-Gluu. Failed to get endpoint ARN for user: '%s'" % user.getUserId() - return None - - print "Super-Gluu. Get target endpoint ARN. Create target endpoint ARN '%s' for user: '%s'" % (targetEndpointArn, user.getUserId()) - - # Store created endpoint ARN in device entry - userInum = user.getAttribute("inum") - u2fDeviceUpdate = deviceRegistrationService.findUserDeviceRegistration(userInum, u2fDevice.getId()) - u2fDeviceUpdate.setDeviceNotificationConf('{"sns_endpoint_arn" : "%s"}' % targetEndpointArn) - deviceRegistrationService.updateDeviceRegistration(userInum, u2fDeviceUpdate) - - return targetEndpointArn - - def getApplicationUri(self, session_attributes): - if self.applicationId != None: - return self.applicationId - - if not session_attributes.containsKey("redirect_uri"): - return None - - return session_attributes.get("redirect_uri") - - def setRequestScopedParameters(self, identity, step): - downloadMap = HashMap() - if self.registrationUri != None: - identity.setWorkingParameter("external_registration_uri", self.registrationUri) - - if self.androidUrl!= None and step == 1: - downloadMap.put("android", self.androidUrl) - - if self.IOSUrl != None and step == 1: - downloadMap.put("ios", self.IOSUrl) - - if self.customLabel != None: - identity.setWorkingParameter("super_gluu_label", self.customLabel) - - identity.setWorkingParameter("download_url", downloadMap) - identity.setWorkingParameter("super_gluu_qr_options", self.customQrOptions) - - def addGeolocationData(self, session_attributes, super_gluu_request_dictionary): - if session_attributes.containsKey("remote_ip"): - remote_ip = session_attributes.get("remote_ip") - if StringHelper.isNotEmpty(remote_ip): - print "Super-Gluu. Prepare for step 2. Adding req_ip and req_loc to super_gluu_request" - super_gluu_request_dictionary['req_ip'] = remote_ip - - remote_loc_dic = self.determineGeolocationData(remote_ip) - if remote_loc_dic == None: - print "Super-Gluu. Prepare for step 2. Failed to determine remote location by remote IP '%s'" % remote_ip - return - - remote_loc = "%s, %s, %s" % ( remote_loc_dic['country'], remote_loc_dic['regionName'], remote_loc_dic['city'] ) - remote_loc_encoded = urllib.quote(remote_loc.encode('utf-8')) - super_gluu_request_dictionary['req_loc'] = remote_loc_encoded - - def determineGeolocationData(self, remote_ip): - print "Super-Gluu. Determine remote location. remote_ip: '%s'" % remote_ip - httpService = CdiUtil.bean(HttpService) - - http_client = httpService.getHttpsClient() - http_client_params = http_client.getParams() - http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000) - - geolocation_service_url = "http://ip-api.com/json/%s?fields=49177" % remote_ip - geolocation_service_headers = { "Accept" : "application/json" } - - try: - http_service_response = httpService.executeGet(http_client, geolocation_service_url, geolocation_service_headers) - http_response = http_service_response.getHttpResponse() - except: - print "Super-Gluu. Determine remote location. Exception: ", sys.exc_info()[1] - return None - - try: - if not httpService.isResponseStastusCodeOk(http_response): - print "Super-Gluu. Determine remote location. Get invalid response from validation server: ", str(http_response.getStatusLine().getStatusCode()) - httpService.consume(http_response) - return None - - response_bytes = httpService.getResponseContent(http_response) - response_string = httpService.convertEntityToString(response_bytes) - httpService.consume(http_response) - finally: - http_service_response.closeConnection() - - if response_string == None: - print "Super-Gluu. Determine remote location. Get empty response from location server" - return None - - response = json.loads(response_string) - - if not StringHelper.equalsIgnoreCase(response['status'], "success"): - print "Super-Gluu. Determine remote location. Get response with status: '%s'" % response['status'] - return None - - return response - - def isUserMemberOfGroup(self, user, attribute, group): - is_member = False - member_of_list = user.getAttributeValues(attribute) - if (member_of_list != None): - for member_of in member_of_list: - if StringHelper.equalsIgnoreCase(group, member_of) or member_of.endswith(group): - is_member = True - break - - return is_member - - def processAuditGroup(self, user, attribute, group): - is_member = self.isUserMemberOfGroup(user, attribute, group) - if (is_member): - print "Super-Gluu. Authenticate for processAuditGroup. User '%s' member of audit group" % user.getUserId() - print "Super-Gluu. Authenticate for processAuditGroup. Sending e-mail about user '%s' login to %s" % (user.getUserId(), self.audit_email) - - # Send e-mail to administrator - user_id = user.getUserId() - mailService = CdiUtil.bean(MailService) - subject = "User log in: %s" % user_id - body = "User log in: %s" % user_id - mailService.sendMail(self.audit_email, subject, body) diff --git a/jans-auth-server/server/integrations/twilio_sms/twilio2FA.py b/jans-auth-server/server/integrations/twilio_sms/twilio2FA.py deleted file mode 100644 index e47ad811753..00000000000 --- a/jans-auth-server/server/integrations/twilio_sms/twilio2FA.py +++ /dev/null @@ -1,251 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Jose Gonzalez -# Author: Gasmyr Mougang - -from io.jans.service.cdi.util import CdiUtil -from io.jans.as.server.security import Identity -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.server.service import AuthenticationService -from io.jans.as.server.service.common import UserService -from io.jans.as.server.service import SessionIdService -from io.jans.as.server.util import ServerUtil -from io.jans.util import StringHelper, ArrayHelper -from java.util import Arrays -from javax.faces.application import FacesMessage -from io.jans.jsf2.message import FacesMessages - -import com.twilio.Twilio as Twilio -import com.twilio.rest.api.v2010.account.Message as Message -import com.twilio.type.PhoneNumber as PhoneNumber -import org.codehaus.jettison.json.JSONArray as JSONArray - - -import java -import random -import jarray - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - self.mobile_number = None - self.identity = CdiUtil.bean(Identity) - - def init(self, customScript, configurationAttributes): - print "==============================================" - print "===TWILIO SMS INITIALIZATION==================" - print "==============================================" - self.ACCOUNT_SID = None - self.AUTH_TOKEN = None - self.FROM_NUMBER = None - - # Get Custom Properties - try: - self.ACCOUNT_SID = configurationAttributes.get("twilio_sid").getValue2() - except: - print 'TwilioSMS, Missing required configuration attribute "twilio_sid"' - - try: - self.AUTH_TOKEN = configurationAttributes.get("twilio_token").getValue2() - except: - print'TwilioSMS, Missing required configuration attribute "twilio_token"' - try: - self.FROM_NUMBER = configurationAttributes.get("from_number").getValue2() - except: - print'TwilioSMS, Missing required configuration attribute "from_number"' - - if None in (self.ACCOUNT_SID, self.AUTH_TOKEN, self.FROM_NUMBER): - print "twilio_sid, twilio_token, from_number is empty ... returning False" - return False - - print "===TWILIO SMS INITIALIZATION DONE PROPERLY=====" - return True - - def destroy(self, configurationAttributes): - print "Twilio SMS. Destroy" - print "Twilio SMS. Destroyed successfully" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - print "==============================================" - print "====TWILIO SMS AUTHENCATION===================" - print "==============================================" - userService = CdiUtil.bean(UserService) - authenticationService = CdiUtil.bean(AuthenticationService) - sessionIdService = CdiUtil.bean(SessionIdService) - facesMessages = CdiUtil.bean(FacesMessages) - facesMessages.setKeepMessages() - - session_attributes = self.identity.getSessionId().getSessionAttributes() - form_passcode = ServerUtil.getFirstValue(requestParameters, "passcode") - form_name = ServerUtil.getFirstValue(requestParameters, "TwilioSmsloginForm") - - print "TwilioSMS. form_response_passcode: %s" % str(form_passcode) - - if step == 1: - print "==============================================" - print "=TWILIO SMS STEP 1 | Password Authentication==" - print "==============================================" - credentials = self.identity.getCredentials() - user_name = credentials.getUsername() - user_password = credentials.getPassword() - logged_in = False - if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password): - logged_in = authenticationService.authenticate(user_name, user_password) - - if not logged_in: - return False - - # Get the Person's number and generate a code - foundUser = None - try: - foundUser = authenticationService.getAuthenticatedUser() - except: - print 'TwilioSMS, Error retrieving user %s from LDAP' % (user_name) - return False - - try: - isVerified = foundUser.getAttribute("phoneNumberVerified") - if isVerified: - self.mobile_number = foundUser.getAttribute("employeeNumber") - if self.mobile_number == None: - self.mobile_number = foundUser.getAttribute("mobile") - if self.mobile_number == None: - self.mobile_number = foundUser.getAttribute("telephoneNumber") - if self.mobile_number == None: - print "TwilioSMS, Error finding mobile number for user '%s'" % user_name - - except: - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to determine mobile phone number") - print 'TwilioSMS, Error finding mobile number for "%s". Exception: %s` % (user_name, sys.exc_info()[1])`' - return False - - # Generate Random six digit code and store it in array - code = random.randint(100000, 999999) - - # Get code and save it in LDAP temporarily with special session entry - self.identity.setWorkingParameter("code", code) - sessionId = sessionIdService.getSessionId() # fetch from persistence - sessionId.getSessionAttributes().put("code", code) - - try: - Twilio.init(self.ACCOUNT_SID, self.AUTH_TOKEN); - message = Message.creator(PhoneNumber(self.mobile_number), PhoneNumber(self.FROM_NUMBER), str(code)).create(); - print "++++++++++++++++++++++++++++++++++++++++++++++" - print 'TwilioSMs, Message Sid: %s' % (message.getSid()) - print 'TwilioSMs, User phone: %s' % (self.mobile_number) - print "++++++++++++++++++++++++++++++++++++++++++++++" - sessionId.getSessionAttributes().put("mobile_number", self.mobile_number) - sessionId.getSessionAttributes().put("mobile", self.mobile_number) - sessionIdService.updateSessionId(sessionId) - self.identity.setWorkingParameter("mobile_number", self.mobile_number) - self.identity.getSessionId().getSessionAttributes().put("mobile_number",self.mobile_number) - self.identity.setWorkingParameter("mobile", self.mobile_number) - self.identity.getSessionId().getSessionAttributes().put("mobile",self.mobile_number) - print "++++++++++++++++++++++++++++++++++++++++++++++" - print "Number: %s" % (self.identity.getWorkingParameter("mobile_number")) - print "Mobile: %s" % (self.identity.getWorkingParameter("mobile")) - print "++++++++++++++++++++++++++++++++++++++++++++++" - print "========================================" - print "===TWILIO SMS FIRST STEP DONE PROPERLY==" - print "========================================" - return True - except Exception, ex: - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to send message to mobile phone") - print "TwilioSMS. Error sending message to Twilio" - print "TwilioSMS. Unexpected error:", ex - - return False - elif step == 2: - # Retrieve the session attribute - print "==============================================" - print "=TWILIO SMS STEP 2 | Password Authentication==" - print "==============================================" - code = session_attributes.get("code") - print '=======> Session code is "%s"' % str(code) - sessionIdService = CdiUtil.bean(SessionIdService) - sessionId = sessionIdService.getSessionId() # fetch from persistence - code = sessionId.getSessionAttributes().get("code") - print '=======> Database code is "%s"' % str(code) - self.identity.setSessionId(sessionId) - print "==============================================" - print "TwilioSMS. Code: %s" % str(code) - print "==============================================" - if code is None: - print "TwilioSMS. Failed to find previously sent code" - return False - - if form_passcode is None: - print "TwilioSMS. Passcode is empty" - return False - - if len(form_passcode) != 6: - print "TwilioSMS. Passcode from response is not 6 digits: %s" % form_passcode - return False - - if form_passcode == code: - print "TiwlioSMS, SUCCESS! User entered the same code!" - print "========================================" - print "===TWILIO SMS SECOND STEP DONE PROPERLY" - print "========================================" - return True - - print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" - print "TwilioSMS. FAIL! User entered the wrong code! %s != %s" % (form_passcode, code) - print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" - facesMessages.add(FacesMessage.SEVERITY_ERROR, "Incorrect Twilio code, please try again.") - print "================================================" - print "===TWILIO SMS SECOND STEP FAILED: INCORRECT CODE" - print "================================================" - return False - - print "TwilioSMS. ERROR: step param not found or != (1|2)" - - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - if step == 1: - print "TwilioSMS. Prepare for Step 1" - return True - elif step == 2: - print "TwilioSMS. Prepare for Step 2" - return True - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - if step == 2: - return Arrays.asList("code") - - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - return 2 - - def getPageForStep(self, configurationAttributes, step): - if step == 2: - return "/auth/otp_sms/otp_sms.xhtml" - - return "" - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True diff --git a/jans-auth-server/server/integrations/u2f/U2fExternalAuthenticator.py b/jans-auth-server/server/integrations/u2f/U2fExternalAuthenticator.py deleted file mode 100644 index ec86a68f97e..00000000000 --- a/jans-auth-server/server/integrations/u2f/U2fExternalAuthenticator.py +++ /dev/null @@ -1,214 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan -# - -import java -import sys -from javax.ws.rs.core import Response -from javax.ws.rs import WebApplicationException -from org.jboss.resteasy.client.exception import ResteasyClientException -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from org.gluu.oxauth.client.fido.u2f import FidoU2fClientFactory -from org.gluu.oxauth.model.config import Constants -from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService, SessionIdService -from io.jans.as.server.service.common import UserService -from io.jans.as.server.service.fido.u2f import DeviceRegistrationService -from io.jans.as.server.util import ServerUtil -from io.jans.service.cdi.util import CdiUtil -from io.jans.util import StringHelper - - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "U2F. Initialization" - - print "U2F. Initialization. Downloading U2F metadata" - u2f_server_uri = configurationAttributes.get("u2f_server_uri").getValue2() - u2f_server_metadata_uri = u2f_server_uri + "/.well-known/fido-u2f-configuration" - - metaDataConfigurationService = FidoU2fClientFactory.instance().createMetaDataConfigurationService(u2f_server_metadata_uri) - - max_attempts = 20 - for attempt in range(1, max_attempts + 1): - try: - self.metaDataConfiguration = metaDataConfigurationService.getMetadataConfiguration() - break - except WebApplicationException, ex: - # Detect if last try or we still get Service Unavailable HTTP error - if (attempt == max_attempts) or (ex.getResponse().getStatus() != Response.Status.SERVICE_UNAVAILABLE.getStatusCode()): - raise ex - - java.lang.Thread.sleep(3000) - print "Attempting to load metadata: %d" % attempt - - print "U2F. Initialized successfully" - return True - - def destroy(self, configurationAttributes): - print "U2F. Destroy" - print "U2F. Destroyed successfully" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - authenticationService = CdiUtil.bean(AuthenticationService) - - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - - user_name = credentials.getUsername() - - if (step == 1): - print "U2F. Authenticate for step 1" - - user_password = credentials.getPassword() - logged_in = False - if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): - userService = CdiUtil.bean(UserService) - logged_in = authenticationService.authenticate(user_name, user_password) - - if (not logged_in): - return False - - return True - elif (step == 2): - print "U2F. Authenticate for step 2" - - token_response = ServerUtil.getFirstValue(requestParameters, "tokenResponse") - if token_response == None: - print "U2F. Authenticate for step 2. tokenResponse is empty" - return False - - auth_method = ServerUtil.getFirstValue(requestParameters, "authMethod") - if auth_method == None: - print "U2F. Authenticate for step 2. authMethod is empty" - return False - - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - if (user == None): - print "U2F. Prepare for step 2. Failed to determine user name" - return False - - if (auth_method == 'authenticate'): - print "U2F. Prepare for step 2. Call FIDO U2F in order to finish authentication workflow" - authenticationRequestService = FidoU2fClientFactory.instance().createAuthenticationRequestService(self.metaDataConfiguration) - authenticationStatus = authenticationRequestService.finishAuthentication(user.getUserId(), token_response) - - if (authenticationStatus.getStatus() != Constants.RESULT_SUCCESS): - print "U2F. Authenticate for step 2. Get invalid authentication status from FIDO U2F server" - return False - - return True - elif (auth_method == 'enroll'): - print "U2F. Prepare for step 2. Call FIDO U2F in order to finish registration workflow" - registrationRequestService = FidoU2fClientFactory.instance().createRegistrationRequestService(self.metaDataConfiguration) - registrationStatus = registrationRequestService.finishRegistration(user.getUserId(), token_response) - - if (registrationStatus.getStatus() != Constants.RESULT_SUCCESS): - print "U2F. Authenticate for step 2. Get invalid registration status from FIDO U2F server" - return False - - return True - else: - print "U2F. Prepare for step 2. Authenticatiod method is invalid" - return False - - return False - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - identity = CdiUtil.bean(Identity) - - if (step == 1): - return True - elif (step == 2): - print "U2F. Prepare for step 2" - - session = CdiUtil.bean(SessionIdService).getSessionId() - if session == None: - print "U2F. Prepare for step 2. Failed to determine session_id" - return False - - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - if (user == None): - print "U2F. Prepare for step 2. Failed to determine user name" - return False - - u2f_application_id = configurationAttributes.get("u2f_application_id").getValue2() - - # Check if user have registered devices - deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService) - - userInum = user.getAttribute("inum") - - registrationRequest = None - authenticationRequest = None - - deviceRegistrations = deviceRegistrationService.findUserDeviceRegistrations(userInum, u2f_application_id) - if (deviceRegistrations.size() > 0): - print "U2F. Prepare for step 2. Call FIDO U2F in order to start authentication workflow" - - try: - authenticationRequestService = FidoU2fClientFactory.instance().createAuthenticationRequestService(self.metaDataConfiguration) - authenticationRequest = authenticationRequestService.startAuthentication(user.getUserId(), None, u2f_application_id, session.getId()) - except ClientResponseFailure, ex: - if (ex.getResponse().getResponseStatus() != Response.Status.NOT_FOUND): - print "U2F. Prepare for step 2. Failed to start authentication workflow. Exception:", sys.exc_info()[1] - return False - else: - print "U2F. Prepare for step 2. Call FIDO U2F in order to start registration workflow" - registrationRequestService = FidoU2fClientFactory.instance().createRegistrationRequestService(self.metaDataConfiguration) - registrationRequest = registrationRequestService.startRegistration(user.getUserId(), u2f_application_id, session.getId()) - - identity.setWorkingParameter("fido_u2f_authentication_request", ServerUtil.asJson(authenticationRequest)) - identity.setWorkingParameter("fido_u2f_registration_request", ServerUtil.asJson(registrationRequest)) - - return True - elif (step == 3): - print "U2F. Prepare for step 3" - - return True - else: - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - return 2 - - def getPageForStep(self, configurationAttributes, step): - if (step == 2): - return "/auth/u2f/login.xhtml" - - return "" - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True diff --git a/jans-auth-server/server/integrations/uaf/Installation.md b/jans-auth-server/server/integrations/uaf/Installation.md deleted file mode 100644 index d2cf46caf16..00000000000 --- a/jans-auth-server/server/integrations/uaf/Installation.md +++ /dev/null @@ -1,48 +0,0 @@ -This list of steps needed to do to enable SAML person authentication module. - -1. Configure apache HTTP proxy to access UAF server: - - Make sure that enabled next apache2 plugins: proxy, proxy_http, ssl - To enable them use next commands: - * a2enmod proxy - * a2enmod proxy_http - * a2enmod ssl - - Add to Apache2 https_gluu.conf file next lines: -``` - SSLProxyEngine on - SSLProxyCheckPeerCN on - SSLProxyCheckPeerExpire on - - - ProxyPass https://evaluation4.noknoktest.com:8443/nnl retry=5 disablereuse=On - ProxyPassReverse https://evaluation4.noknoktest.com:8443/nnl - Order allow,deny - Allow from all - -``` - Proxy between UAF and oxAuth sever is needed because UAF server not supports CORS operations. In this configuration we uses evaluation server. - -2. Confire new custom module in oxTrust: - - Log into oxTrust with administrative permissions. - - Open "Configuration→Manage Custom Scripts" page. - - Select "Person Authentication" tab. - - Click on "Add custom script configuration" link. - - Enter name = uaf - - Enter level = 0-100 (priority of this method). - - Select usage type "Interactive". - - Add custom required and optional properties which specified in "Properties description.md". - - Copy/paste script from UafExternalAuthenticator.py. - - Activate it via "Enabled" checkbox. - - Click "Update" button at the bottom of this page. - -3. Configure oxAuth to use UAF authentication by default: - - Log into oxTrust with administrative permissions. - - Open "Configuration→Manage Authentication" page. - - Scroll to "Default Authentication Method" panel. Select "uaf" authentication mode. - - Click "Update" button at the bottom of this page. - -4. Try to log in using UAF authentication method: - - Wait 30 seconds and try to log in again. During this time oxAuth reload list of available person authentication modules. - - Open second browser or second browsing session and try to log in again. It's better to try to do that from another browser session because we can return back to previous authentication method if something will go wrong. - -There are log messages in this custom authentication script. In order to debug this module we can use command like this: -tail -f /opt/tomcat/logs/wrapper.log | grep "UAF" diff --git a/jans-auth-server/server/integrations/uaf/Readme.md b/jans-auth-server/server/integrations/uaf/Readme.md deleted file mode 100644 index 8073ff5b0ab..00000000000 --- a/jans-auth-server/server/integrations/uaf/Readme.md +++ /dev/null @@ -1,51 +0,0 @@ -# FIDO UAF Authenticator - -UAF allows applications to take advantage of the security capabilities of modern devices such as fingerprint, iris, and voice biometrics. It provides a unified infrastructure that allows you to integrate these capabilities in a simple manner to enable authentication that is both more user friendly and more secure than passwords. - -## Typical UAF architecture - -The following diagram provides an overview of the UAF infrastructure, which contains (1) components that resides on the user’s device, and (2) server side components that connect to a UAF server. The typical gateway between these two parts is a mobile browser with a UAF plugin. The RP should provide proxy capabilities to deliver messages from the mobile browser plugin to the UAF server. - -![Typical UAF design](./img/typical_uaf_architecture.png) - -It's not very convenient when the RP is a second device. Non Nok offers an Out-of-band (OOB) API which simplifies UAF integration in this case. - -## Out-of-Band Authentication -Out-of-Band authentication allows mobile device authenticatation with UAF even on devices that -do not have any UAF components installed. Using this workflow, the user of a laptop authenticates -to a web application using their mobile device. The user binds the browser session to his or her -mobile device by scanning a QR code, or by triggering a push notification. The user then performs -the UAF authentication on an out-of-band channel between the mobile device and the Nok Nok -Authentication Server. Once the user authenticates successfully, the Authentication Server -notifies your application server. OOB is a proprietary feature developed by Nok Nok Labs on top -of the FIDO UAF protocol. - -![OOB with QR codes](./img/oob_qr_code.png) - -Also it allows push notification messages to be sent by the platform. - -## Device integration models - -This is not a part of the UAF authentication script, but it shows the modular -architecture of the UAF mobile authentication stack. - -Some devices will feature a preloaded UAF Client and one or more UAF ASMs. In some cases, -devices may only feature a preloaded UAF ASM, rather than both a UAF Client and ASM. Older -legacy devices may feature neither a UAF Client nor a UAF ASM. Nevertheless the App SDK -can support each of these three scenarios illustrated below from the same mobile application. - -![Typical UAF design](./img/uaf_device_integration_models.png) - - -## Integration with oxAuth - -The oxAuth UAF integration leverages the Person Authentication module. This workflow shows -the communication process between the components. - -![Typical UAF design](./img/gluu_uaf_integration_authentication_workflow.png) - -## Person authentication module activation - -This module is part of CE. It has only one mandatory property "uaf_server_uri". There are more information about module configuration in "Installation.md" and "Properties description.md" - -Nok Nok SDK contains sample application which allows to test script. In the SDK there are binaries and source code of this application. diff --git a/jans-auth-server/server/integrations/yubicloud/YubicloudExternalAuthenticator.py b/jans-auth-server/server/integrations/yubicloud/YubicloudExternalAuthenticator.py deleted file mode 100644 index ada83ef1457..00000000000 --- a/jans-auth-server/server/integrations/yubicloud/YubicloudExternalAuthenticator.py +++ /dev/null @@ -1,118 +0,0 @@ -# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. -# Copyright (c) 2020, Janssen Project -# -# Author: Yuriy Movchan, Arunmozhi -# - -from io.jans.service.cdi.util import CdiUtil -from io.jans.as.server.security import Identity -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.server.service import UserService -from io.jans.util import StringHelper - -import java - -import urllib2 -import urllib -import uuid - - -class PersonAuthentication(PersonAuthenticationType): - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - - def init(self, customScript, configurationAttributes): - print "Yubicloud. Initialization" - - self.api_server = configurationAttributes.get("yubicloud_uri").getValue2() - self.api_key = configurationAttributes.get("yubicloud_api_key").getValue2() - self.client_id = configurationAttributes.get("yubicloud_id").getValue2() - - return True - - def destroy(self, configurationAttributes): - print "Yubicloud. Destroyed successfully" - return True - - def getApiVersion(self): - return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - return True - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - def authenticate(self, configurationAttributes, requestParameters, step): - if (step == 1): - print "Yubicloud. Authenticate for step 1" - - identity = CdiUtil.bean(Identity) - credentials = identity.getCredentials() - - username = credentials.getUsername() - otp = credentials.getPassword() - - # Validate otp length - if len(otp) < 32 or len(otp) > 48: - print "Yubicloud. Invalid OTP length" - return False - - user_service = CdiUtil.bean(UserService) - user = user_service.getUser(username) - - public_key = user.getAttribute('yubikeyId') - - # Match the user with the yubikey - if public_key not in otp: - print "Yubicloud. Public Key not matching OTP" - return False - - data = "" - try: - nonce = str(uuid.uuid4()).replace("-", "") - params = urllib.urlencode({"id": self.client_id, "otp": otp, "nonce": nonce}) - url = "https://" + self.api_server + "/wsapi/2.0/verify/?" + params - f = urllib2.urlopen(url) - data = f.read() - except Exception as e: - print "Yubicloud. Exception ", e - - if 'status=OK' in data: - user_service.authenticate(username) - print "Yubicloud. Authentication Successful" - return True - - print "Yubicloud. End of Step 1. Returning False." - return False - else: - return False - - def prepareForStep(self, configurationAttributes, requestParameters, step): - if (step == 1): - print "Yubicloud. Prepare for Step 1" - return True - else: - return False - - def getExtraParametersForStep(self, configurationAttributes, step): - return None - - def getCountAuthenticationSteps(self, configurationAttributes): - return 1 - - def getPageForStep(self, configurationAttributes, step): - return "" - - def getNextStep(self, configurationAttributes, requestParameters, step): - return -1 - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None - - def logout(self, configurationAttributes, requestParameters): - return True diff --git a/jans-linux-setup/static/extension/person_authentication/BasicExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/BasicExternalAuthenticator.py index a17afbfa0fb..77dcf8ac0b7 100644 --- a/jans-linux-setup/static/extension/person_authentication/BasicExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/BasicExternalAuthenticator.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # diff --git a/jans-linux-setup/static/extension/person_authentication/BasicLockAccountExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/BasicLockAccountExternalAuthenticator.py index 74187311f4a..5fbdbd758a3 100644 --- a/jans-linux-setup/static/extension/person_authentication/BasicLockAccountExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/BasicLockAccountExternalAuthenticator.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # Author: Gasmyr Mougang @@ -29,7 +29,7 @@ def __init__(self, currentTimeMillis): def init(self, customScript, configurationAttributes): print "Basic (lock account). Initialization" - self.invalidLoginCountAttribute = "oxCountInvalidLogin" + self.invalidLoginCountAttribute = "jansCountInvalidLogin" if configurationAttributes.containsKey("invalid_login_count_attribute"): self.invalidLoginCountAttribute = configurationAttributes.get("invalid_login_count_attribute").getValue2() else: @@ -232,15 +232,14 @@ def lockUser(self, user_name): if (find_user_by_uid == None): return None - status_attribute_value = userService.getCustomAttribute(find_user_by_uid, "jansStatus") + status_attribute_value = userService.getCustomAttribute(find_user_by_uid, "gluuStatus") if status_attribute_value != None: user_status = status_attribute_value.getValue() if StringHelper.equals(user_status, "inactive"): print "Basic (lock account). Lock user. User '%s' locked already" % user_name return - userService.setCustomAttribute(find_user_by_uid, "jansStatus", "inactive") - userService.setCustomAttribute(find_user_by_uid, "oxTrustActive", "false") + userService.setCustomAttribute(find_user_by_uid, "gluuStatus", "inactive") updated_user = userService.updateUser(find_user_by_uid) object_to_store = json.dumps({'locked': True, 'created': LocalDateTime.now().toString()}, separators=(',',':')) @@ -265,7 +264,6 @@ def unLockUser(self, user_name): cacheService.put(StringHelper.toString(self.lockExpirationTime), "lock_user_"+user_name, object_to_store); userService.setCustomAttribute(find_user_by_uid, "jansStatus", "active") - userService.setCustomAttribute(find_user_by_uid, "oxTrustActive", "true") userService.setCustomAttribute(find_user_by_uid, self.invalidLoginCountAttribute, None) updated_user = userService.updateUser(find_user_by_uid) diff --git a/jans-linux-setup/static/extension/person_authentication/Casa.py b/jans-linux-setup/static/extension/person_authentication/Casa.py deleted file mode 100644 index 6ff7d03d29e..00000000000 --- a/jans-linux-setup/static/extension/person_authentication/Casa.py +++ /dev/null @@ -1,667 +0,0 @@ -# Author: Jose Gonzalez - -from java.util import Collections, HashMap, HashSet, ArrayList, Arrays, Date -from java.nio.charset import Charset - -from org.apache.http.params import CoreConnectionPNames - -from org.oxauth.persistence.model.configuration import JanssenConfiguration -from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService, UserService -from io.jans.as.service.common import EncryptionService -from io.jans.as.service.custom import CustomScriptService -from io.jans.as.service.net import HttpService -from io.jans.as.util import ServerUtil -from io.jans.model import SimpleCustomProperty -from io.jans.model.casa import ApplicationConfiguration -from io.jans.model.custom.script import CustomScriptType -from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.persist import PersistenceEntryManager -from io.jans.service import CacheService -from io.jans.service.cdi.util import CdiUtil -from io.jans.util import StringHelper - -try: - import json -except ImportError: - import simplejson as json -import sys - -class PersonAuthentication(PersonAuthenticationType): - - def __init__(self, currentTimeMillis): - self.currentTimeMillis = currentTimeMillis - self.ACR_SG = "super.jans. - self.ACR_U2F = "u2f" - - self.modulePrefix = "casa-external_" - - def init(self, customScript, configurationAttributes): - - print "Casa. init called" - self.authenticators = {} - self.uid_attr = self.getLocalPrimaryKey() - - custScriptService = CdiUtil.bean(CustomScriptService) - self.scriptsList = custScriptService.findCustomScripts(Collections.singletonList(CustomScriptType.PERSON_AUTHENTICATION), "oxConfigurationProperty", "displayName", "jansEnabled", "oxLevel") - dynamicMethods = self.computeMethods(self.scriptsList) - - if len(dynamicMethods) > 0: - print "Casa. init. Loading scripts for dynamic modules: %s" % dynamicMethods - - for acr in dynamicMethods: - moduleName = self.modulePrefix + acr - try: - external = __import__(moduleName, globals(), locals(), ["PersonAuthentication"], -1) - module = external.PersonAuthentication(self.currentTimeMillis) - - print "Casa. init. Got dynamic module for acr %s" % acr - configAttrs = self.getConfigurationAttributes(acr, self.scriptsList) - - if acr == self.ACR_U2F: - u2f_application_id = configurationAttributes.get("u2f_app_id").getValue2() - configAttrs.put("u2f_application_id", SimpleCustomProperty("u2f_application_id", u2f_application_id)) - elif acr == self.ACR_SG: - application_id = configurationAttributes.get("supe.jans.app_id").getValue2() - configAttrs.put("application_id", SimpleCustomProperty("application_id", application_id)) - - if module.init(None, configAttrs): - module.configAttrs = configAttrs - self.authenticators[acr] = module - else: - print "Casa. init. Call to init in module '%s' returned False" % moduleName - except: - print "Casa. init. Failed to load module %s" % moduleName - print "Exception: ", sys.exc_info()[1] - - mobile_methods = configurationAttributes.get("mobile_methods") - self.mobile_methods = [] if mobile_methods == None else StringHelper.split(mobile_methods.getValue2(), ",") - - print "Casa. init. Initialized successfully" - return True - - - def destroy(self, configurationAttributes): - print "Casa. Destroyed called" - return True - - - def getApiVersion(self): - return 11 - - - def getAuthenticationMethodClaims(self, configurationAttributes): - return None - - - def isValidAuthenticationMethod(self, usageType, configurationAttributes): - print "Casa. isValidAuthenticationMethod called" - return True - - - def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): - return None - - - def authenticate(self, configurationAttributes, requestParameters, step): - print "Casa. authenticate for step %s" % str(step) - - userService = CdiUtil.bean(UserService) - authenticationService = CdiUtil.bean(AuthenticationService) - identity = CdiUtil.bean(Identity) - - if step == 1: - credentials = identity.getCredentials() - user_name = credentials.getUsername() - user_password = credentials.getPassword() - - if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password): - - foundUser = userService.getUserByAttribute(self.uid_attr, user_name) - #foundUser = userService.getUser(user_name) - if foundUser == None: - print "Casa. authenticate for step 1. Unknown username" - else: - platform_data = self.parsePlatformData(requestParameters) - mfaOff = foundUser.getAttribute("oxPreferredMethod") == None - logged_in = False - - if mfaOff: - logged_in = authenticationService.authenticate(user_name, user_password) - else: - acr = self.getSuitableAcr(foundUser, platform_data) - if acr != None: - module = self.authenticators[acr] - logged_in = module.authenticate(module.configAttrs, requestParameters, step) - - if logged_in: - foundUser = authenticationService.getAuthenticatedUser() - - if foundUser == None: - print "Casa. authenticate for step 1. Cannot retrieve logged user" - else: - if mfaOff: - identity.setWorkingParameter("skip2FA", True) - else: - #Determine whether to skip 2FA based on policy defined (global or user custom) - skip2FA = self.determineSkip2FA(userService, identity, foundUser, platform_data) - identity.setWorkingParameter("skip2FA", skip2FA) - identity.setWorkingParameter("ACR", acr) - - return True - - else: - print "Casa. authenticate for step 1 was not successful" - return False - - else: - user = authenticationService.getAuthenticatedUser() - if user == None: - print "Casa. authenticate for step 2. Cannot retrieve logged user" - return False - - #see casa.xhtml - alter = ServerUtil.getFirstValue(requestParameters, "alternativeMethod") - if alter != None: - #bypass the rest of this step if an alternative method was provided. Current step will be retried (see getNextStep) - self.simulateFirstStep(requestParameters, alter) - return True - - session_attributes = identity.getSessionId().getSessionAttributes() - acr = session_attributes.get("ACR") - #this working parameter is used in casa.xhtml - identity.setWorkingParameter("methods", ArrayList(self.getAvailMethodsUser(user, acr))) - - success = False - if acr in self.authenticators: - module = self.authenticators[acr] - success = module.authenticate(module.configAttrs, requestParameters, step) - - #Update the list of trusted devices if 2fa passed - if success: - print "Casa. authenticate. 2FA authentication was successful" - tdi = session_attributes.get("trustedDevicesInfo") - if tdi == None: - print "Casa. authenticate. List of user's trusted devices was not updated" - else: - user.setAttribute("oxTrustedDevicesInfo", tdi) - userService.updateUser(user) - else: - print "Casa. authenticate. 2FA authentication failed" - - return success - - return False - - - def prepareForStep(self, configurationAttributes, requestParameters, step): - print "Casa. prepareForStep %s" % str(step) - identity = CdiUtil.bean(Identity) - - if step == 1: - self.prepareUIParams(identity) - return True - else: - session_attributes = identity.getSessionId().getSessionAttributes() - - authenticationService = CdiUtil.bean(AuthenticationService) - user = authenticationService.getAuthenticatedUser() - - if user == None: - print "Casa. prepareForStep. Cannot retrieve logged user" - return False - - acr = session_attributes.get("ACR") - print "Casa. prepareForStep. ACR = %s" % acr - identity.setWorkingParameter("methods", ArrayList(self.getAvailMethodsUser(user, acr))) - - if acr in self.authenticators: - module = self.authenticators[acr] - return module.prepareForStep(module.configAttrs, requestParameters, step) - else: - return False - - - def getExtraParametersForStep(self, configurationAttributes, step): - print "Casa. getExtraParametersForStep %s" % str(step) - list = ArrayList() - - if step > 1: - acr = CdiUtil.bean(Identity).getWorkingParameter("ACR") - - if acr in self.authenticators: - module = self.authenticators[acr] - params = module.getExtraParametersForStep(module.configAttrs, step) - if params != None: - list.addAll(params) - - list.addAll(Arrays.asList("ACR", "methods", "trustedDevicesInfo")) - - list.addAll(Arrays.asList("casa_contextPath", "casa_prefix", "casa_faviconUrl", "casa_extraCss", "casa_logoUrl")) - print "extras are %s" % list - return list - - - def getCountAuthenticationSteps(self, configurationAttributes): - print "Casa. getCountAuthenticationSteps called" - - if CdiUtil.bean(Identity).getWorkingParameter("skip2FA"): - return 1 - - acr = CdiUtil.bean(Identity).getWorkingParameter("ACR") - if acr in self.authenticators: - module = self.authenticators[acr] - return module.getCountAuthenticationSteps(module.configAttrs) - else: - return 2 - - print "Casa. getCountAuthenticationSteps. Could not determine the step count for acr %s" % acr - - - def getPageForStep(self, configurationAttributes, step): - print "Casa. getPageForStep called %s" % str(step) - - if step > 1: - acr = CdiUtil.bean(Identity).getWorkingParameter("ACR") - if acr in self.authenticators: - module = self.authenticators[acr] - page = module.getPageForStep(module.configAttrs, step) - else: - page=None - - return page - - return "/casa/login.xhtml" - - - def getNextStep(self, configurationAttributes, requestParameters, step): - - print "Casa. getNextStep called %s" % str(step) - if step > 1: - acr = ServerUtil.getFirstValue(requestParameters, "alternativeMethod") - if acr != None: - print "Casa. getNextStep. Use alternative method %s" % acr - CdiUtil.bean(Identity).setWorkingParameter("ACR", acr) - #retry step with different acr - return 2 - - return -1 - - - def logout(self, configurationAttributes, requestParameters): - print "Casa. logout called" - return True - -# Miscelaneous - - def getLocalPrimaryKey(self): - entryManager = CdiUtil.bean(PersistenceEntryManager) - config = JanssenConfiguration() - config = entryManager.find(config.getClass(), "ou=configuration,o.jans.) - #Pick (one) attribute where user id is stored (e.g. uid/mail) - uid_attr = config.getOxIDPAuthentication().get(0).getConfig().getPrimaryKey() - print "Casa. init. uid attribute is '%s'" % uid_attr - return uid_attr - - - def getSettings(self): - entryManager = CdiUtil.bean(PersistenceEntryManager) - config = ApplicationConfiguration() - config = entryManager.find(config.getClass(), "ou=casa,ou=configuration,o.jans.) - settings = None - try: - settings = json.loads(config.getSettings()) - except: - print "Casa. getSettings. Failed to parse casa settings from DB" - return settings - - - def computeMethods(self, scriptList): - - methods = [] - mapping = {} - cmConfigs = self.getSettings() - - if cmConfigs != None and 'acr_plugin_mapping' in cmConfigs: - mapping = cmConfigs['acr_plugin_mapping'] - - for m in mapping: - for customScript in scriptList: - if customScript.getName() == m and customScript.isEnabled(): - methods.append(m) - - print "Casa. computeMethods. %s" % methods - return methods - - - def getConfigurationAttributes(self, acr, scriptsList): - - configMap = HashMap() - for customScript in scriptsList: - if customScript.getName() == acr and customScript.isEnabled(): - for prop in customScript.getConfigurationProperties(): - configMap.put(prop.getValue1(), SimpleCustomProperty(prop.getValue1(), prop.getValue2())) - - print "Casa. getConfigurationAttributes. %d configuration properties were found for %s" % (configMap.size(), acr) - return configMap - - - def getAvailMethodsUser(self, user, skip=None): - methods = HashSet() - - for method in self.authenticators: - try: - module = self.authenticators[method] - if module.hasEnrollments(module.configAttrs, user): - methods.add(method) - except: - print "Casa. getAvailMethodsUser. hasEnrollments call could not be issued for %s module" % method - print "Exception: ", sys.exc_info()[1] - - try: - if skip != None: - # skip is guaranteed to be a member of methods (if hasEnrollments routines are properly implemented). - # A call to remove strangely crashes when skip is absent - methods.remove(skip) - except: - print "Casa. getAvailMethodsUser. methods list does not contain %s" % skip - - print "Casa. getAvailMethodsUser %s" % methods.toString() - return methods - - - def prepareUIParams(self, identity): - - print "Casa. prepareUIParams. Reading UI branding params" - cacheService = CdiUtil.bean(CacheService) - casaAssets = cacheService.get("casa_assets") - - if casaAssets == None: - #This may happen when cache type is IN_MEMORY, where actual cache is merely a local variable - #(a expiring map) living inside Casa webapp, not oxAuth webapp - - sets = self.getSettings() - - custPrefix = "/custom" - logoUrl = "/images/logo.png" - faviconUrl = "/images/favicon.ico" - if ("extra_css" in sets and sets["extra_css"] != None) or sets["use_branding"]: - logoUrl = custPrefix + logoUrl - faviconUrl = custPrefix + faviconUrl - - prefix = custPrefix if sets["use_branding"] else "" - - casaAssets = { - "contextPath": "/casa", - "prefix" : prefix, - "faviconUrl" : faviconUrl, - "extraCss": sets["extra_css"] if "extra_css" in sets else None, - "logoUrl": logoUrl - } - - #Setting a single variable with the whole map does not work... - identity.setWorkingParameter("casa_contextPath", casaAssets['contextPath']) - identity.setWorkingParameter("casa_prefix", casaAssets['prefix']) - identity.setWorkingParameter("casa_faviconUrl", casaAssets['contextPath'] + casaAssets['faviconUrl']) - identity.setWorkingParameter("casa_extraCss", casaAssets['extraCss']) - identity.setWorkingParameter("casa_logoUrl", casaAssets['contextPath'] + casaAssets['logoUrl']) - - - def simulateFirstStep(self, requestParameters, acr): - #To simulate 1st step, there is no need to call: - # getPageforstep (no need as user/pwd won't be shown again) - # isValidAuthenticationMethod (by restriction, it returns True) - # prepareForStep (by restriction, it returns True) - # getExtraParametersForStep (by restriction, it returns None) - print "Casa. simulateFirstStep. Calling authenticate (step 1) for %s module" % acr - if acr in self.authenticators: - module = self.authenticators[acr] - auth = module.authenticate(module.configAttrs, requestParameters, 1) - print "Casa. simulateFirstStep. returned value was %s" % auth - - -# 2FA policy enforcement - - def parsePlatformData(self, requestParameters): - try: - #Find device info passed in HTTP request params (see index.xhtml) - platform = ServerUtil.getFirstValue(requestParameters, "loginForm:platform") - deviceInf = json.loads(platform) - except: - print "Casa. parsePlatformData. Error parsing platform data" - deviceInf = None - - return deviceInf - - - def getSuitableAcr(self, user, deviceInf): - - onMobile = deviceInf != None and 'isMobile' in deviceInf and deviceInf['isMobile'] - id = user.getUserId() - strongest = -1 - acr = None - user_methods = self.getAvailMethodsUser(user) - - for s in self.scriptsList: - name = s.getName() - if user_methods.contains(name) and name in self.authenticators and s.getLevel() > strongest and (not onMobile or name in self.mobile_methods): - acr = name - strongest = s.getLevel() - - print "Casa. getSuitableAcr. On mobile = %s" % onMobile - if acr == None and onMobile: - print "Casa. getSuitableAcr. No mobile-friendly authentication method available for user %s" % id - # user_methods is not empty when this function is called, so just pick any - acr = user_methods.get(0) - - print "Casa. getSuitableAcr. %s was selected for user %s" % (acr, id) - return acr - - - def determineSkip2FA(self, userService, identity, foundUser, deviceInf): - - cmConfigs = self.getSettings() - - if cmConfigs == None: - print "Casa. determineSkip2FA. Failed to read policy_2fa" - return False - - missing = False - if not 'plugins_settings' in cmConfigs: - missing = True - elif not 'strong-authn-settings' in cmConfigs['plugins_settings']: - missing = True - else: - cmConfigs = cmConfigs['plugins_settings']['strong-authn-settings'] - - policy2FA = 'EVERY_LOGIN' - if not missing and 'policy_2fa' in cmConfigs: - policy2FA = ','.join(cmConfigs['policy_2fa']) - - print "Casa. determineSkip2FA with general policy %s" % policy2FA - policy2FA += ',' - skip2FA = False - - if 'CUSTOM,' in policy2FA: - #read setting from user profile - policy = foundUser.getAttribute("oxStrongAuthPolicy") - if policy == None: - policy = 'EVERY_LOGIN,' - else: - policy = policy.upper() + ',' - print "Casa. determineSkip2FA. Using user's enforcement policy %s" % policy - - else: - #If it's not custom, then apply the global setting admin defined - policy = policy2FA - - if not 'EVERY_LOGIN,' in policy: - locationCriterion = 'LOCATION_UNKNOWN,' in policy - deviceCriterion = 'DEVICE_UNKNOWN,' in policy - - if locationCriterion or deviceCriterion: - if deviceInf == None: - print "Casa. determineSkip2FA. No user device data. Forcing 2FA to take place..." - else: - skip2FA = self.process2FAPolicy(identity, foundUser, deviceInf, locationCriterion, deviceCriterion) - - if skip2FA: - print "Casa. determineSkip2FA. Second factor is skipped" - #Update attribute if authentication will not have second step - devInf = identity.getWorkingParameter("trustedDevicesInfo") - if devInf != None: - foundUser.setAttribute("oxTrustedDevicesInfo", devInf) - userService.updateUser(foundUser) - else: - print "Casa. determineSkip2FA. Unknown %s policy: cannot skip 2FA" % policy - - return skip2FA - - - def process2FAPolicy(self, identity, foundUser, deviceInf, locationCriterion, deviceCriterion): - - skip2FA = False - #Retrieve user's devices info - devicesInfo = foundUser.getAttribute("oxTrustedDevicesInfo") - - #do geolocation - geodata = self.getGeolocation(identity) - if geodata == None: - print "Casa. process2FAPolicy: Geolocation data not obtained. 2FA skipping based on location cannot take place" - - try: - encService = CdiUtil.bean(EncryptionService) - - if devicesInfo == None: - print "Casa. process2FAPolicy: There are no trusted devices for user yet" - #Simulate empty list - devicesInfo = "[]" - else: - devicesInfo = encService.decrypt(devicesInfo) - - devicesInfo = json.loads(devicesInfo) - - partialMatch = False - idx = 0 - #Try to find a match for device only - for device in devicesInfo: - partialMatch = device['browser']['name']==deviceInf['name'] and device['os']['version']==deviceInf['os']['version'] and device['os']['family']==deviceInf['os']['family'] - if partialMatch: - break - idx+=1 - - matchFound = False - - #At least one of locationCriterion or deviceCriterion is True - if locationCriterion and not deviceCriterion: - #this check makes sense if there is city data only - if geodata!=None: - for device in devicesInfo: - #Search all registered cities that are found in trusted devices - for origin in device['origins']: - matchFound = matchFound or origin['city']==geodata['city'] - - elif partialMatch: - #In this branch deviceCriterion is True - if not locationCriterion: - matchFound = True - elif geodata!=None: - for origin in devicesInfo[idx]['origins']: - matchFound = matchFound or origin['city']==geodata['city'] - - skip2FA = matchFound - now = Date().getTime() - - #Update attribute oxTrustedDevicesInfo accordingly - if partialMatch: - #Update an existing record (update timestamp in city, or else add it) - if geodata != None: - partialMatch = False - idxCity = 0 - - for origin in devicesInfo[idx]['origins']: - partialMatch = origin['city']==geodata['city'] - if partialMatch: - break; - idxCity+=1 - - if partialMatch: - devicesInfo[idx]['origins'][idxCity]['timestamp'] = now - else: - devicesInfo[idx]['origins'].append({"city": geodata['city'], "country": geodata['country'], "timestamp": now}) - else: - #Create a new entry - browser = {"name": deviceInf['name'], "version": deviceInf['version']} - os = {"family": deviceInf['os']['family'], "version": deviceInf['os']['version']} - - if geodata == None: - origins = [] - else: - origins = [{"city": geodata['city'], "country": geodata['country'], "timestamp": now}] - - obj = {"browser": browser, "os": os, "addedOn": now, "origins": origins} - devicesInfo.append(obj) - - enc = json.dumps(devicesInfo, separators=(',',':')) - enc = encService.encrypt(enc) - identity.setWorkingParameter("trustedDevicesInfo", enc) - - except: - print "Casa. process2FAPolicy. Error!", sys.exc_info()[1] - - return skip2FA - - - def getGeolocation(self, identity): - - session_attributes = identity.getSessionId().getSessionAttributes() - if session_attributes.containsKey("remote_ip"): - remote_ip = session_attributes.get("remote_ip") - if StringHelper.isNotEmpty(remote_ip): - - httpService = CdiUtil.bean(HttpService) - - http_client = httpService.getHttpsClient() - http_client_params = http_client.getParams() - http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 4 * 1000) - - geolocation_service_url = "http://ip-api.com/json/%s?fields=country,city,status,message" % remote_ip - geolocation_service_headers = { "Accept" : "application/json" } - - try: - http_service_response = httpService.executeGet(http_client, geolocation_service_url, geolocation_service_headers) - http_response = http_service_response.getHttpResponse() - except: - print "Casa. Determine remote location. Exception: ", sys.exc_info()[1] - return None - - try: - if not httpService.isResponseStastusCodeOk(http_response): - print "Casa. Determine remote location. Get non 200 OK response from server:", str(http_response.getStatusLine().getStatusCode()) - httpService.consume(http_response) - return None - - response_bytes = httpService.getResponseContent(http_response) - response_string = httpService.convertEntityToString(response_bytes, Charset.forName("UTF-8")) - httpService.consume(http_response) - finally: - http_service_response.closeConnection() - - if response_string == None: - print "Casa. Determine remote location. Get empty response from location server" - return None - - response = json.loads(response_string) - - if not StringHelper.equalsIgnoreCase(response['status'], "success"): - print "Casa. Determine remote location. Get response with status: '%s'" % response['status'] - return None - - return response - - return None - - - def getLogoutExternalUrl(self, configurationAttributes, requestParameters): - print "Get external logout URL call" - return None diff --git a/jans-linux-setup/static/extension/person_authentication/DuoExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/DuoExternalAuthenticator.py index 589b0062018..262b559f7c0 100644 --- a/jans-linux-setup/static/extension/person_authentication/DuoExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/DuoExternalAuthenticator.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # diff --git a/jans-linux-setup/static/extension/person_authentication/Fido2ExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/Fido2ExternalAuthenticator.py index a0ea4bb4845..bf91db2df49 100644 --- a/jans-linux-setup/static/extension/person_authentication/Fido2ExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/Fido2ExternalAuthenticator.py @@ -1,30 +1,26 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2018, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # -from javax.ws.rs.core import Response -from org.jboss.resteasy.client import ClientResponseFailure -from org.jboss.resteasy.client.exception import ResteasyClientException -from javax.ws.rs.core import Response from io.jans.model.custom.script.type.auth import PersonAuthenticationType from io.jans.fido2.client import Fido2ClientFactory from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService, SessionIdService +from io.jans.as.server.service import AuthenticationService from io.jans.as.server.service import UserService -from io.jans.as.util import ServerUtil +from io.jans.as.server.service import SessionIdService +from io.jans.as.server.util import ServerUtil from io.jans.service.cdi.util import CdiUtil from io.jans.util import StringHelper from java.util.concurrent.locks import ReentrantLock +from javax.ws.rs import ClientErrorException +from javax.ws.rs.core import Response import java import sys -try: - import json -except ImportError: - import simplejson as json +import json class PersonAuthentication(PersonAuthenticationType): def __init__(self, currentTimeMillis): @@ -42,7 +38,7 @@ def init(self, customScript, configurationAttributes): self.fido2_domain = None if configurationAttributes.containsKey("fido2_domain"): self.fido2_domain = configurationAttributes.get("fido2_domain").getValue2() - + self.metaDataLoaderLock = ReentrantLock() self.metaDataConfiguration = None @@ -56,10 +52,7 @@ def destroy(self, configurationAttributes): def getApiVersion(self): return 11 - - def getAuthenticationMethodClaims(self, requestParameters): - return None - + def isValidAuthenticationMethod(self, usageType, configurationAttributes): return True @@ -157,21 +150,20 @@ def prepareForStep(self, configurationAttributes, requestParameters, step): userName = user.getUserId() metaDataConfiguration = self.getMetaDataConfiguration() - + assertionResponse = None attestationResponse = None # Check if user have registered devices - userService = CdiUtil.bean(UserService) - countFido2Devices = userService.countFidoAndFido2Devices(userName, self.fido2_domain) - if countFido2Devices > 0: + count = CdiUtil.bean(UserService).countFido2RegisteredDevices(userName, self.fido2_domain) + if count > 0: print "Fido2. Prepare for step 2. Call Fido2 endpoint in order to start assertion flow" try: assertionService = Fido2ClientFactory.instance().createAssertionService(metaDataConfiguration) assertionRequest = json.dumps({'username': userName}, separators=(',', ':')) assertionResponse = assertionService.authenticate(assertionRequest).readEntity(java.lang.String) - except ClientResponseFailure, ex: + except ClientErrorException, ex: print "Fido2. Prepare for step 2. Failed to start assertion flow. Exception:", sys.exc_info()[1] return False else: @@ -179,9 +171,9 @@ def prepareForStep(self, configurationAttributes, requestParameters, step): try: attestationService = Fido2ClientFactory.instance().createAttestationService(metaDataConfiguration) - attestationRequest = json.dumps({'username': userName, 'displayName': userName, 'attestation' : 'direct'}, separators=(',', ':')) + attestationRequest = json.dumps({'username': userName, 'displayName': userName, 'attestation': 'direct'}, separators=(',', ':')) attestationResponse = attestationService.register(attestationRequest).readEntity(java.lang.String) - except ClientResponseFailure, ex: + except ClientErrorException, ex: print "Fido2. Prepare for step 2. Failed to start attestation flow. Exception:", sys.exc_info()[1] return False @@ -221,8 +213,7 @@ def getAuthenticationMethodClaims(self, requestParameters): def getLogoutExternalUrl(self, configurationAttributes, requestParameters): print "Get external logout URL call" return None - - + def getMetaDataConfiguration(self): if self.metaDataConfiguration != None: return self.metaDataConfiguration @@ -235,7 +226,6 @@ def getMetaDataConfiguration(self): try: print "Fido2. Initialization. Downloading Fido2 metadata" self.fido2_server_metadata_uri = self.fido2_server_uri + "/.well-known/fido2-configuration" - #self.fido2_server_metadata_uri = self.fido2_server_uri + "/fido2/restv1/fido2/configuration" metaDataConfigurationService = Fido2ClientFactory.instance().createMetaDataConfigurationService(self.fido2_server_metadata_uri) @@ -244,20 +234,12 @@ def getMetaDataConfiguration(self): try: self.metaDataConfiguration = metaDataConfigurationService.getMetadataConfiguration().readEntity(java.lang.String) return self.metaDataConfiguration - except ClientResponseFailure, ex: + except ClientErrorException, ex: # Detect if last try or we still get Service Unavailable HTTP error if (attempt == max_attempts) or (ex.getResponse().getResponseStatus() != Response.Status.SERVICE_UNAVAILABLE): raise ex - java.lang.Thread.sleep(3000) - print "Attempting to load metadata: %d" % attempt - except ResteasyClientException, ex: - # Detect if last try or we still get Service Unavailable HTTP error - if attempt == max_attempts: - raise ex - java.lang.Thread.sleep(3000) print "Attempting to load metadata: %d" % attempt finally: self.metaDataLoaderLock.unlock() - diff --git a/jans-linux-setup/static/extension/person_authentication/OtpExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/OtpExternalAuthenticator.py index 7dcaeb4674d..b5134a0ca9b 100644 --- a/jans-linux-setup/static/extension/person_authentication/OtpExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/OtpExternalAuthenticator.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # @@ -32,13 +32,13 @@ from io.jans.jsf2.message import FacesMessages from io.jans.model.custom.script.type.auth import PersonAuthenticationType from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService, SessionIdService +from io.jans.as.server.service import AuthenticationService +from io.jans.as.server.service import SessionIdService from io.jans.as.server.service import UserService -from io.jans.as.util import ServerUtil +from io.jans.as.server.util import ServerUtil from io.jans.service.cdi.util import CdiUtil from io.jans.util import StringHelper - class PersonAuthentication(PersonAuthenticationType): def __init__(self, currentTimeMillis): self.currentTimeMillis = currentTimeMillis @@ -98,7 +98,7 @@ def getNextStep(self, configurationAttributes, requestParameters, step): if retry_current_step: print "OTP. Get next step. Retrying current step %s" % step # Remove old QR code - #identity.setWorkingParameter("super.jans.request", "timeout") + #identity.setWorkingParameter("super_gluu_request", "timeout") resultStep = step return resultStep return -1 @@ -371,12 +371,12 @@ def findEnrollments(self, user_name, skipPrefix = True): result = [] userService = CdiUtil.bean(UserService) - user = userService.getUser(user_name, "oxExternalUid") + user = userService.getUser(user_name, "jansExtUid") if user == None: print "OTP. Find enrollments. Failed to find user" return result - user_custom_ext_attribute = userService.getCustomAttribute(user, "oxExternalUid") + user_custom_ext_attribute = userService.getCustomAttribute(user, "jansExtUid") if user_custom_ext_attribute == None: return result @@ -439,7 +439,7 @@ def processOtpAuthentication(self, requestParameters, user_name, identity, otp_a otp_user_external_uid = "hotp:%s;%s" % ( otp_secret_key_encoded, validation_result["movingFactor"] ) # Add otp_user_external_uid to user's external GUID list - find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", otp_user_external_uid) + find_user_by_external_uid = userService.addUserAttribute(user_name, "jansExtUid", otp_user_external_uid, True) if find_user_by_external_uid != None: return True @@ -452,7 +452,7 @@ def processOtpAuthentication(self, requestParameters, user_name, identity, otp_a otp_user_external_uid = "totp:%s" % otp_secret_key_encoded # Add otp_user_external_uid to user's external GUID list - find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", otp_user_external_uid) + find_user_by_external_uid = userService.addUserAttribute(user_name, "jansExtUid", otp_user_external_uid, True) if find_user_by_external_uid != None: return True @@ -482,7 +482,7 @@ def processOtpAuthentication(self, requestParameters, user_name, identity, otp_a new_otp_user_external_uid = "hotp:%s;%s" % ( otp_secret_key_encoded, validation_result["movingFactor"] ) # Update moving factor in user entry - find_user_by_external_uid = userService.replaceUserAttribute(user_name, "oxExternalUid", otp_user_external_uid, new_otp_user_external_uid) + find_user_by_external_uid = userService.replaceUserAttribute(user_name, "jansExtUid", otp_user_external_uid, new_otp_user_external_uid, True) if find_user_by_external_uid != None: return True @@ -566,20 +566,20 @@ def validateTotpKey(self, secretKey, totpKey, user_name): if StringHelper.equals(localTotpKey, totpKey) and not StringHelper.equals(localTotpKey, cachedOTP): userService = CdiUtil.bean(UserService) if cachedOTP is None: - userService.addUserAttribute(user_name, "oxOTPCache",localTotpKey) + userService.addUserAttribute(user_name, "jansOTPCache",localTotpKey) else : - userService.replaceUserAttribute(user_name, "oxOTPCache", cachedOTP, localTotpKey) + userService.replaceUserAttribute(user_name, "jansOTPCache", cachedOTP, localTotpKey) print "OTP. Caching OTP: '%s'" % localTotpKey return { "result": True } return { "result": False } def getCachedOTP(self, user_name): userService = CdiUtil.bean(UserService) - user = userService.getUser(user_name, "oxOTPCache") + user = userService.getUser(user_name, "jansOTPCache") if user is None: print "OTP. Get Cached OTP. Failed to find OTP" return None - customAttribute = userService.getCustomAttribute(user, "oxOTPCache") + customAttribute = userService.getCustomAttribute(user, "jansOTPCache") if customAttribute is None: print "OTP. Custom attribute is null" @@ -613,5 +613,3 @@ def toBase64Url(self, bytes): def fromBase64Url(self, chars): return BaseEncoding.base64Url().decode(chars) - - diff --git a/jans-linux-setup/static/extension/person_authentication/README.md b/jans-linux-setup/static/extension/person_authentication/README.md new file mode 100644 index 00000000000..ef38c90e805 --- /dev/null +++ b/jans-linux-setup/static/extension/person_authentication/README.md @@ -0,0 +1,5 @@ +# 2FA authentication scripts + +Jython files contained in the top level of this folder are already added as authentication scripts in your Janssen installation. + +Inside `other` directory you may find extra information about these scripts as well as additional (non curated) scripts that you may use as a guide to integrate third party authentication services or APIs with Janssen server. \ No newline at end of file diff --git a/jans-linux-setup/static/extension/person_authentication/SuperGluuExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/SuperGluuExternalAuthenticator.py index 4bdb57278da..83098109875 100644 --- a/jans-linux-setup/static/extension/person_authentication/SuperGluuExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/SuperGluuExternalAuthenticator.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # @@ -11,28 +11,23 @@ from io.jans.service.cdi.util import CdiUtil from io.jans.as.server.security import Identity from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.model.config import ConfigurationFactory -from io.jans.as.server.service import AuthenticationService, SessionIdService -from io.jans.as.service.fido.u2f import DeviceRegistrationService -from io.jans.as.service.net import HttpService -from io.jans.as.util import ServerUtil +from io.jans.as.server.model.config import ConfigurationFactory +from io.jans.as.server.service import AuthenticationService +from io.jans.as.server.service import SessionIdService +from io.jans.as.server.service.fido.u2f import DeviceRegistrationService +from io.jans.as.server.service.net import HttpService +from io.jans.as.server.util import ServerUtil from io.jans.util import StringHelper -from io.jans.as.service.common import EncryptionService, UserService +from io.jans.as.common.service.common import EncryptionService +from io.jans.as.server.service import UserService from io.jans.service import MailService -from io.jans.as.service.push.sns import PushPlatform, PushSnsService -from io.jans.oxnotify.client import NotifyClientFactory +from io.jans.as.server.service.push.sns import PushPlatform +from io.jans.as.server.service.push.sns import PushSnsService +from io.jans.notify.client import NotifyClientFactory from java.util import Arrays, HashMap, IdentityHashMap, Date from java.time import ZonedDateTime from java.time.format import DateTimeFormatter -try: - from io.jans.oxd.license.client.js import Product - from io.jans.oxd.license.validator import LicenseValidator - has_license_api = True -except ImportError: - print "Super-Janssen. Load. Failed to load licensing API" - has_license_api = False - import datetime import urllib @@ -44,10 +39,10 @@ def __init__(self, currentTimeMillis): self.currentTimeMillis = currentTimeMillis def init(self, customScript, configurationAttributes): - print "Super-Janssen. Initialization" + print "Super-Gluu. Initialization" if not configurationAttributes.containsKey("authentication_mode"): - print "Super-Janssen. Initialization. Property authentication_mode is mandatory" + print "Super-Gluu. Initialization. Property authentication_mode is mandatory" return False self.applicationId = None @@ -60,25 +55,25 @@ def init(self, customScript, configurationAttributes): authentication_mode = configurationAttributes.get("authentication_mode").getValue2() if StringHelper.isEmpty(authentication_mode): - print "Super-Janssen. Initialization. Failed to determine authentication_mode. authentication_mode configuration parameter is empty" + print "Super-Gluu. Initialization. Failed to determine authentication_mode. authentication_mode configuration parameter is empty" return False self.oneStep = StringHelper.equalsIgnoreCase(authentication_mode, "one_step") self.twoStep = StringHelper.equalsIgnoreCase(authentication_mode, "two_step") if not (self.oneStep or self.twoStep): - print "Super-Janssen. Initialization. Valid authentication_mode values are one_step and two_step" + print "Super-Gluu. Initialization. Valid authentication_mode values are one_step and two_step" return False self.enabledPushNotifications = self.initPushNotificationService(configurationAttributes) self.androidUrl = None - if configurationAttributes.containsKey("supe.jans.android_download_url"): - self.androidUrl = configurationAttributes.get("supe.jans.android_download_url").getValue2() + if configurationAttributes.containsKey("supergluu_android_download_url"): + self.androidUrl = configurationAttributes.get("supergluu_android_download_url").getValue2() self.IOSUrl = None - if configurationAttributes.containsKey("supe.jans.ios_download_url"): - self.IOSUrl = configurationAttributes.get("supe.jans.ios_download_url").getValue2() + if configurationAttributes.containsKey("supergluu_ios_download_url"): + self.IOSUrl = configurationAttributes.get("supergluu_ios_download_url").getValue2() self.customLabel = None if configurationAttributes.containsKey("label"): @@ -88,69 +83,43 @@ def init(self, customScript, configurationAttributes): if configurationAttributes.containsKey("qr_options"): self.customQrOptions = configurationAttributes.get("qr_options").getValue2() - self.use_super.jans.group = False - if configurationAttributes.containsKey("super.jans.group"): - self.super.jans.group = configurationAttributes.get("super.jans.group").getValue2() - self.use_super.jans.group = True - print "Super-Janssen. Initialization. Using super.jans.only if user belong to group: %s" % self.super.jans.group + self.use_super_gluu_group = False + if configurationAttributes.containsKey("super_gluu_group"): + self.super_gluu_group = configurationAttributes.get("super_gluu_group").getValue2() + self.use_super_gluu_group = True + print "Super-Gluu. Initialization. Using super_gluu only if user belong to group: %s" % self.super_gluu_group self.use_audit_group = False if configurationAttributes.containsKey("audit_group"): self.audit_group = configurationAttributes.get("audit_group").getValue2() if (not configurationAttributes.containsKey("audit_group_email")): - print "Super-Janssen. Initialization. Property audit_group_email is not specified" + print "Super-Gluu. Initialization. Property audit_group_email is not specified" return False self.audit_email = configurationAttributes.get("audit_group_email").getValue2() self.use_audit_group = True - print "Super-Janssen. Initialization. Using audit group: %s" % self.audit_group + print "Super-Gluu. Initialization. Using audit group: %s" % self.audit_group - if self.use_super.jans.group or self.use_audit_group: + if self.use_super_gluu_group or self.use_audit_group: if not configurationAttributes.containsKey("audit_attribute"): - print "Super-Janssen. Initialization. Property audit_attribute is not specified" + print "Super-Gluu. Initialization. Property audit_attribute is not specified" return False else: self.audit_attribute = configurationAttributes.get("audit_attribute").getValue2() - self.valid_license = False - # Removing or altering this block validation is against the terms of the license. - if has_license_api and configurationAttributes.containsKey("license_file"): - license_file = configurationAttributes.get("license_file").getValue2() - - # Load license from file - f = open(license_file, 'r') - try: - license = json.loads(f.read()) - except: - print "Super-Janssen. Initialization. Failed to load license from file: %s" % license_file - return False - finally: - f.close() - - # Validate license - try: - self.license_content = LicenseValidator.validate(license["public_key"], license["public_password"], license["license_password"], license["license"], - Product.SUPER_GLUU, Date()) - self.valid_license = self.license_content.isValid() - except: - print "Super-Janssen. Initialization. Failed to validate license. Exception: ", sys.exc_info()[1] - return False - - print "Super-Janssen. Initialization. License status: '%s'. License metadata: '%s'" % (self.valid_license, self.license_content.getMetadata()) - - print "Super-Janssen. Initialized successfully. oneStep: '%s', twoStep: '%s', pushNotifications: '%s', customLabel: '%s'" % (self.oneStep, self.twoStep, self.enabledPushNotifications, self.customLabel) + print "Super-Gluu. Initialized successfully. oneStep: '%s', twoStep: '%s', pushNotifications: '%s', customLabel: '%s'" % (self.oneStep, self.twoStep, self.enabledPushNotifications, self.customLabel) return True def destroy(self, configurationAttributes): - print "Super-Janssen. Destroy" + print "Super-Gluu. Destroy" self.pushAndroidService = None self.pushAppleService = None - print "Super-Janssen. Destroyed successfully" + print "Super-Gluu. Destroyed successfully" return True def getApiVersion(self): @@ -175,7 +144,7 @@ def authenticate(self, configurationAttributes, requestParameters, step): client_redirect_uri = self.getApplicationUri(session_attributes) if client_redirect_uri == None: - print "Super-Janssen. Authenticate. redirect_uri is not set" + print "Super-Gluu. Authenticate. redirect_uri is not set" return False self.setRequestScopedParameters(identity, step) @@ -184,20 +153,20 @@ def authenticate(self, configurationAttributes, requestParameters, step): identity.setWorkingParameter("retry_current_step", False) form_auth_result = ServerUtil.getFirstValue(requestParameters, "auth_result") if StringHelper.isNotEmpty(form_auth_result): - print "Super-Janssen. Authenticate for step %s. Get auth_result: '%s'" % (step, form_auth_result) + print "Super-Gluu. Authenticate for step %s. Get auth_result: '%s'" % (step, form_auth_result) if form_auth_result in ['error']: return False if form_auth_result in ['timeout']: if ((step == 1) and self.oneStep) or ((step == 2) and self.twoStep): - print "Super-Janssen. Authenticate for step %s. Reinitializing current step" % step + print "Super-Gluu. Authenticate for step %s. Reinitializing current step" % step identity.setWorkingParameter("retry_current_step", True) return False userService = CdiUtil.bean(UserService) deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService) if step == 1: - print "Super-Janssen. Authenticate for step 1" + print "Super-Gluu. Authenticate for step 1" user_name = credentials.getUsername() if self.oneStep: @@ -209,33 +178,33 @@ def authenticate(self, configurationAttributes, requestParameters, step): validation_result = self.validateSessionDeviceStatus(client_redirect_uri, session_device_status) if validation_result: - print "Super-Janssen. Authenticate for step 1. User successfully authenticated with u2f_device '%s'" % u2f_device_id + print "Super-Gluu. Authenticate for step 1. User successfully authenticated with u2f_device '%s'" % u2f_device_id else: return False if not session_device_status['one_step']: - print "Super-Janssen. Authenticate for step 1. u2f_device '%s' is not one step device" % u2f_device_id + print "Super-Gluu. Authenticate for step 1. u2f_device '%s' is not one step device" % u2f_device_id return False # There are two steps only in enrollment mode if session_device_status['enroll']: return validation_result - identity.setWorkingParameter("super.jans.count_login_steps", 1) + identity.setWorkingParameter("super_gluu_count_login_steps", 1) user_inum = session_device_status['user_inum'] - u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id, "oxId") + u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id, "jansId") if u2f_device == None: - print "Super-Janssen. Authenticate for step 1. Failed to load u2f_device '%s'" % u2f_device_id + print "Super-Gluu. Authenticate for step 1. Failed to load u2f_device '%s'" % u2f_device_id return False logged_in = authenticationService.authenticate(user_name) if not logged_in: - print "Super-Janssen. Authenticate for step 1. Failed to authenticate user '%s'" % user_name + print "Super-Gluu. Authenticate for step 1. Failed to authenticate user '%s'" % user_name return False - print "Super-Janssen. Authenticate for step 1. User '%s' successfully authenticated with u2f_device '%s'" % (user_name, u2f_device_id) + print "Super-Gluu. Authenticate for step 1. User '%s' successfully authenticated with u2f_device '%s'" % (user_name, u2f_device_id) return True elif self.twoStep: @@ -243,20 +212,20 @@ def authenticate(self, configurationAttributes, requestParameters, step): if authenticated_user == None: return False - if (self.use_super.jans.group): - print "Super-Janssen. Authenticate for step 1. Checking if user belong to super.jans.group" - is_member_super.jans.group = self.isUserMemberOfGroup(authenticated_user, self.audit_attribute, self.super.jans.group) - if (is_member_super.jans.group): - print "Super-Janssen. Authenticate for step 1. User '%s' member of super.jans.group" % authenticated_user.getUserId() - super.jans.count_login_steps = 2 + if (self.use_super_gluu_group): + print "Super-Gluu. Authenticate for step 1. Checking if user belong to super_gluu group" + is_member_super_gluu_group = self.isUserMemberOfGroup(authenticated_user, self.audit_attribute, self.super_gluu_group) + if (is_member_super_gluu_group): + print "Super-Gluu. Authenticate for step 1. User '%s' member of super_gluu group" % authenticated_user.getUserId() + super_gluu_count_login_steps = 2 else: if self.use_audit_group: self.processAuditGroup(authenticated_user, self.audit_attribute, self.audit_group) - super.jans.count_login_steps = 1 + super_gluu_count_login_steps = 1 - identity.setWorkingParameter("super.jans.count_login_steps", super.jans.count_login_steps) + identity.setWorkingParameter("super_gluu_count_login_steps", super_gluu_count_login_steps) - if super.jans.count_login_steps == 1: + if super_gluu_count_login_steps == 1: return True auth_method = 'authenticate' @@ -266,24 +235,24 @@ def authenticate(self, configurationAttributes, requestParameters, step): if auth_method == 'authenticate': user_inum = userService.getUserInum(authenticated_user) - u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, "oxId") + u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, "jansId") if u2f_devices_list.size() == 0: auth_method = 'enroll' - print "Super-Janssen. Authenticate for step 1. There is no U2F '%s' user devices associated with application '%s'. Changing auth_method to '%s'" % (user_name, client_redirect_uri, auth_method) + print "Super-Gluu. Authenticate for step 1. There is no U2F '%s' user devices associated with application '%s'. Changing auth_method to '%s'" % (user_name, client_redirect_uri, auth_method) - print "Super-Janssen. Authenticate for step 1. auth_method: '%s'" % auth_method + print "Super-Gluu. Authenticate for step 1. auth_method: '%s'" % auth_method - identity.setWorkingParameter("super.jans.auth_method", auth_method) + identity.setWorkingParameter("super_gluu_auth_method", auth_method) return True return False elif step == 2: - print "Super-Janssen. Authenticate for step 2" + print "Super-Gluu. Authenticate for step 2" user = authenticationService.getAuthenticatedUser() if (user == None): - print "Super-Janssen. Authenticate for step 2. Failed to determine user name" + print "Super-Gluu. Authenticate for step 2. Failed to determine user name" return False user_name = user.getUserId() @@ -305,22 +274,22 @@ def authenticate(self, configurationAttributes, requestParameters, step): attach_result = deviceRegistrationService.attachUserDeviceRegistration(user_inum, u2f_device_id) - print "Super-Janssen. Authenticate for step 2. Result after attaching u2f_device '%s' to user '%s': '%s'" % (u2f_device_id, user_name, attach_result) + print "Super-Gluu. Authenticate for step 2. Result after attaching u2f_device '%s' to user '%s': '%s'" % (u2f_device_id, user_name, attach_result) return attach_result elif self.twoStep: if user_name == None: - print "Super-Janssen. Authenticate for step 2. Failed to determine user name" + print "Super-Gluu. Authenticate for step 2. Failed to determine user name" return False validation_result = self.validateSessionDeviceStatus(client_redirect_uri, session_device_status, user_name) if validation_result: - print "Super-Janssen. Authenticate for step 2. User '%s' successfully authenticated with u2f_device '%s'" % (user_name, u2f_device_id) + print "Super-Gluu. Authenticate for step 2. User '%s' successfully authenticated with u2f_device '%s'" % (user_name, u2f_device_id) else: return False - super.jans.request = json.loads(session_device_status['super.jans.request']) - auth_method = super.jans.request['method'] + super_gluu_request = json.loads(session_device_status['super_gluu_request']) + auth_method = super_gluu_request['method'] if auth_method in ['enroll', 'authenticate']: if validation_result and self.use_audit_group: user = authenticationService.getAuthenticatedUser() @@ -328,7 +297,7 @@ def authenticate(self, configurationAttributes, requestParameters, step): return validation_result - print "Super-Janssen. Authenticate for step 2. U2F auth_method is invalid" + print "Super-Gluu. Authenticate for step 2. U2F auth_method is invalid" return False else: @@ -340,84 +309,82 @@ def prepareForStep(self, configurationAttributes, requestParameters, step): client_redirect_uri = self.getApplicationUri(session_attributes) if client_redirect_uri == None: - print "Super-Janssen. Prepare for step. redirect_uri is not set" + print "Super-Gluu. Prepare for step. redirect_uri is not set" return False self.setRequestScopedParameters(identity, step) if step == 1: - print "Super-Janssen. Prepare for step 1" + print "Super-Gluu. Prepare for step 1" if self.oneStep: session = CdiUtil.bean(SessionIdService).getSessionId() if session == None: - print "Super-Janssen. Prepare for step 2. Failed to determine session_id" + print "Super-Gluu. Prepare for step 2. Failed to determine session_id" return False issuer = CdiUtil.bean(ConfigurationFactory).getConfiguration().getIssuer() - super.jans.request_dictionary = {'app': client_redirect_uri, + super_gluu_request_dictionary = {'app': client_redirect_uri, 'issuer': issuer, 'state': session.getId(), - 'licensed': self.valid_license, 'created': DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().withNano(0))} - self.addGeolocationData(session_attributes, super.jans.request_dictionary) + self.addGeolocationData(session_attributes, super_gluu_request_dictionary) - super.jans.request = json.dumps(super.jans.request_dictionary, separators=(',',':')) - print "Super-Janssen. Prepare for step 1. Prepared super.jans.request:", super.jans.request + super_gluu_request = json.dumps(super_gluu_request_dictionary, separators=(',',':')) + print "Super-Gluu. Prepare for step 1. Prepared super_gluu_request:", super_gluu_request - identity.setWorkingParameter("super.jans.request", super.jans.request) + identity.setWorkingParameter("super_gluu_request", super_gluu_request) elif self.twoStep: identity.setWorkingParameter("display_register_action", True) return True elif step == 2: - print "Super-Janssen. Prepare for step 2" + print "Super-Gluu. Prepare for step 2" if self.oneStep: return True authenticationService = CdiUtil.bean(AuthenticationService) user = authenticationService.getAuthenticatedUser() if user == None: - print "Super-Janssen. Prepare for step 2. Failed to determine user name" + print "Super-Gluu. Prepare for step 2. Failed to determine user name" return False - if session_attributes.containsKey("super.jans.request"): - super.jans.request = session_attributes.get("super.jans.request") - if not StringHelper.equalsIgnoreCase(super.jans.request, "timeout"): - print "Super-Janssen. Prepare for step 2. Request was generated already" + if session_attributes.containsKey("super_gluu_request"): + super_gluu_request = session_attributes.get("super_gluu_request") + if not StringHelper.equalsIgnoreCase(super_gluu_request, "timeout"): + print "Super-Gluu. Prepare for step 2. Request was generated already" return True session = CdiUtil.bean(SessionIdService).getSessionId() if session == None: - print "Super-Janssen. Prepare for step 2. Failed to determine session_id" + print "Super-Gluu. Prepare for step 2. Failed to determine session_id" return False - auth_method = session_attributes.get("super.jans.auth_method") + auth_method = session_attributes.get("super_gluu_auth_method") if StringHelper.isEmpty(auth_method): - print "Super-Janssen. Prepare for step 2. Failed to determine auth_method" + print "Super-Gluu. Prepare for step 2. Failed to determine auth_method" return False - print "Super-Janssen. Prepare for step 2. auth_method: '%s'" % auth_method + print "Super-Gluu. Prepare for step 2. auth_method: '%s'" % auth_method issuer = CdiUtil.bean(ConfigurationFactory).getAppConfiguration().getIssuer() - super.jans.request_dictionary = {'username': user.getUserId(), + super_gluu_request_dictionary = {'username': user.getUserId(), 'app': client_redirect_uri, 'issuer': issuer, 'method': auth_method, 'state': session.getId(), - 'licensed': self.valid_license, 'created': DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().withNano(0))} - self.addGeolocationData(session_attributes, super.jans.request_dictionary) + self.addGeolocationData(session_attributes, super_gluu_request_dictionary) - super.jans.request = json.dumps(super.jans.request_dictionary, separators=(',',':')) - print "Super-Janssen. Prepare for step 2. Prepared super.jans.request:", super.jans.request + super_gluu_request = json.dumps(super_gluu_request_dictionary, separators=(',',':')) + print "Super-Gluu. Prepare for step 2. Prepared super_gluu_request:", super_gluu_request - identity.setWorkingParameter("super.jans.request", super.jans.request) - identity.setWorkingParameter("super.jans.auth_method", auth_method) + identity.setWorkingParameter("super_gluu_request", super_gluu_request) + identity.setWorkingParameter("super_gluu_auth_method", auth_method) if auth_method in ['authenticate']: - self.sendPushNotification(client_redirect_uri, user, super.jans.request) + self.sendPushNotification(client_redirect_uri, user, super_gluu_request) return True else: @@ -428,10 +395,10 @@ def getNextStep(self, configurationAttributes, requestParameters, step): identity = CdiUtil.bean(Identity) retry_current_step = identity.getWorkingParameter("retry_current_step") if retry_current_step: - print "Super-Janssen. Get next step. Retrying current step" + print "Super-Gluu. Get next step. Retrying current step" # Remove old QR code - identity.setWorkingParameter("super.jans.request", "timeout") + identity.setWorkingParameter("super_gluu_request", "timeout") resultStep = step return resultStep @@ -441,36 +408,36 @@ def getNextStep(self, configurationAttributes, requestParameters, step): def getExtraParametersForStep(self, configurationAttributes, step): if step == 1: if self.oneStep: - return Arrays.asList("super.jans.request") + return Arrays.asList("super_gluu_request") elif self.twoStep: return Arrays.asList("display_register_action") elif step == 2: - return Arrays.asList("super.jans.auth_method", "super.jans.request") + return Arrays.asList("super_gluu_auth_method", "super_gluu_request") return None def getCountAuthenticationSteps(self, configurationAttributes): identity = CdiUtil.bean(Identity) - if identity.isSetWorkingParameter("super.jans.count_login_steps"): - return identity.getWorkingParameter("super.jans.count_login_steps") + if identity.isSetWorkingParameter("super_gluu_count_login_steps"): + return identity.getWorkingParameter("super_gluu_count_login_steps") else: return 2 def getPageForStep(self, configurationAttributes, step): if step == 1: if self.oneStep: - return "/auth/super.jans.login.xhtml" + return "/auth/super-gluu/login.xhtml" elif step == 2: if self.oneStep: return "/login.xhtml" else: identity = CdiUtil.bean(Identity) - authmethod = identity.getWorkingParameter("super.jans.auth_method") - print "Super-Janssen. authmethod '%s'" % authmethod + authmethod = identity.getWorkingParameter("super_gluu_auth_method") + print "Super-Gluu. authmethod '%s'" % authmethod if authmethod == "enroll": - return "/auth/super.jans.login.xhtml" + return "/auth/super-gluu/login.xhtml" else: - return "/auth/super.jans.login.xhtml" + return "/auth/super-gluu/login.xhtml" return "" @@ -496,7 +463,7 @@ def processBasicAuthentication(self, credentials): find_user_by_uid = authenticationService.getAuthenticatedUser() if find_user_by_uid == None: - print "Super-Janssen. Process basic authentication. Failed to find user '%s'" % user_name + print "Super-Gluu. Process basic authentication. Failed to find user '%s'" % user_name return None return find_user_by_uid @@ -511,7 +478,7 @@ def validateSessionDeviceStatus(self, client_redirect_uri, session_device_status if session_device_status['enroll'] and session_device_status['one_step']: u2f_device = deviceRegistrationService.findOneStepUserDeviceRegistration(u2f_device_id) if u2f_device == None: - print "Super-Janssen. Validate session device status. There is no one step u2f_device '%s'" % u2f_device_id + print "Super-Gluu. Validate session device status. There is no one step u2f_device '%s'" % u2f_device_id return False else: # Validate if user has specified device_id enrollment @@ -522,40 +489,40 @@ def validateSessionDeviceStatus(self, client_redirect_uri, session_device_status u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id) if u2f_device == None: - print "Super-Janssen. Validate session device status. There is no u2f_device '%s' associated with user '%s'" % (u2f_device_id, user_inum) + print "Super-Gluu. Validate session device status. There is no u2f_device '%s' associated with user '%s'" % (u2f_device_id, user_inum) return False if not StringHelper.equalsIgnoreCase(client_redirect_uri, u2f_device.application): - print "Super-Janssen. Validate session device status. u2f_device '%s' associated with other application '%s'" % (u2f_device_id, u2f_device.application) + print "Super-Gluu. Validate session device status. u2f_device '%s' associated with other application '%s'" % (u2f_device_id, u2f_device.application) return False return True def getSessionDeviceStatus(self, session_attributes, user_name): - print "Super-Janssen. Get session device status" + print "Super-Gluu. Get session device status" - if not session_attributes.containsKey("super.jans.request"): - print "Super-Janssen. Get session device status. There is no Super-Janssen request in session attributes" + if not session_attributes.containsKey("super_gluu_request"): + print "Super-Gluu. Get session device status. There is no Super-Gluu request in session attributes" return None # Check session state extended if not session_attributes.containsKey("session_custom_state"): - print "Super-Janssen. Get session device status. There is no session_custom_state in session attributes" + print "Super-Gluu. Get session device status. There is no session_custom_state in session attributes" return None session_custom_state = session_attributes.get("session_custom_state") if not StringHelper.equalsIgnoreCase("approved", session_custom_state): - print "Super-Janssen. Get session device status. User '%s' not approve or not pass U2F authentication. session_custom_state: '%s'" % (user_name, session_custom_state) + print "Super-Gluu. Get session device status. User '%s' not approve or not pass U2F authentication. session_custom_state: '%s'" % (user_name, session_custom_state) return None # Try to find device_id in session attribute if not session_attributes.containsKey("oxpush2_u2f_device_id"): - print "Super-Janssen. Get session device status. There is no u2f_device associated with this request" + print "Super-Gluu. Get session device status. There is no u2f_device associated with this request" return None # Try to find user_inum in session attribute if not session_attributes.containsKey("oxpush2_u2f_device_user_inum"): - print "Super-Janssen. Get session device status. There is no user_inum associated with this request" + print "Super-Gluu. Get session device status. There is no user_inum associated with this request" return None enroll = False @@ -566,31 +533,31 @@ def getSessionDeviceStatus(self, session_attributes, user_name): if session_attributes.containsKey("oxpush2_u2f_device_one_step"): one_step = StringHelper.equalsIgnoreCase("true", session_attributes.get("oxpush2_u2f_device_one_step")) - super.jans.request = session_attributes.get("super.jans.request") + super_gluu_request = session_attributes.get("super_gluu_request") u2f_device_id = session_attributes.get("oxpush2_u2f_device_id") user_inum = session_attributes.get("oxpush2_u2f_device_user_inum") - session_device_status = {"super.jans.request": super.jans.request, "device_id": u2f_device_id, "user_inum" : user_inum, "enroll" : enroll, "one_step" : one_step} - print "Super-Janssen. Get session device status. session_device_status: '%s'" % (session_device_status) + session_device_status = {"super_gluu_request": super_gluu_request, "device_id": u2f_device_id, "user_inum" : user_inum, "enroll" : enroll, "one_step" : one_step} + print "Super-Gluu. Get session device status. session_device_status: '%s'" % (session_device_status) return session_device_status def initPushNotificationService(self, configurationAttributes): - print "Super-Janssen. Initialize Native/SNS/Janssen notification services" + print "Super-Gluu. Initialize Native/SNS/Gluu notification services" self.pushSnsMode = False - self.pushJanssenMode = False + self.pushGluuMode = False if configurationAttributes.containsKey("notification_service_mode"): notificationServiceMode = configurationAttributes.get("notification_service_mode").getValue2() if StringHelper.equalsIgnoreCase(notificationServiceMode, "sns"): return self.initSnsPushNotificationService(configurationAttributes) - elif StringHelper.equalsIgnoreCase(notificationServiceMode, .jans.): - return self.initJanssenPushNotificationService(configurationAttributes) + elif StringHelper.equalsIgnoreCase(notificationServiceMode, "gluu"): + return self.initGluuPushNotificationService(configurationAttributes) return self.initNativePushNotificationService(configurationAttributes) def initNativePushNotificationService(self, configurationAttributes): - print "Super-Janssen. Initialize native notification services" + print "Super-Gluu. Initialize native notification services" creds = self.loadPushNotificationCreds(configurationAttributes) if creds == None: @@ -600,14 +567,14 @@ def initNativePushNotificationService(self, configurationAttributes): android_creds = creds["android"]["gcm"] ios_creds = creds["ios"]["apns"] except: - print "Super-Janssen. Initialize native notification services. Invalid credentials file format" + print "Super-Gluu. Initialize native notification services. Invalid credentials file format" return False self.pushAndroidService = None self.pushAppleService = None if android_creds["enabled"]: self.pushAndroidService = Sender(android_creds["api_key"]) - print "Super-Janssen. Initialize native notification services. Created Android notification service" + print "Super-Gluu. Initialize native notification services. Created Android notification service" if ios_creds["enabled"]: p12_file_path = ios_creds["p12_file_path"] @@ -618,7 +585,7 @@ def initNativePushNotificationService(self, configurationAttributes): p12_password = encryptionService.decrypt(p12_password) except: # Ignore exception. Password is not encrypted - print "Super-Janssen. Initialize native notification services. Assuming that 'p12_password' password in not encrypted" + print "Super-Gluu. Initialize native notification services. Assuming that 'p12_password' password in not encrypted" apnsServiceBuilder = APNS.newService().withCert(p12_file_path, p12_password) if ios_creds["production"]: @@ -628,14 +595,14 @@ def initNativePushNotificationService(self, configurationAttributes): self.pushAppleServiceProduction = ios_creds["production"] - print "Super-Janssen. Initialize native notification services. Created iOS notification service" + print "Super-Gluu. Initialize native notification services. Created iOS notification service" enabled = self.pushAndroidService != None or self.pushAppleService != None return enabled def initSnsPushNotificationService(self, configurationAttributes): - print "Super-Janssen. Initialize SNS notification services" + print "Super-Gluu. Initialize SNS notification services" self.pushSnsMode = True creds = self.loadPushNotificationCreds(configurationAttributes) @@ -647,13 +614,13 @@ def initSnsPushNotificationService(self, configurationAttributes): android_creds = creds["android"]["sns"] ios_creds = creds["ios"]["sns"] except: - print "Super-Janssen. Initialize SNS notification services. Invalid credentials file format" + print "Super-Gluu. Initialize SNS notification services. Invalid credentials file format" return False self.pushAndroidService = None self.pushAppleService = None if not (android_creds["enabled"] or ios_creds["enabled"]): - print "Super-Janssen. Initialize SNS notification services. SNS disabled for all platforms" + print "Super-Gluu. Initialize SNS notification services. SNS disabled for all platforms" return False sns_access_key = sns_creds["access_key"] @@ -666,7 +633,7 @@ def initSnsPushNotificationService(self, configurationAttributes): sns_secret_access_key = encryptionService.decrypt(sns_secret_access_key) except: # Ignore exception. Password is not encrypted - print "Super-Janssen. Initialize SNS notification services. Assuming that 'sns_secret_access_key' in not encrypted" + print "Super-Gluu. Initialize SNS notification services. Assuming that 'sns_secret_access_key' in not encrypted" pushSnsService = CdiUtil.bean(PushSnsService) pushClient = pushSnsService.createSnsClient(sns_access_key, sns_secret_access_key, sns_region) @@ -674,116 +641,116 @@ def initSnsPushNotificationService(self, configurationAttributes): if android_creds["enabled"]: self.pushAndroidService = pushClient self.pushAndroidPlatformArn = android_creds["platform_arn"] - print "Super-Janssen. Initialize SNS notification services. Created Android notification service" + print "Super-Gluu. Initialize SNS notification services. Created Android notification service" if ios_creds["enabled"]: self.pushAppleService = pushClient self.pushApplePlatformArn = ios_creds["platform_arn"] self.pushAppleServiceProduction = ios_creds["production"] - print "Super-Janssen. Initialize SNS notification services. Created iOS notification service" + print "Super-Gluu. Initialize SNS notification services. Created iOS notification service" enabled = self.pushAndroidService != None or self.pushAppleService != None return enabled - def initJanssenPushNotificationService(self, configurationAttributes): - print "Super-Janssen. Initialize Janssen notification services" + def initGluuPushNotificationService(self, configurationAttributes): + print "Super-Gluu. Initialize Gluu notification services" - self.pushJanssenMode = True + self.pushGluuMode = True creds = self.loadPushNotificationCreds(configurationAttributes) if creds == None: return False try: - .jans.conf = creds[.jans.] - android_creds = creds["android"][.jans.] - ios_creds = creds["ios"][.jans.] + gluu_conf = creds["gluu"] + android_creds = creds["android"]["gluu"] + ios_creds = creds["ios"]["gluu"] except: - print "Super-Janssen. Initialize Janssen notification services. Invalid credentials file format" + print "Super-Gluu. Initialize Gluu notification services. Invalid credentials file format" return False self.pushAndroidService = None self.pushAppleService = None if not (android_creds["enabled"] or ios_creds["enabled"]): - print "Super-Janssen. Initialize Janssen notification services. Janssen disabled for all platforms" + print "Super-Gluu. Initialize Gluu notification services. Gluu disabled for all platforms" return False - .jans.server_uri =.jans.conf["server_uri"] + gluu_server_uri = gluu_conf["server_uri"] notifyClientFactory = NotifyClientFactory.instance() metadataConfiguration = None try: - metadataConfiguration = notifyClientFactory.createMetaDataConfigurationService.jans.server_uri).getMetadataConfiguration() + metadataConfiguration = notifyClientFactory.createMetaDataConfigurationService(gluu_server_uri).getMetadataConfiguration() except: - print "Super-Janssen. Initialize Janssen notification services. Failed to load metadata. Exception: ", sys.exc_info()[1] + print "Super-Gluu. Initialize Gluu notification services. Failed to load metadata. Exception: ", sys.exc_info()[1] return False - .jans.lient = notifyClientFactory.createNotifyService(metadataConfiguration) + gluuClient = notifyClientFactory.createNotifyService(metadataConfiguration) encryptionService = CdiUtil.bean(EncryptionService) if android_creds["enabled"]: - .jans.access_key = android_creds["access_key"] - .jans.secret_access_key = android_creds["secret_access_key"] + gluu_access_key = android_creds["access_key"] + gluu_secret_access_key = android_creds["secret_access_key"] try: - .jans.secret_access_key = encryptionService.decrypt.jans.secret_access_key) + gluu_secret_access_key = encryptionService.decrypt(gluu_secret_access_key) except: # Ignore exception. Password is not encrypted - print "Super-Janssen. Initialize Janssen notification services. Assuming that .jans.secret_access_key' in not encrypted" + print "Super-Gluu. Initialize Gluu notification services. Assuming that 'gluu_secret_access_key' in not encrypted" - self.pushAndroidService =.jans.lient - self.pushAndroidServiceAuth = notifyClientFactory.getAuthorization.jans.access_key,.jans.secret_access_key); - print "Super-Janssen. Initialize Janssen notification services. Created Android notification service" + self.pushAndroidService = gluuClient + self.pushAndroidServiceAuth = notifyClientFactory.getAuthorization(gluu_access_key, gluu_secret_access_key); + print "Super-Gluu. Initialize Gluu notification services. Created Android notification service" if ios_creds["enabled"]: - .jans.access_key = ios_creds["access_key"] - .jans.secret_access_key = ios_creds["secret_access_key"] + gluu_access_key = ios_creds["access_key"] + gluu_secret_access_key = ios_creds["secret_access_key"] try: - .jans.secret_access_key = encryptionService.decrypt.jans.secret_access_key) + gluu_secret_access_key = encryptionService.decrypt(gluu_secret_access_key) except: # Ignore exception. Password is not encrypted - print "Super-Janssen. Initialize Janssen notification services. Assuming that .jans.secret_access_key' in not encrypted" + print "Super-Gluu. Initialize Gluu notification services. Assuming that 'gluu_secret_access_key' in not encrypted" - self.pushAppleService =.jans.lient - self.pushAppleServiceAuth = notifyClientFactory.getAuthorization.jans.access_key,.jans.secret_access_key); - print "Super-Janssen. Initialize Janssen notification services. Created iOS notification service" + self.pushAppleService = gluuClient + self.pushAppleServiceAuth = notifyClientFactory.getAuthorization(gluu_access_key, gluu_secret_access_key); + print "Super-Gluu. Initialize Gluu notification services. Created iOS notification service" enabled = self.pushAndroidService != None or self.pushAppleService != None return enabled def loadPushNotificationCreds(self, configurationAttributes): - print "Super-Janssen. Initialize notification services" + print "Super-Gluu. Initialize notification services" if not configurationAttributes.containsKey("credentials_file"): return None - super.jans.creds_file = configurationAttributes.get("credentials_file").getValue2() + super_gluu_creds_file = configurationAttributes.get("credentials_file").getValue2() # Load credentials from file - f = open(super.jans.creds_file, 'r') + f = open(super_gluu_creds_file, 'r') try: creds = json.loads(f.read()) except: - print "Super-Janssen. Initialize notification services. Failed to load credentials from file:", super.jans.creds_file + print "Super-Gluu. Initialize notification services. Failed to load credentials from file:", super_gluu_creds_file return None finally: f.close() return creds - def sendPushNotification(self, client_redirect_uri, user, super.jans.request): + def sendPushNotification(self, client_redirect_uri, user, super_gluu_request): try: - self.sendPushNotificationImpl(client_redirect_uri, user, super.jans.request) + self.sendPushNotificationImpl(client_redirect_uri, user, super_gluu_request) except: - print "Super-Janssen. Send push notification. Failed to send push notification: ", sys.exc_info()[1] + print "Super-Gluu. Send push notification. Failed to send push notification: ", sys.exc_info()[1] - def sendPushNotificationImpl(self, client_redirect_uri, user, super.jans.request): + def sendPushNotificationImpl(self, client_redirect_uri, user, super_gluu_request): if not self.enabledPushNotifications: return user_name = user.getUserId() - print "Super-Janssen. Send push notification. Loading user '%s' devices" % user_name + print "Super-Gluu. Send push notification. Loading user '%s' devices" % user_name send_notification = False send_notification_result = True @@ -795,12 +762,12 @@ def sendPushNotificationImpl(self, client_redirect_uri, user, super.jans.request send_android = 0 send_ios = 0 - u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, "oxId", "oxDeviceData", "oxDeviceNotificationConf") + u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, "jansId", "jansDeviceData", "jansDeviceNotificationConf") if u2f_devices_list.size() > 0: for u2f_device in u2f_devices_list: device_data = u2f_device.getDeviceData() - # Device data which Super-Janssen gets during enrollment + # Device data which Super-Gluu gets during enrollment if device_data == None: continue @@ -811,14 +778,14 @@ def sendPushNotificationImpl(self, client_redirect_uri, user, super.jans.request if StringHelper.equalsIgnoreCase(platform, "ios") and StringHelper.isNotEmpty(push_token): # Sending notification to iOS user's device if self.pushAppleService == None: - print "Super-Janssen. Send push notification. Apple native push notification service is not enabled" + print "Super-Gluu. Send push notification. Apple native push notification service is not enabled" else: send_notification = True - title = "Super Janssen" + title = "Super Gluu" message = "Confirm your sign in request to: %s" % client_redirect_uri - if self.pushSnsMode or self.pushJanssenMode: + if self.pushSnsMode or self.pushGluuMode: pushSnsService = CdiUtil.bean(PushSnsService) targetEndpointArn = self.getTargetEndpointArn(deviceRegistrationService, pushSnsService, PushPlatform.APNS, user, u2f_device) if targetEndpointArn == None: @@ -833,7 +800,7 @@ def sendPushNotificationImpl(self, client_redirect_uri, user, super.jans.request "content-available": "1", "sound": 'default' }, - "request" : super.jans.request + "request" : super_gluu_request } push_message = json.dumps(sns_push_request_dictionary, separators=(',',':')) @@ -844,13 +811,13 @@ def sendPushNotificationImpl(self, client_redirect_uri, user, super.jans.request send_notification_result = pushSnsService.sendPushMessage(self.pushAppleService, apple_push_platform, targetEndpointArn, push_message, None) if debug: - print "Super-Janssen. Send iOS SNS push notification. token: '%s', message: '%s', send_notification_result: '%s', apple_push_platform: '%s'" % (push_token, push_message, send_notification_result, apple_push_platform) - elif self.pushJanssenMode: + print "Super-Gluu. Send iOS SNS push notification. token: '%s', message: '%s', send_notification_result: '%s', apple_push_platform: '%s'" % (push_token, push_message, send_notification_result, apple_push_platform) + elif self.pushGluuMode: send_notification_result = self.pushAppleService.sendNotification(self.pushAppleServiceAuth, targetEndpointArn, push_message) if debug: - print "Super-Janssen. Send iOS Janssen push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) + print "Super-Gluu. Send iOS Gluu push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) else: - additional_fields = { "request" : super.jans.request } + additional_fields = { "request" : super_gluu_request } msgBuilder = APNS.newPayload().alertBody(message).alertTitle(title).sound("default") msgBuilder.category('ACTIONABLE').badge(0) @@ -860,18 +827,18 @@ def sendPushNotificationImpl(self, client_redirect_uri, user, super.jans.request send_notification_result = self.pushAppleService.push(push_token, push_message) if debug: - print "Super-Janssen. Send iOS Native push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) + print "Super-Gluu. Send iOS Native push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) send_ios = send_ios + 1 if StringHelper.equalsIgnoreCase(platform, "android") and StringHelper.isNotEmpty(push_token): # Sending notification to Android user's device if self.pushAndroidService == None: - print "Super-Janssen. Send native push notification. Android native push notification service is not enabled" + print "Super-Gluu. Send native push notification. Android native push notification service is not enabled" else: send_notification = True - title = "Super-Janssen" - if self.pushSnsMode or self.pushJanssenMode: + title = "Super-Gluu" + if self.pushSnsMode or self.pushGluuMode: pushSnsService = CdiUtil.bean(PushSnsService) targetEndpointArn = self.getTargetEndpointArn(deviceRegistrationService, pushSnsService, PushPlatform.GCM, user, u2f_device) if targetEndpointArn == None: @@ -883,7 +850,7 @@ def sendPushNotificationImpl(self, client_redirect_uri, user, super.jans.request "content_available": True, "time_to_live": 60, "data": - { "message" : super.jans.request, + { "message" : super_gluu_request, "title" : title } } push_message = json.dumps(sns_push_request_dictionary, separators=(',',':')) @@ -891,21 +858,21 @@ def sendPushNotificationImpl(self, client_redirect_uri, user, super.jans.request if self.pushSnsMode: send_notification_result = pushSnsService.sendPushMessage(self.pushAndroidService, PushPlatform.GCM, targetEndpointArn, push_message, None) if debug: - print "Super-Janssen. Send Android SNS push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) - elif self.pushJanssenMode: + print "Super-Gluu. Send Android SNS push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) + elif self.pushGluuMode: send_notification_result = self.pushAndroidService.sendNotification(self.pushAndroidServiceAuth, targetEndpointArn, push_message) if debug: - print "Super-Janssen. Send Android Janssen push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) + print "Super-Gluu. Send Android Gluu push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) else: - msgBuilder = Message.Builder().addData("message", super.jans.request).addData("title", title).collapseKey("single").contentAvailable(True) + msgBuilder = Message.Builder().addData("message", super_gluu_request).addData("title", title).collapseKey("single").contentAvailable(True) push_message = msgBuilder.build() send_notification_result = self.pushAndroidService.send(push_message, push_token, 3) if debug: - print "Super-Janssen. Send Android Native push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) + print "Super-Gluu. Send Android Native push notification. token: '%s', message: '%s', send_notification_result: '%s'" % (push_token, push_message, send_notification_result) send_android = send_android + 1 - print "Super-Janssen. Send push notification. send_android: '%s', send_ios: '%s'" % (send_android, send_ios) + print "Super-Gluu. Send push notification. send_android: '%s', send_ios: '%s'" % (send_android, send_ios) def getTargetEndpointArn(self, deviceRegistrationService, pushSnsService, platform, user, u2fDevice): targetEndpointArn = None @@ -916,7 +883,7 @@ def getTargetEndpointArn(self, deviceRegistrationService, pushSnsService, platfo notificationConfJson = json.loads(notificationConf) targetEndpointArn = notificationConfJson['sns_endpoint_arn'] if StringHelper.isNotEmpty(targetEndpointArn): - print "Super-Janssen. Get target endpoint ARN. There is already created target endpoint ARN" + print "Super-Gluu. Get target endpoint ARN. There is already created target endpoint ARN" return targetEndpointArn # Create endpoint ARN @@ -927,13 +894,13 @@ def getTargetEndpointArn(self, deviceRegistrationService, pushSnsService, platfo pushClient = self.pushAndroidService if self.pushSnsMode: platformApplicationArn = self.pushAndroidPlatformArn - if self.pushJanssenMode: + if self.pushGluuMode: pushClientAuth = self.pushAndroidServiceAuth elif platform == PushPlatform.APNS: pushClient = self.pushAppleService if self.pushSnsMode: platformApplicationArn = self.pushApplePlatformArn - if self.pushJanssenMode: + if self.pushGluuMode: pushClientAuth = self.pushAppleServiceAuth else: return None @@ -941,7 +908,7 @@ def getTargetEndpointArn(self, deviceRegistrationService, pushSnsService, platfo deviceData = u2fDevice.getDeviceData() pushToken = deviceData.getPushToken() - print "Super-Janssen. Get target endpoint ARN. Attempting to create target endpoint ARN for user: '%s'" % user.getUserId() + print "Super-Gluu. Get target endpoint ARN. Attempting to create target endpoint ARN for user: '%s'" % user.getUserId() if self.pushSnsMode: targetEndpointArn = pushSnsService.createPlatformArn(pushClient, platformApplicationArn, pushToken, user) else: @@ -951,10 +918,10 @@ def getTargetEndpointArn(self, deviceRegistrationService, pushSnsService, platfo targetEndpointArn = registerDeviceResponse.getEndpointArn() if StringHelper.isEmpty(targetEndpointArn): - print "Super-Janssen. Failed to get endpoint ARN for user: '%s'" % user.getUserId() + print "Super-Gluu. Failed to get endpoint ARN for user: '%s'" % user.getUserId() return None - print "Super-Janssen. Get target endpoint ARN. Create target endpoint ARN '%s' for user: '%s'" % (targetEndpointArn, user.getUserId()) + print "Super-Gluu. Get target endpoint ARN. Create target endpoint ARN '%s' for user: '%s'" % (targetEndpointArn, user.getUserId()) # Store created endpoint ARN in device entry userInum = user.getAttribute("inum") @@ -985,29 +952,29 @@ def setRequestScopedParameters(self, identity, step): downloadMap.put("ios", self.IOSUrl) if self.customLabel != None: - identity.setWorkingParameter("super.jans.label", self.customLabel) + identity.setWorkingParameter("super_gluu_label", self.customLabel) identity.setWorkingParameter("download_url", downloadMap) - identity.setWorkingParameter("super.jans.qr_options", self.customQrOptions) + identity.setWorkingParameter("super_gluu_qr_options", self.customQrOptions) - def addGeolocationData(self, session_attributes, super.jans.request_dictionary): + def addGeolocationData(self, session_attributes, super_gluu_request_dictionary): if session_attributes.containsKey("remote_ip"): remote_ip = session_attributes.get("remote_ip") if StringHelper.isNotEmpty(remote_ip): - print "Super-Janssen. Prepare for step 2. Adding req_ip and req_loc to super.jans.request" - super.jans.request_dictionary['req_ip'] = remote_ip + print "Super-Gluu. Prepare for step 2. Adding req_ip and req_loc to super_gluu_request" + super_gluu_request_dictionary['req_ip'] = remote_ip remote_loc_dic = self.determineGeolocationData(remote_ip) if remote_loc_dic == None: - print "Super-Janssen. Prepare for step 2. Failed to determine remote location by remote IP '%s'" % remote_ip + print "Super-Gluu. Prepare for step 2. Failed to determine remote location by remote IP '%s'" % remote_ip return remote_loc = "%s, %s, %s" % ( remote_loc_dic['country'], remote_loc_dic['regionName'], remote_loc_dic['city'] ) remote_loc_encoded = urllib.quote(remote_loc.encode('utf-8')) - super.jans.request_dictionary['req_loc'] = remote_loc_encoded + super_gluu_request_dictionary['req_loc'] = remote_loc_encoded def determineGeolocationData(self, remote_ip): - print "Super-Janssen. Determine remote location. remote_ip: '%s'" % remote_ip + print "Super-Gluu. Determine remote location. remote_ip: '%s'" % remote_ip httpService = CdiUtil.bean(HttpService) http_client = httpService.getHttpsClient() @@ -1021,12 +988,12 @@ def determineGeolocationData(self, remote_ip): http_service_response = httpService.executeGet(http_client, geolocation_service_url, geolocation_service_headers) http_response = http_service_response.getHttpResponse() except: - print "Super-Janssen. Determine remote location. Exception: ", sys.exc_info()[1] + print "Super-Gluu. Determine remote location. Exception: ", sys.exc_info()[1] return None try: if not httpService.isResponseStastusCodeOk(http_response): - print "Super-Janssen. Determine remote location. Get invalid response from validation server: ", str(http_response.getStatusLine().getStatusCode()) + print "Super-Gluu. Determine remote location. Get invalid response from validation server: ", str(http_response.getStatusLine().getStatusCode()) httpService.consume(http_response) return None @@ -1037,13 +1004,13 @@ def determineGeolocationData(self, remote_ip): http_service_response.closeConnection() if response_string == None: - print "Super-Janssen. Determine remote location. Get empty response from location server" + print "Super-Gluu. Determine remote location. Get empty response from location server" return None response = json.loads(response_string) if not StringHelper.equalsIgnoreCase(response['status'], "success"): - print "Super-Janssen. Determine remote location. Get response with status: '%s'" % response['status'] + print "Super-Gluu. Determine remote location. Get response with status: '%s'" % response['status'] return None return response @@ -1062,8 +1029,8 @@ def isUserMemberOfGroup(self, user, attribute, group): def processAuditGroup(self, user, attribute, group): is_member = self.isUserMemberOfGroup(user, attribute, group) if (is_member): - print "Super-Janssen. Authenticate for processAuditGroup. User '%s' member of audit group" % user.getUserId() - print "Super-Janssen. Authenticate for processAuditGroup. Sending e-mail about user '%s' login to %s" % (user.getUserId(), self.audit_email) + print "Super-Gluu. Authenticate for processAuditGroup. User '%s' member of audit group" % user.getUserId() + print "Super-Gluu. Authenticate for processAuditGroup. Sending e-mail about user '%s' login to %s" % (user.getUserId(), self.audit_email) # Send e-mail to administrator user_id = user.getUserId() diff --git a/jans-linux-setup/static/extension/person_authentication/ThumbSignInExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/ThumbSignInExternalAuthenticator.py index 7c7e141e59f..c58de672fe1 100644 --- a/jans-linux-setup/static/extension/person_authentication/ThumbSignInExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/ThumbSignInExternalAuthenticator.py @@ -5,7 +5,7 @@ from io.jans.model.custom.script.type.auth import PersonAuthenticationType from io.jans.as.server.service import AuthenticationService from io.jans.util import StringHelper -from io.jans.as.util import ServerUtil +from io.jans.as.server.util import ServerUtil from com.pramati.ts.thumbsignin_java_sdk import ThumbsigninApiController from org.json import JSONObject from io.jans.as.model.util import Base64Util diff --git a/jans-linux-setup/static/extension/person_authentication/U2fExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/U2fExternalAuthenticator.py index 066c49d8dba..006fc84b584 100644 --- a/jans-linux-setup/static/extension/person_authentication/U2fExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/U2fExternalAuthenticator.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # @@ -7,16 +7,16 @@ import java import sys from javax.ws.rs.core import Response -from javax.ws.rs import WebApplicationException -from org.jboss.resteasy.client.exception import ResteasyClientException +from javax.ws.rs import ClientErrorException, WebApplicationException from io.jans.model.custom.script.type.auth import PersonAuthenticationType from io.jans.as.client.fido.u2f import FidoU2fClientFactory from io.jans.as.model.config import Constants from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService, SessionIdService +from io.jans.as.server.service import AuthenticationService +from io.jans.as.server.service import SessionIdService from io.jans.as.server.service import UserService -from io.jans.as.service.fido.u2f import DeviceRegistrationService -from io.jans.as.util import ServerUtil +from io.jans.as.server.service.fido.u2f import DeviceRegistrationService +from io.jans.as.server.util import ServerUtil from io.jans.service.cdi.util import CdiUtil from io.jans.util import StringHelper @@ -171,7 +171,7 @@ def prepareForStep(self, configurationAttributes, requestParameters, step): try: authenticationRequestService = FidoU2fClientFactory.instance().createAuthenticationRequestService(self.metaDataConfiguration) authenticationRequest = authenticationRequestService.startAuthentication(user.getUserId(), None, u2f_application_id, session.getId()) - except ClientResponseFailure, ex: + except ClientErrorException, ex: if (ex.getResponse().getResponseStatus() != Response.Status.NOT_FOUND): print "U2F. Prepare for step 2. Failed to start authentication workflow. Exception:", sys.exc_info()[1] return False diff --git a/jans-linux-setup/static/extension/person_authentication/UafExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/UafExternalAuthenticator.py index dbe05fa9827..0cbaa0e4d79 100644 --- a/jans-linux-setup/static/extension/person_authentication/UafExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/UafExternalAuthenticator.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # @@ -16,14 +16,16 @@ from io.jans.model.custom.script.type.auth import PersonAuthenticationType from io.jans.service.cdi.util import CdiUtil from io.jans.as.server.security import Identity -from io.jans.as.server.service import AuthenticationService, SessionIdService +from io.jans.as.server.service import AuthenticationService +from io.jans.as.server.service import SessionIdService from io.jans.as.server.service import UserService -from io.jans.util import StringHelper, ArrayHelper -from io.jans.as.util import ServerUtil +from io.jans.util import StringHelper +from io.jans.util import ArrayHelper +from io.jans.as.server.util import ServerUtil from io.jans.as.model.config import Constants from javax.ws.rs.core import Response from java.util import Arrays -from io.jans.as.service.net import HttpService +from io.jans.as.server.service.net import HttpService from org.apache.http.params import CoreConnectionPNames import sys @@ -206,10 +208,10 @@ def authenticate(self, configurationAttributes, requestParameters, step): # Double check just to make sure. We did checking in previous step # Check if there is user which has uaf_user_external_uid # Avoid mapping user cert to more than one IDP account - find_user_by_external_uid = userService.getUserByAttribute("oxExternalUid", uaf_user_external_uid) + find_user_by_external_uid = userService.getUserByAttribute("jansExtUid", uaf_user_external_uid) if find_user_by_external_uid == None: # Add uaf_user_external_uid to user's external GUID list - find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", uaf_user_external_uid) + find_user_by_external_uid = userService.addUserAttribute(user_name, "jansExtUid", uaf_user_external_uid) if find_user_by_external_uid == None: print "UAF. Authenticate for step 2. Failed to update current user" return False @@ -351,12 +353,12 @@ def findEnrollments(self, credentials): userService = CdiUtil.bean(UserService) user_name = credentials.getUsername() - user = userService.getUser(user_name, "oxExternalUid") + user = userService.getUser(user_name, "jansExtUid") if user == None: print "UAF. Find enrollments. Failed to find user" return result - user_custom_ext_attribute = userService.getCustomAttribute(user, "oxExternalUid") + user_custom_ext_attribute = userService.getCustomAttribute(user, "jansExtUid") if user_custom_ext_attribute == None: return result diff --git a/jans-linux-setup/static/extension/person_authentication/UserCertExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/UserCertExternalAuthenticator.py index 6bb71b7234f..46fa9a51612 100644 --- a/jans-linux-setup/static/extension/person_authentication/UserCertExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/UserCertExternalAuthenticator.py @@ -1,6 +1,6 @@ # -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan # @@ -12,15 +12,18 @@ from io.jans.as.server.service import AuthenticationService from io.jans.as.server.service import UserService from io.jans.util import StringHelper -from io.jans.as.util import ServerUtil -from io.jans.as.service.common import EncryptionService +from io.jans.as.server.util import ServerUtil +from io.jans.as.common.service.common import EncryptionService from java.util import Arrays -from io.jans.as.cert.fingerprint import FingerprintHelper -from io.jans.as.cert.validation import GenericCertificateVerifier, PathCertificateVerifier, OCSPCertificateVerifier, CRLCertificateVerifier -from io.jans.as.cert.validation.model import ValidationStatus -from io.jans.as.util import CertUtil +from io.jans.as.common.cert.fingerprint import FingerprintHelper +from io.jans.as.common.cert.validation import GenericCertificateVerifier +from io.jans.as.common.cert.validation import PathCertificateVerifier +from io.jans.as.common.cert.validation import OCSPCertificateVerifier +from io.jans.as.common.cert.validation import CRLCertificateVerifier +from io.jans.as.common.cert.validation.model import ValidationStatus +from io.jans.as.server.util import CertUtil from io.jans.as.model.util import CertUtils -from io.jans.as.service.net import HttpService +from io.jans.as.server.service.net import HttpService from org.apache.http.params import CoreConnectionPNames import sys @@ -167,9 +170,9 @@ def authenticate(self, configurationAttributes, requestParameters, step): # Attempt to find user by certificate fingerprint cert_user_external_uid = "cert:%s" % x509CertificateFingerprint - print "Cert. Authenticate for step 2. Attempting to find user by oxExternalUid attribute value %s" % cert_user_external_uid + print "Cert. Authenticate for step 2. Attempting to find user by jansExtUid attribute value %s" % cert_user_external_uid - find_user_by_external_uid = userService.getUserByAttribute("oxExternalUid", cert_user_external_uid) + find_user_by_external_uid = userService.getUserByAttribute("jansExtUid", cert_user_external_uid) if find_user_by_external_uid == None: print "Cert. Authenticate for step 2. Failed to find user" @@ -213,10 +216,10 @@ def authenticate(self, configurationAttributes, requestParameters, step): # Double check just to make sure. We did checking in previous step # Check if there is user which has cert_user_external_uid # Avoid mapping user cert to more than one IDP account - find_user_by_external_uid = userService.getUserByAttribute("oxExternalUid", cert_user_external_uid) + find_user_by_external_uid = userService.getUserByAttribute("jansExtUid", cert_user_external_uid) if find_user_by_external_uid == None: # Add cert_user_external_uid to user's external GUID list - find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", cert_user_external_uid) + find_user_by_external_uid = userService.addUserAttribute(user_name, "jansExtUid", cert_user_external_uid) if find_user_by_external_uid == None: print "Cert. Authenticate for step 3. Failed to update current user" return False diff --git a/jans-linux-setup/static/extension/person_authentication/YubicloudExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/YubicloudExternalAuthenticator.py index cf37afc07c6..ada83ef1457 100644 --- a/jans-linux-setup/static/extension/person_authentication/YubicloudExternalAuthenticator.py +++ b/jans-linux-setup/static/extension/person_authentication/YubicloudExternalAuthenticator.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2016, Janssen +# Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # # Author: Yuriy Movchan, Arunmozhi # @@ -7,7 +7,7 @@ from io.jans.service.cdi.util import CdiUtil from io.jans.as.server.security import Identity from io.jans.model.custom.script.type.auth import PersonAuthenticationType -from io.jans.as.service import UserService +from io.jans.as.server.service import UserService from io.jans.util import StringHelper import java diff --git a/jans-linux-setup/static/extension/person_authentication/other/ThumbSignIn/README.md b/jans-linux-setup/static/extension/person_authentication/other/ThumbSignIn/README.md new file mode 100644 index 00000000000..70286e2c30d --- /dev/null +++ b/jans-linux-setup/static/extension/person_authentication/other/ThumbSignIn/README.md @@ -0,0 +1,10 @@ +# ThumbSignIn + +ThumbSignIn can be integrated with Janssen Server to achieve strong authentication for enterprise applications. The administrator of an organization can deploy the ThumbSignIn Java SDK, UI components and custom Jython script in Janssen server. Here, ThumbSignIn is integrated with Janssen server as a primary authenticator to achieve passwordless login. The user will be able to login to the Janssen server with just his/her biometrics and there is no need for the password. For the first time user, the user can login with his/her LDAP credentials and then can register through ThumbSignIn mobile app. For the subsequent logins, the user can directly login to Janssen server with his/her biometric. + +- [Steps to perform Integration](https://thumbsignin.com/download/thumbsigninGluuIntegrationDoc) + +For more information about ThumbSignIn, see their [website](http://thumbsignin.com) + +Script contents +[here](https://github.com/JanssenProject/jans/jans-linux-setup/static/extension/person_authentication/ThumbSignInExternalAuthenticator.py) \ No newline at end of file diff --git a/jans-auth-server/server/integrations/acr_router/Readme.txt b/jans-linux-setup/static/extension/person_authentication/other/acr_router/Readme.txt similarity index 100% rename from jans-auth-server/server/integrations/acr_router/Readme.txt rename to jans-linux-setup/static/extension/person_authentication/other/acr_router/Readme.txt diff --git a/jans-auth-server/server/integrations/acr_router/acr_routerauthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/acr_router/acr_routerauthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/acr_router/acr_routerauthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/acr_router/acr_routerauthenticator.py diff --git a/jans-auth-server/server/integrations/allowed_countries/allowed_countries.py b/jans-linux-setup/static/extension/person_authentication/other/allowed_countries/allowed_countries.py similarity index 100% rename from jans-auth-server/server/integrations/allowed_countries/allowed_countries.py rename to jans-linux-setup/static/extension/person_authentication/other/allowed_countries/allowed_countries.py diff --git a/jans-auth-server/server/integrations/allowed_countries/readme.txt b/jans-linux-setup/static/extension/person_authentication/other/allowed_countries/readme.txt similarity index 98% rename from jans-auth-server/server/integrations/allowed_countries/readme.txt rename to jans-linux-setup/static/extension/person_authentication/other/allowed_countries/readme.txt index d5a5c8fc7a6..3c30d9a4236 100644 --- a/jans-auth-server/server/integrations/allowed_countries/readme.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/allowed_countries/readme.txt @@ -1,3 +1,3 @@ -This is a person authentication module for oxAuth to allow access based on the user location. - -1) allowed_countries = short Country codes (eg US,UK,IN) separated by comma which will be allowed to access +This is a person authentication module for oxAuth to allow access based on the user location. + +1) allowed_countries = short Country codes (eg US,UK,IN) separated by comma which will be allowed to access diff --git a/jans-auth-server/server/integrations/authz/ConsentGatheringSample.py b/jans-linux-setup/static/extension/person_authentication/other/authz/ConsentGatheringSample.py similarity index 100% rename from jans-auth-server/server/integrations/authz/ConsentGatheringSample.py rename to jans-linux-setup/static/extension/person_authentication/other/authz/ConsentGatheringSample.py diff --git a/jans-auth-server/server/integrations/authz/docs/Authz design.dia b/jans-linux-setup/static/extension/person_authentication/other/authz/docs/Authz design.dia similarity index 100% rename from jans-auth-server/server/integrations/authz/docs/Authz design.dia rename to jans-linux-setup/static/extension/person_authentication/other/authz/docs/Authz design.dia diff --git a/jans-auth-server/server/integrations/authz/docs/Authz design.png b/jans-linux-setup/static/extension/person_authentication/other/authz/docs/Authz design.png similarity index 100% rename from jans-auth-server/server/integrations/authz/docs/Authz design.png rename to jans-linux-setup/static/extension/person_authentication/other/authz/docs/Authz design.png diff --git a/jans-auth-server/server/integrations/azuread/AzureADAuthenticationForGluu.py b/jans-linux-setup/static/extension/person_authentication/other/azuread/AzureADAuthenticationForGluu.py similarity index 100% rename from jans-auth-server/server/integrations/azuread/AzureADAuthenticationForGluu.py rename to jans-linux-setup/static/extension/person_authentication/other/azuread/AzureADAuthenticationForGluu.py diff --git a/jans-auth-server/server/integrations/azuread/README.md b/jans-linux-setup/static/extension/person_authentication/other/azuread/README.md similarity index 100% rename from jans-auth-server/server/integrations/azuread/README.md rename to jans-linux-setup/static/extension/person_authentication/other/azuread/README.md diff --git a/jans-auth-server/server/integrations/basic.change_password/BasicPassowrdUpdateExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/basic.change_password/BasicPassowrdUpdateExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/basic.change_password/BasicPassowrdUpdateExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.change_password/BasicPassowrdUpdateExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/basic.change_password/auth/pwd/new-password.xhtml b/jans-linux-setup/static/extension/person_authentication/other/basic.change_password/auth/pwd/new-password.xhtml similarity index 100% rename from jans-auth-server/server/integrations/basic.change_password/auth/pwd/new-password.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/basic.change_password/auth/pwd/new-password.xhtml diff --git a/jans-auth-server/server/integrations/basic.client_group/BasicClientGroupExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/basic.client_group/BasicClientGroupExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/basic.client_group/BasicClientGroupExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.client_group/BasicClientGroupExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/basic.client_group/README.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.client_group/README.txt similarity index 96% rename from jans-auth-server/server/integrations/basic.client_group/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.client_group/README.txt index 788a696fc7c..9cb52631572 100644 --- a/jans-auth-server/server/integrations/basic.client_group/README.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/basic.client_group/README.txt @@ -1,25 +1,25 @@ -This person authentication module for oxAuth allows to restrict access to RP for specific user groups. It allows to define configuration for each client. - -This module has one mandatory property `configuration_file`. It's path to JSON configuration file - Example: /etc/certs/client_group.json - Example content of this file: - -{ - "client_1":{ - "client_inum":"client_inum_1", - "user_group":[ - "group_dn_1", - "group_dn_2" - ] - }, - "client_2":{ - "client_inum":"client_inum_2", - "user_group":[ - "group_dn_1", - "group_dn_2" - ] - } -} - -Also it's possible to define how it should work when there is no configuration for specific client. This is controlled via property: -`allow_default_login`: true/false +This person authentication module for oxAuth allows to restrict access to RP for specific user groups. It allows to define configuration for each client. + +This module has one mandatory property `configuration_file`. It's path to JSON configuration file + Example: /etc/certs/client_group.json + Example content of this file: + +{ + "client_1":{ + "client_inum":"client_inum_1", + "user_group":[ + "group_dn_1", + "group_dn_2" + ] + }, + "client_2":{ + "client_inum":"client_inum_2", + "user_group":[ + "group_dn_1", + "group_dn_2" + ] + } +} + +Also it's possible to define how it should work when there is no configuration for specific client. This is controlled via property: +`allow_default_login`: true/false diff --git a/jans-auth-server/server/integrations/basic.client_group/client_group.json b/jans-linux-setup/static/extension/person_authentication/other/basic.client_group/client_group.json similarity index 94% rename from jans-auth-server/server/integrations/basic.client_group/client_group.json rename to jans-linux-setup/static/extension/person_authentication/other/basic.client_group/client_group.json index c3a8380d045..4476826fc46 100644 --- a/jans-auth-server/server/integrations/basic.client_group/client_group.json +++ b/jans-linux-setup/static/extension/person_authentication/other/basic.client_group/client_group.json @@ -1,16 +1,16 @@ -{ - "client_1":{ - "client_inum":"client_inum_1", - "user_group":[ - "group_dn_1", - "group_dn_2" - ] - }, - "client_2":{ - "client_inum":"client_inum_2", - "user_group":[ - "group_dn_1", - "group_dn_2" - ] - } -} +{ + "client_1":{ + "client_inum":"client_inum_1", + "user_group":[ + "group_dn_1", + "group_dn_2" + ] + }, + "client_2":{ + "client_inum":"client_inum_2", + "user_group":[ + "group_dn_1", + "group_dn_2" + ] + } +} diff --git a/jans-auth-server/server/integrations/basic.external_logout/BasicExternalAuthenticatorWithExternalLogout.py b/jans-linux-setup/static/extension/person_authentication/other/basic.external_logout/BasicExternalAuthenticatorWithExternalLogout.py similarity index 100% rename from jans-auth-server/server/integrations/basic.external_logout/BasicExternalAuthenticatorWithExternalLogout.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.external_logout/BasicExternalAuthenticatorWithExternalLogout.py diff --git a/jans-auth-server/server/integrations/basic.external_logout/README.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.external_logout/README.txt similarity index 100% rename from jans-auth-server/server/integrations/basic.external_logout/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.external_logout/README.txt diff --git a/jans-auth-server/server/integrations/basic.lock.account/README.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.lock.account/README.txt similarity index 64% rename from jans-auth-server/server/integrations/basic.lock.account/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.lock.account/README.txt index e9c9cab7c72..94356f02aa5 100644 --- a/jans-auth-server/server/integrations/basic.lock.account/README.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/basic.lock.account/README.txt @@ -1,11 +1,12 @@ +Script contents [here](https://github.com/JanssenProject/jans/jans-linux-setup/static/extension/person_authentication/BasicLockAccountExternalAuthenticator.py) -This is person authentication module for oxAuth which do basic authentication. +This is a person authentication script for jans-auth-server which does basic authentication. It looks user account after specified number of unsuccessful login attempts. This module has 2 properties: 1) invalid_login_count_attribute - Specify attribute where script stores count of invalid number of login attemps - Default value: oxCountInvalidLogin + Default value: jansCountInvalidLogin 2) maximum_invalid_login_attemps - Specify how many times user can enter invalid password before application will lock account Allowed values: integer value greater that 0 diff --git a/jans-auth-server/server/integrations/basic.multi_auth_conf/BasicMultiAuthConfExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/basic.multi_auth_conf/BasicMultiAuthConfExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/basic.multi_auth_conf/BasicMultiAuthConfExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.multi_auth_conf/BasicMultiAuthConfExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/basic.multi_auth_conf/INSTALLATION.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.multi_auth_conf/INSTALLATION.txt similarity index 100% rename from jans-auth-server/server/integrations/basic.multi_auth_conf/INSTALLATION.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.multi_auth_conf/INSTALLATION.txt diff --git a/jans-auth-server/server/integrations/basic.multi_auth_conf/README.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.multi_auth_conf/README.txt similarity index 100% rename from jans-auth-server/server/integrations/basic.multi_auth_conf/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.multi_auth_conf/README.txt diff --git a/jans-auth-server/server/integrations/basic.multi_login/BasicMultiLoginExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/basic.multi_login/BasicMultiLoginExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/basic.multi_login/BasicMultiLoginExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.multi_login/BasicMultiLoginExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/basic.multi_login/INSTALLATION.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.multi_login/INSTALLATION.txt similarity index 100% rename from jans-auth-server/server/integrations/basic.multi_login/INSTALLATION.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.multi_login/INSTALLATION.txt diff --git a/jans-auth-server/server/integrations/basic.multi_login/README.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.multi_login/README.txt similarity index 100% rename from jans-auth-server/server/integrations/basic.multi_login/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.multi_login/README.txt diff --git a/jans-auth-server/server/integrations/basic.multiple_test_email_addresses/BasicMultipleTestEmailAddressesExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/basic.multiple_test_email_addresses/BasicMultipleTestEmailAddressesExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/basic.multiple_test_email_addresses/BasicMultipleTestEmailAddressesExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.multiple_test_email_addresses/BasicMultipleTestEmailAddressesExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/basic.multiple_test_email_addresses/README.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.multiple_test_email_addresses/README.txt similarity index 100% rename from jans-auth-server/server/integrations/basic.multiple_test_email_addresses/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.multiple_test_email_addresses/README.txt diff --git a/jans-auth-server/server/integrations/basic.one_session/BasicOneSessionExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/basic.one_session/BasicOneSessionExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/basic.one_session/BasicOneSessionExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.one_session/BasicOneSessionExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/basic.one_session/README.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.one_session/README.txt similarity index 100% rename from jans-auth-server/server/integrations/basic.one_session/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.one_session/README.txt diff --git a/jans-auth-server/server/integrations/basic.password_expiration/PasswordExpiration.py b/jans-linux-setup/static/extension/person_authentication/other/basic.password_expiration/PasswordExpiration.py similarity index 100% rename from jans-auth-server/server/integrations/basic.password_expiration/PasswordExpiration.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.password_expiration/PasswordExpiration.py diff --git a/jans-auth-server/server/integrations/basic.password_expiration/README.md b/jans-linux-setup/static/extension/person_authentication/other/basic.password_expiration/README.md similarity index 100% rename from jans-auth-server/server/integrations/basic.password_expiration/README.md rename to jans-linux-setup/static/extension/person_authentication/other/basic.password_expiration/README.md diff --git a/jans-auth-server/server/integrations/basic.reset_to_step/BasicResetToStepExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/basic.reset_to_step/BasicResetToStepExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/basic.reset_to_step/BasicResetToStepExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/basic.reset_to_step/BasicResetToStepExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/basic.reset_to_step/README.txt b/jans-linux-setup/static/extension/person_authentication/other/basic.reset_to_step/README.txt similarity index 100% rename from jans-auth-server/server/integrations/basic.reset_to_step/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/basic.reset_to_step/README.txt diff --git a/jans-auth-server/server/integrations/bcrypt_ssha_migration/pwd_migration.py b/jans-linux-setup/static/extension/person_authentication/other/bcrypt_ssha_migration/pwd_migration.py similarity index 100% rename from jans-auth-server/server/integrations/bcrypt_ssha_migration/pwd_migration.py rename to jans-linux-setup/static/extension/person_authentication/other/bcrypt_ssha_migration/pwd_migration.py diff --git a/jans-auth-server/server/integrations/bioid/BioIDExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/bioid/BioIDExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/bioid/BioIDExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/bioid/BioIDExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/bioid/README.txt b/jans-linux-setup/static/extension/person_authentication/other/bioid/README.txt similarity index 100% rename from jans-auth-server/server/integrations/bioid/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/bioid/README.txt diff --git a/jans-auth-server/server/integrations/cas2/Cas2ExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/cas2/Cas2ExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/cas2/Cas2ExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/cas2/Cas2ExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/cas2_duo/Cas2DuoExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/cas2_duo/Cas2DuoExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/cas2_duo/Cas2DuoExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/cas2_duo/Cas2DuoExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/cas2_duo/Readme.md b/jans-linux-setup/static/extension/person_authentication/other/cas2_duo/Readme.md similarity index 100% rename from jans-auth-server/server/integrations/cas2_duo/Readme.md rename to jans-linux-setup/static/extension/person_authentication/other/cas2_duo/Readme.md diff --git a/jans-auth-server/server/integrations/cas2_duo/docs/joinded_flows.dia b/jans-linux-setup/static/extension/person_authentication/other/cas2_duo/docs/joinded_flows.dia similarity index 100% rename from jans-auth-server/server/integrations/cas2_duo/docs/joinded_flows.dia rename to jans-linux-setup/static/extension/person_authentication/other/cas2_duo/docs/joinded_flows.dia diff --git a/jans-auth-server/server/integrations/cas2_duo/docs/joinded_flows.jpg b/jans-linux-setup/static/extension/person_authentication/other/cas2_duo/docs/joinded_flows.jpg similarity index 100% rename from jans-auth-server/server/integrations/cas2_duo/docs/joinded_flows.jpg rename to jans-linux-setup/static/extension/person_authentication/other/cas2_duo/docs/joinded_flows.jpg diff --git a/jans-auth-server/server/integrations/cert/Generate certs guide.md b/jans-linux-setup/static/extension/person_authentication/other/cert/Generate certs guide.md similarity index 96% rename from jans-auth-server/server/integrations/cert/Generate certs guide.md rename to jans-linux-setup/static/extension/person_authentication/other/cert/Generate certs guide.md index 0471ae6ad58..4c3045b64b0 100644 --- a/jans-auth-server/server/integrations/cert/Generate certs guide.md +++ b/jans-linux-setup/static/extension/person_authentication/other/cert/Generate certs guide.md @@ -1,407 +1,407 @@ -For testing purpouses there is archive with CA/Intermidiate/User certs in [archive](./sample/generated_certs.zip). - -## 1. Create and sign Root CA - -### 1.1. Generate password protected a 8192-bit long SHA-256 RSA key for root CA: - -`openssl genrsa -aes256 -out rootca.key 8192` - -Example output: -``` -Generating RSA private key, 8192 bit long modulus (2 primes) -....................+++ -........................................................................................................................................................................................................................................................................................................................................................................................+++ -e is 65537 (0x010001) -Enter pass phrase for rootca.key: -Verifying - Enter pass phrase for rootca.key: -``` - -### 1.2 Create the self-signed root CA certificate ca.crt; you'll need to provide an identity for your root CA: - -`openssl req -sha256 -new -x509 -days 1826 -key rootca.key -out rootca.crt` - -Example output: -``` -Enter pass phrase for rootca.key: -You are about to be asked to enter information that will be incorporated -into your certificate request. -What you are about to enter is what is called a Distinguished Name or a DN. -There are quite a few fields but you can leave some blank -For some fields there will be a default value, -If you enter '.', the field will be left blank. ------ -Country Name (2 letter code) [AU]:US -State or Province Name (full name) [Some-State]:TX -Locality Name (eg, city) []:Austin -Organization Name (eg, company) [Internet Widgits Pty Ltd]:Gluu, Inc. -Organizational Unit Name (eg, section) []:Gluu CA -Common Name (e.g. server FQDN or YOUR name) []:Gluu Root CA -Email Address []: -``` - -### 1.3. Create `root-ca.conf` file: - -``` -[ ca ] -default_ca = gluuca - -[ crl_ext ] -issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always - -[ gluuca ] -dir = ./ -new_certs_dir = $dir -unique_subject = no -certificate = $dir/rootca.crt -database = $dir/certindex -private_key = $dir/rootca.key -serial = $dir/certserial -default_days = 730 -default_md = sha1 -policy = gluuca_policy -x509_extensions = gluuca_extensions -crlnumber = $dir/crlnumber -default_crl_days = 730 - -[ gluuca_policy ] -commonName = supplied -stateOrProvinceName = supplied -countryName = optional -emailAddress = optional -organizationName = supplied -organizationalUnitName = optional - -[ gluuca_extensions ] -basicConstraints = critical,CA:TRUE,pathlen:0 -keyUsage = critical,any -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer -keyUsage = digitalSignature,cRLSign,keyCertSign -extendedKeyUsage = serverAuth -crlDistributionPoints = @crl_section -subjectAltName = @alt_names -authorityInfoAccess = @ocsp_section - -[alt_names] -DNS.0 = Gluu Intermidiate CA 1 -DNS.1 = Gluu CA Intermidiate 1 - -[crl_section] -URI.0 = http://pki.gluu.org/GluuRoot.crl -URI.1 = http://pki.backup.com/GluuRoot.crl - -[ocsp_section] -caIssuers;URI.0 = http://pki.gluu.org/GluuRoot.crt -caIssuers;URI.1 = http://pki.backup.com/GluuRoot.crt -OCSP;URI.0 = http://pki.gluu.org/ocsp/ -OCSP;URI.1 = http://pki.backup.com/ocsp/ - -``` -### 1.4. Create a few files where the CA will store it's serials: - -``` -touch certindex -echo 1000 > certserial -echo 1000 > crlnumber -``` - -### 1.5. If you need to set a specific certificate start / expiry date, add the following to [gluuca] -``` -# format: YYYYMMDDHHMMSS -default_enddate = 20191222035911 -default_startdate = 20181222035911 -``` - -## 2. Create and sign Intermediate 1 CA - -### 2.1. Generate the intermediate CA's private key: - -`openssl genrsa -out intermediate1.key 4096` - -Example output: -``` -Generating RSA private key, 4096 bit long modulus (2 primes) -........................................................++++ -.........++++ -e is 65537 (0x010001) -``` -### 2.2. Generate the intermediate1 CA's CSR: - -`openssl req -new -sha256 -key intermediate1.key -out intermediate1.csr` - -Example output: -``` -You are about to be asked to enter information that will be incorporated -into your certificate request. -What you are about to enter is what is called a Distinguished Name or a DN. -There are quite a few fields but you can leave some blank -For some fields there will be a default value, -If you enter '.', the field will be left blank. ------ -Country Name (2 letter code) [AU]:US -State or Province Name (full name) [Some-State]:TX -Locality Name (eg, city) []:Austin -Organization Name (eg, company) [Internet Widgits Pty Ltd]:Gluu, Inc. -Organizational Unit Name (eg, section) []:Gluu CA -Common Name (e.g. server FQDN or YOUR name) []:Gluu Intermediate CA -Email Address []: - -Please enter the following 'extra' attributes -to be sent with your certificate request -A challenge password []: -An optional company name []: -``` - -### 2.3. Sign the intermediate1 CSR with the Root CA: - -`openssl ca -batch -config root-ca.conf -notext -in intermediate1.csr -out intermediate1.crt` - -Example output: -``` -Using configuration from root-ca.conf -Enter pass phrase for .//rootca.key: -Check that the request matches the signature -Signature ok -The Subject's Distinguished Name is as follows -countryName :PRINTABLE:'US' -stateOrProvinceName :ASN.1 12:'TX' -localityName :ASN.1 12:'Austin' -organizationName :ASN.1 12:'Gluu, Inc.' -organizationalUnitName:ASN.1 12:'Gluu CA' -commonName :ASN.1 12:'Gluu Intermediate CA' -Certificate is to be certified until Dec 22 07:39:24 2021 GMT (730 days) - -Write out database with 1 new entries -Data Base Updated -``` - -### 2.4. Generate the CRL (both in PEM and DER): - -``` -openssl ca -config root-ca.conf -gencrl -keyfile rootca.key -cert rootca.crt -out rootca.crl.pem -openssl crl -inform PEM -in rootca.crl.pem -outform DER -out rootca.crl -``` - -Generate the CRL after every certificate you sign with the CA. - -### 2.5. Configuring the Intermediate CA 1 - -Create a new folder for this intermediate and move in to it: - -``` -mkdir intermediate1 -cd ./intermediate1 -``` - -Copy the Intermediate cert and key from the Root CA: - -`mv ../intermediate1.* ./` - -Create the index files: - -``` -touch certindex -echo 1000 > certserial -echo 1000 > crlnumber -``` - -### 2.6. Create a new intermediate-ca.conf file: - -``` -[ ca ] -default_ca = gluuca - -[ crl_ext ] -issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always - -[ gluuca ] -dir = ./ -new_certs_dir = $dir -unique_subject = no -certificate = $dir/intermediate1.crt -database = $dir/certindex -private_key = $dir/intermediate1.key -serial = $dir/certserial -default_days = 365 -default_md = sha1 -policy = gluuca_policy -x509_extensions = gluuca_extensions -crlnumber = $dir/crlnumber -default_crl_days = 365 - -[ gluuca_policy ] -commonName = supplied -stateOrProvinceName = supplied -countryName = optional -emailAddress = optional -organizationName = supplied -organizationalUnitName = optional - -[ gluuca_extensions ] -basicConstraints = critical,CA:FALSE -keyUsage = critical,any -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer -keyUsage = digitalSignature, nonRepudiation, keyEncipherment -extendedKeyUsage = clientAuth -crlDistributionPoints = @crl_section -subjectAltName = @alt_names -authorityInfoAccess = @ocsp_section - -[alt_names] -DNS.0 = example.com -DNS.1 = example.org - -[crl_section] -URI.0 = http://pki.gluu.org/GluuIntermidiate1.crl -URI.1 = http://pki.backup.com/GluuIntermidiate1.crl - -[ocsp_section] -caIssuers;URI.0 = http://pki.gluu.org/GluuIntermediate1.crt -caIssuers;URI.1 = http://pki.backup.com/GluuIntermediate1.crt -OCSP;URI.0 = http://pki.gluu.org/ocsp/ -OCSP;URI.1 = http://pki.backup.com/ocsp/ -``` - -Change the [alt_names] section to whatever you need as Subject Alternative names. Remove it including the subjectAltName = @alt_names line if you don't want a Subject Alternative Name. - -If you need to set a specific certificate start / expiry date, add the following to [gluuca] - -``` -# format: YYYYMMDDHHMMSS -default_enddate = 20191222035911 -default_startdate = 20181222035911 -``` - -Generate an empty CRL (both in PEM and DER): - -``` -openssl ca -config intermediate-ca.conf -gencrl -keyfile intermediate1.key -cert intermediate1.crt -out intermediate1.crl.pem -openssl crl -inform PEM -in intermediate1.crl.pem -outform DER -out intermediate1.crl -``` - -### 2.7. This is sample to show how to revoke cert. Use it only when you need to revoke the intermediate cert: - -`openssl ca -config root-ca.conf -revoke intermediate1.crt -keyfile rootca.key -cert rootca.crt` - - -## 3. Creating end user certificates -We use this new intermediate CA to generate an end user certificate. Repeat these steps for every end user certificate you want to sign with this CA. - -### 3.1. Create folder for end user certs: -`mkdir enduser-certs` - -### 3.2. Generate the end user's private key: - -`openssl genrsa -out enduser-certs/user-gluu.org.key 4096` - -### 3.3. Generate the end user's CSR: - -`openssl req -new -sha256 -key enduser-certs/user-gluu.org.key -out enduser-certs/user-gluu.org.csr` - -Example output: -``` -You are about to be asked to enter information that will be incorporated -into your certificate request. -What you are about to enter is what is called a Distinguished Name or a DN. -There are quite a few fields but you can leave some blank -For some fields there will be a default value, -If you enter '.', the field will be left blank. ------ -Country Name (2 letter code) [AU]:US -State or Province Name (full name) [Some-State]:TX -Locality Name (eg, city) []:Austin -Organization Name (eg, company) [Internet Widgits Pty Ltd]:Gluu, Inc. -Organizational Unit Name (eg, section) []:User -Common Name (e.g. server FQDN or YOUR name) []:Full User Name -Email Address []: - -Please enter the following 'extra' attributes -to be sent with your certificate request -A challenge password []: -An optional company name []: -``` - -### 3.4. Sign the end user's CSR with the Intermediate 1 CA: - -`openssl ca -batch -config intermediate-ca.conf -notext -in enduser-certs/user-gluu.org.csr -out enduser-certs/user-gluu.org.crt` - -Example output: -``` -Using configuration from intermediate-ca.conf -Check that the request matches the signature -Signature ok -The Subject's Distinguished Name is as follows -countryName :PRINTABLE:'US' -stateOrProvinceName :ASN.1 12:'TX' -localityName :ASN.1 12:'Austin' -organizationName :ASN.1 12:'Gluu, Inc.' -organizationalUnitName:ASN.1 12:'User' -commonName :ASN.1 12:'Full User Name' -Certificate is to be certified until Dec 22 08:07:15 2020 GMT (365 days) - -Write out database with 1 new entries -Data Base Updated -``` - -### 3.5. Generate the CRL (both in PEM and DER): - -``` -openssl ca -config intermediate-ca.conf -gencrl -keyfile intermediate1.key -cert intermediate1.crt -out intermediate1.crl.pem -openssl crl -inform PEM -in intermediate1.crl.pem -outform DER -out intermediate1.crl -``` - -Generate the CRL after every certificate you sign with the CA. - -### 3.6. Create the certificate chain file by concatenating the Root and intermediate 1 certificates together. - -`cat ../rootca.crt intermediate1.crt > enduser-certs/user-gluu.org.chain` - -Send the following files to the end user: - -``` -user-gluu.org.crt -user-gluu.org.key -user-gluu.org.chain -``` - -You can also let the end user supply their own CSR and just send them the .crt file. Do not delete that from the server, otherwise you cannot revoke it. - -### 3.7. This is sample to show how to revoke cert. Use it only when you need to revoke the end users cert: - -`openssl ca -config intermediate-ca.conf -revoke enduser-certs/enduser-gluu.org.crt -keyfile intermediate1.key -cert intermediate1.crt` - -## 4. Validating the certificate - -### 4.1. You can validate the end user certificate against the chain using the following command: - -`openssl verify -CAfile enduser-certs/user-gluu.org.chain enduser-certs/user-gluu.org.crt` - -Example output: -``` -enduser-certs/user-gluu.org.crt: OK -``` - -### 4.2. You can also validate it against the CRL. Concatenate the PEM CRL and the chain together first: - -`cat ../rootca.crt intermediate1.crt intermediate1.crl.pem > enduser-certs/user-gluu.org.crl.chain` - -Verify the certificate: - -`openssl verify -crl_check -CAfile enduser-certs/user-gluu.org.crl.chain enduser-certs/user-gluu.org.crt` - -Example output: -``` -enduser-certs/user-gluu.org.crt: OK -``` - -### 5. Export end user certificate to PKCS#12 - -Convert a PEM certificate file and a private key to PKCS#12 (.pfx .p12) - -``` -openssl pkcs12 -export -out enduser-certs/user-gluu.org.pfx -inkey enduser-certs/user-gluu.org.key -in enduser-certs/user-gluu.org.crt -certfile enduser-certs/user-gluu.org.chain -``` - +For testing purpouses there is archive with CA/Intermidiate/User certs in [archive](./sample/generated_certs.zip). + +## 1. Create and sign Root CA + +### 1.1. Generate password protected a 8192-bit long SHA-256 RSA key for root CA: + +`openssl genrsa -aes256 -out rootca.key 8192` + +Example output: +``` +Generating RSA private key, 8192 bit long modulus (2 primes) +....................+++ +........................................................................................................................................................................................................................................................................................................................................................................................+++ +e is 65537 (0x010001) +Enter pass phrase for rootca.key: +Verifying - Enter pass phrase for rootca.key: +``` + +### 1.2 Create the self-signed root CA certificate ca.crt; you'll need to provide an identity for your root CA: + +`openssl req -sha256 -new -x509 -days 1826 -key rootca.key -out rootca.crt` + +Example output: +``` +Enter pass phrase for rootca.key: +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:TX +Locality Name (eg, city) []:Austin +Organization Name (eg, company) [Internet Widgits Pty Ltd]:Gluu, Inc. +Organizational Unit Name (eg, section) []:Gluu CA +Common Name (e.g. server FQDN or YOUR name) []:Gluu Root CA +Email Address []: +``` + +### 1.3. Create `root-ca.conf` file: + +``` +[ ca ] +default_ca = gluuca + +[ crl_ext ] +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ gluuca ] +dir = ./ +new_certs_dir = $dir +unique_subject = no +certificate = $dir/rootca.crt +database = $dir/certindex +private_key = $dir/rootca.key +serial = $dir/certserial +default_days = 730 +default_md = sha1 +policy = gluuca_policy +x509_extensions = gluuca_extensions +crlnumber = $dir/crlnumber +default_crl_days = 730 + +[ gluuca_policy ] +commonName = supplied +stateOrProvinceName = supplied +countryName = optional +emailAddress = optional +organizationName = supplied +organizationalUnitName = optional + +[ gluuca_extensions ] +basicConstraints = critical,CA:TRUE,pathlen:0 +keyUsage = critical,any +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +keyUsage = digitalSignature,cRLSign,keyCertSign +extendedKeyUsage = serverAuth +crlDistributionPoints = @crl_section +subjectAltName = @alt_names +authorityInfoAccess = @ocsp_section + +[alt_names] +DNS.0 = Gluu Intermidiate CA 1 +DNS.1 = Gluu CA Intermidiate 1 + +[crl_section] +URI.0 = http://pki.gluu.org/GluuRoot.crl +URI.1 = http://pki.backup.com/GluuRoot.crl + +[ocsp_section] +caIssuers;URI.0 = http://pki.gluu.org/GluuRoot.crt +caIssuers;URI.1 = http://pki.backup.com/GluuRoot.crt +OCSP;URI.0 = http://pki.gluu.org/ocsp/ +OCSP;URI.1 = http://pki.backup.com/ocsp/ + +``` +### 1.4. Create a few files where the CA will store it's serials: + +``` +touch certindex +echo 1000 > certserial +echo 1000 > crlnumber +``` + +### 1.5. If you need to set a specific certificate start / expiry date, add the following to [gluuca] +``` +# format: YYYYMMDDHHMMSS +default_enddate = 20191222035911 +default_startdate = 20181222035911 +``` + +## 2. Create and sign Intermediate 1 CA + +### 2.1. Generate the intermediate CA's private key: + +`openssl genrsa -out intermediate1.key 4096` + +Example output: +``` +Generating RSA private key, 4096 bit long modulus (2 primes) +........................................................++++ +.........++++ +e is 65537 (0x010001) +``` +### 2.2. Generate the intermediate1 CA's CSR: + +`openssl req -new -sha256 -key intermediate1.key -out intermediate1.csr` + +Example output: +``` +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:TX +Locality Name (eg, city) []:Austin +Organization Name (eg, company) [Internet Widgits Pty Ltd]:Gluu, Inc. +Organizational Unit Name (eg, section) []:Gluu CA +Common Name (e.g. server FQDN or YOUR name) []:Gluu Intermediate CA +Email Address []: + +Please enter the following 'extra' attributes +to be sent with your certificate request +A challenge password []: +An optional company name []: +``` + +### 2.3. Sign the intermediate1 CSR with the Root CA: + +`openssl ca -batch -config root-ca.conf -notext -in intermediate1.csr -out intermediate1.crt` + +Example output: +``` +Using configuration from root-ca.conf +Enter pass phrase for .//rootca.key: +Check that the request matches the signature +Signature ok +The Subject's Distinguished Name is as follows +countryName :PRINTABLE:'US' +stateOrProvinceName :ASN.1 12:'TX' +localityName :ASN.1 12:'Austin' +organizationName :ASN.1 12:'Gluu, Inc.' +organizationalUnitName:ASN.1 12:'Gluu CA' +commonName :ASN.1 12:'Gluu Intermediate CA' +Certificate is to be certified until Dec 22 07:39:24 2021 GMT (730 days) + +Write out database with 1 new entries +Data Base Updated +``` + +### 2.4. Generate the CRL (both in PEM and DER): + +``` +openssl ca -config root-ca.conf -gencrl -keyfile rootca.key -cert rootca.crt -out rootca.crl.pem +openssl crl -inform PEM -in rootca.crl.pem -outform DER -out rootca.crl +``` + +Generate the CRL after every certificate you sign with the CA. + +### 2.5. Configuring the Intermediate CA 1 + +Create a new folder for this intermediate and move in to it: + +``` +mkdir intermediate1 +cd ./intermediate1 +``` + +Copy the Intermediate cert and key from the Root CA: + +`mv ../intermediate1.* ./` + +Create the index files: + +``` +touch certindex +echo 1000 > certserial +echo 1000 > crlnumber +``` + +### 2.6. Create a new intermediate-ca.conf file: + +``` +[ ca ] +default_ca = gluuca + +[ crl_ext ] +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ gluuca ] +dir = ./ +new_certs_dir = $dir +unique_subject = no +certificate = $dir/intermediate1.crt +database = $dir/certindex +private_key = $dir/intermediate1.key +serial = $dir/certserial +default_days = 365 +default_md = sha1 +policy = gluuca_policy +x509_extensions = gluuca_extensions +crlnumber = $dir/crlnumber +default_crl_days = 365 + +[ gluuca_policy ] +commonName = supplied +stateOrProvinceName = supplied +countryName = optional +emailAddress = optional +organizationName = supplied +organizationalUnitName = optional + +[ gluuca_extensions ] +basicConstraints = critical,CA:FALSE +keyUsage = critical,any +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +keyUsage = digitalSignature, nonRepudiation, keyEncipherment +extendedKeyUsage = clientAuth +crlDistributionPoints = @crl_section +subjectAltName = @alt_names +authorityInfoAccess = @ocsp_section + +[alt_names] +DNS.0 = example.com +DNS.1 = example.org + +[crl_section] +URI.0 = http://pki.gluu.org/GluuIntermidiate1.crl +URI.1 = http://pki.backup.com/GluuIntermidiate1.crl + +[ocsp_section] +caIssuers;URI.0 = http://pki.gluu.org/GluuIntermediate1.crt +caIssuers;URI.1 = http://pki.backup.com/GluuIntermediate1.crt +OCSP;URI.0 = http://pki.gluu.org/ocsp/ +OCSP;URI.1 = http://pki.backup.com/ocsp/ +``` + +Change the [alt_names] section to whatever you need as Subject Alternative names. Remove it including the subjectAltName = @alt_names line if you don't want a Subject Alternative Name. + +If you need to set a specific certificate start / expiry date, add the following to [gluuca] + +``` +# format: YYYYMMDDHHMMSS +default_enddate = 20191222035911 +default_startdate = 20181222035911 +``` + +Generate an empty CRL (both in PEM and DER): + +``` +openssl ca -config intermediate-ca.conf -gencrl -keyfile intermediate1.key -cert intermediate1.crt -out intermediate1.crl.pem +openssl crl -inform PEM -in intermediate1.crl.pem -outform DER -out intermediate1.crl +``` + +### 2.7. This is sample to show how to revoke cert. Use it only when you need to revoke the intermediate cert: + +`openssl ca -config root-ca.conf -revoke intermediate1.crt -keyfile rootca.key -cert rootca.crt` + + +## 3. Creating end user certificates +We use this new intermediate CA to generate an end user certificate. Repeat these steps for every end user certificate you want to sign with this CA. + +### 3.1. Create folder for end user certs: +`mkdir enduser-certs` + +### 3.2. Generate the end user's private key: + +`openssl genrsa -out enduser-certs/user-gluu.org.key 4096` + +### 3.3. Generate the end user's CSR: + +`openssl req -new -sha256 -key enduser-certs/user-gluu.org.key -out enduser-certs/user-gluu.org.csr` + +Example output: +``` +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:TX +Locality Name (eg, city) []:Austin +Organization Name (eg, company) [Internet Widgits Pty Ltd]:Gluu, Inc. +Organizational Unit Name (eg, section) []:User +Common Name (e.g. server FQDN or YOUR name) []:Full User Name +Email Address []: + +Please enter the following 'extra' attributes +to be sent with your certificate request +A challenge password []: +An optional company name []: +``` + +### 3.4. Sign the end user's CSR with the Intermediate 1 CA: + +`openssl ca -batch -config intermediate-ca.conf -notext -in enduser-certs/user-gluu.org.csr -out enduser-certs/user-gluu.org.crt` + +Example output: +``` +Using configuration from intermediate-ca.conf +Check that the request matches the signature +Signature ok +The Subject's Distinguished Name is as follows +countryName :PRINTABLE:'US' +stateOrProvinceName :ASN.1 12:'TX' +localityName :ASN.1 12:'Austin' +organizationName :ASN.1 12:'Gluu, Inc.' +organizationalUnitName:ASN.1 12:'User' +commonName :ASN.1 12:'Full User Name' +Certificate is to be certified until Dec 22 08:07:15 2020 GMT (365 days) + +Write out database with 1 new entries +Data Base Updated +``` + +### 3.5. Generate the CRL (both in PEM and DER): + +``` +openssl ca -config intermediate-ca.conf -gencrl -keyfile intermediate1.key -cert intermediate1.crt -out intermediate1.crl.pem +openssl crl -inform PEM -in intermediate1.crl.pem -outform DER -out intermediate1.crl +``` + +Generate the CRL after every certificate you sign with the CA. + +### 3.6. Create the certificate chain file by concatenating the Root and intermediate 1 certificates together. + +`cat ../rootca.crt intermediate1.crt > enduser-certs/user-gluu.org.chain` + +Send the following files to the end user: + +``` +user-gluu.org.crt +user-gluu.org.key +user-gluu.org.chain +``` + +You can also let the end user supply their own CSR and just send them the .crt file. Do not delete that from the server, otherwise you cannot revoke it. + +### 3.7. This is sample to show how to revoke cert. Use it only when you need to revoke the end users cert: + +`openssl ca -config intermediate-ca.conf -revoke enduser-certs/enduser-gluu.org.crt -keyfile intermediate1.key -cert intermediate1.crt` + +## 4. Validating the certificate + +### 4.1. You can validate the end user certificate against the chain using the following command: + +`openssl verify -CAfile enduser-certs/user-gluu.org.chain enduser-certs/user-gluu.org.crt` + +Example output: +``` +enduser-certs/user-gluu.org.crt: OK +``` + +### 4.2. You can also validate it against the CRL. Concatenate the PEM CRL and the chain together first: + +`cat ../rootca.crt intermediate1.crt intermediate1.crl.pem > enduser-certs/user-gluu.org.crl.chain` + +Verify the certificate: + +`openssl verify -crl_check -CAfile enduser-certs/user-gluu.org.crl.chain enduser-certs/user-gluu.org.crt` + +Example output: +``` +enduser-certs/user-gluu.org.crt: OK +``` + +### 5. Export end user certificate to PKCS#12 + +Convert a PEM certificate file and a private key to PKCS#12 (.pfx .p12) + +``` +openssl pkcs12 -export -out enduser-certs/user-gluu.org.pfx -inkey enduser-certs/user-gluu.org.key -in enduser-certs/user-gluu.org.crt -certfile enduser-certs/user-gluu.org.chain +``` + diff --git a/jans-auth-server/server/integrations/cert/Generate certs without configs.md b/jans-linux-setup/static/extension/person_authentication/other/cert/Generate certs without configs.md similarity index 100% rename from jans-auth-server/server/integrations/cert/Generate certs without configs.md rename to jans-linux-setup/static/extension/person_authentication/other/cert/Generate certs without configs.md diff --git a/jans-auth-server/server/integrations/cert/Quick certs guide for testing.md b/jans-linux-setup/static/extension/person_authentication/other/cert/Quick certs guide for testing.md similarity index 100% rename from jans-auth-server/server/integrations/cert/Quick certs guide for testing.md rename to jans-linux-setup/static/extension/person_authentication/other/cert/Quick certs guide for testing.md diff --git a/jans-auth-server/server/integrations/cert/README.txt b/jans-linux-setup/static/extension/person_authentication/other/cert/README.txt similarity index 78% rename from jans-auth-server/server/integrations/cert/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/cert/README.txt index b24c3a0ed61..a241987c709 100644 --- a/jans-auth-server/server/integrations/cert/README.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/cert/README.txt @@ -1,4 +1,6 @@ -This is a person authentication module for oxAuth that enables user Certificate Authentication. +Script contents [here](https://github.com/JanssenProject/jans/jans-linux-setup/static/extension/person_authentication/UserCertExternalAuthenticator.py) + +This is a person authentication script for jans-auth-server that enables user Certificate Authentication. The module has a few properties: diff --git a/jans-auth-server/server/integrations/cert/docs/Cert design.dia b/jans-linux-setup/static/extension/person_authentication/other/cert/docs/Cert design.dia similarity index 100% rename from jans-auth-server/server/integrations/cert/docs/Cert design.dia rename to jans-linux-setup/static/extension/person_authentication/other/cert/docs/Cert design.dia diff --git a/jans-auth-server/server/integrations/cert/docs/Cert design.jpg b/jans-linux-setup/static/extension/person_authentication/other/cert/docs/Cert design.jpg similarity index 100% rename from jans-auth-server/server/integrations/cert/docs/Cert design.jpg rename to jans-linux-setup/static/extension/person_authentication/other/cert/docs/Cert design.jpg diff --git a/jans-auth-server/server/integrations/cert/sample/cert_creds.json b/jans-linux-setup/static/extension/person_authentication/other/cert/sample/cert_creds.json similarity index 100% rename from jans-auth-server/server/integrations/cert/sample/cert_creds.json rename to jans-linux-setup/static/extension/person_authentication/other/cert/sample/cert_creds.json diff --git a/jans-auth-server/server/integrations/cert/sample/generated_certs.zip b/jans-linux-setup/static/extension/person_authentication/other/cert/sample/generated_certs.zip similarity index 100% rename from jans-auth-server/server/integrations/cert/sample/generated_certs.zip rename to jans-linux-setup/static/extension/person_authentication/other/cert/sample/generated_certs.zip diff --git a/jans-auth-server/server/integrations/ciba/FirebaseEndUserNotification.py b/jans-linux-setup/static/extension/person_authentication/other/ciba/FirebaseEndUserNotification.py similarity index 100% rename from jans-auth-server/server/integrations/ciba/FirebaseEndUserNotification.py rename to jans-linux-setup/static/extension/person_authentication/other/ciba/FirebaseEndUserNotification.py diff --git a/jans-auth-server/server/integrations/compromised_password/compromised_password.py b/jans-linux-setup/static/extension/person_authentication/other/compromised_password/compromised_password.py similarity index 100% rename from jans-auth-server/server/integrations/compromised_password/compromised_password.py rename to jans-linux-setup/static/extension/person_authentication/other/compromised_password/compromised_password.py diff --git a/jans-auth-server/server/integrations/compromised_password/readme.txt b/jans-linux-setup/static/extension/person_authentication/other/compromised_password/readme.txt similarity index 98% rename from jans-auth-server/server/integrations/compromised_password/readme.txt rename to jans-linux-setup/static/extension/person_authentication/other/compromised_password/readme.txt index d2165db7e86..c40a14ac6ab 100644 --- a/jans-auth-server/server/integrations/compromised_password/readme.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/compromised_password/readme.txt @@ -1,7 +1,7 @@ -This is a person authentication module for oxAuth to verify if user password has been compromised and allows user to change password immediately after providing answer to secret question set by admin. - -1) credentials_file = /etc/certs/vericloud_gluu_creds.json -2) secret_question = Set this parameter for the question to be disaplayed to user -3) secret_answer = Set this parameter for the answer to be provided by user to reset password - +This is a person authentication module for oxAuth to verify if user password has been compromised and allows user to change password immediately after providing answer to secret question set by admin. + +1) credentials_file = /etc/certs/vericloud_gluu_creds.json +2) secret_question = Set this parameter for the question to be disaplayed to user +3) secret_answer = Set this parameter for the answer to be provided by user to reset password + Update vericloud_gluu_creds.json file with Vericloud API username and secret \ No newline at end of file diff --git a/jans-auth-server/server/integrations/custom_registration/Attributes.json b/jans-linux-setup/static/extension/person_authentication/other/custom_registration/Attributes.json similarity index 100% rename from jans-auth-server/server/integrations/custom_registration/Attributes.json rename to jans-linux-setup/static/extension/person_authentication/other/custom_registration/Attributes.json diff --git a/jans-auth-server/server/integrations/custom_registration/README.md b/jans-linux-setup/static/extension/person_authentication/other/custom_registration/README.md similarity index 100% rename from jans-auth-server/server/integrations/custom_registration/README.md rename to jans-linux-setup/static/extension/person_authentication/other/custom_registration/README.md diff --git a/jans-auth-server/server/integrations/custom_registration/reg.xhtml b/jans-linux-setup/static/extension/person_authentication/other/custom_registration/reg.xhtml similarity index 100% rename from jans-auth-server/server/integrations/custom_registration/reg.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/custom_registration/reg.xhtml diff --git a/jans-auth-server/server/integrations/custom_registration/register.py b/jans-linux-setup/static/extension/person_authentication/other/custom_registration/register.py similarity index 100% rename from jans-auth-server/server/integrations/custom_registration/register.py rename to jans-linux-setup/static/extension/person_authentication/other/custom_registration/register.py diff --git a/jans-auth-server/server/integrations/duo/README.txt b/jans-linux-setup/static/extension/person_authentication/other/duo/README.txt similarity index 82% rename from jans-auth-server/server/integrations/duo/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/duo/README.txt index 0ece14531eb..501f8f6586d 100644 --- a/jans-auth-server/server/integrations/duo/README.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/duo/README.txt @@ -1,4 +1,6 @@ -This is a person authentication module for oxAuth that enables [Duo Authentication](https://www.duosecurity.com) for user authentication. +Script contents [here](https://github.com/JanssenProject/jans/jans-linux-setup/static/extension/person_authentication/DuoExternalAuthenticator.py) + +This is a person authentication script for jans-auth-server which enables [Duo Authentication](https://www.duosecurity.com) for user authentication. The module has a few properties: diff --git a/jans-auth-server/server/integrations/forgot_password/README.md b/jans-linux-setup/static/extension/person_authentication/other/forgot_password/README.md similarity index 100% rename from jans-auth-server/server/integrations/forgot_password/README.md rename to jans-linux-setup/static/extension/person_authentication/other/forgot_password/README.md diff --git a/jans-auth-server/server/integrations/forgot_password/forgot_password.py b/jans-linux-setup/static/extension/person_authentication/other/forgot_password/forgot_password.py similarity index 100% rename from jans-auth-server/server/integrations/forgot_password/forgot_password.py rename to jans-linux-setup/static/extension/person_authentication/other/forgot_password/forgot_password.py diff --git a/jans-auth-server/server/integrations/fortinet/FortinetExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/fortinet/FortinetExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/fortinet/FortinetExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/fortinet/FortinetExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/fortinet/README.txt b/jans-linux-setup/static/extension/person_authentication/other/fortinet/README.txt similarity index 100% rename from jans-auth-server/server/integrations/fortinet/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/fortinet/README.txt diff --git a/jans-auth-server/server/integrations/gplus/GooglePlusExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/gplus/GooglePlusExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/gplus/GooglePlusExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/gplus/GooglePlusExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/gplus/README.txt b/jans-linux-setup/static/extension/person_authentication/other/gplus/README.txt similarity index 100% rename from jans-auth-server/server/integrations/gplus/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/gplus/README.txt diff --git a/jans-auth-server/server/integrations/gplus/sample/custom_script_entry.ldif b/jans-linux-setup/static/extension/person_authentication/other/gplus/sample/custom_script_entry.ldif similarity index 100% rename from jans-auth-server/server/integrations/gplus/sample/custom_script_entry.ldif rename to jans-linux-setup/static/extension/person_authentication/other/gplus/sample/custom_script_entry.ldif diff --git a/jans-auth-server/server/integrations/gplus/sample/gplus_client_secrets.json b/jans-linux-setup/static/extension/person_authentication/other/gplus/sample/gplus_client_secrets.json similarity index 100% rename from jans-auth-server/server/integrations/gplus/sample/gplus_client_secrets.json rename to jans-linux-setup/static/extension/person_authentication/other/gplus/sample/gplus_client_secrets.json diff --git a/jans-auth-server/server/integrations/gplus/workflow.txt b/jans-linux-setup/static/extension/person_authentication/other/gplus/workflow.txt similarity index 100% rename from jans-auth-server/server/integrations/gplus/workflow.txt rename to jans-linux-setup/static/extension/person_authentication/other/gplus/workflow.txt diff --git a/jans-auth-server/server/integrations/idfirst/README_idfirst.md b/jans-linux-setup/static/extension/person_authentication/other/idfirst/README_idfirst.md similarity index 100% rename from jans-auth-server/server/integrations/idfirst/README_idfirst.md rename to jans-linux-setup/static/extension/person_authentication/other/idfirst/README_idfirst.md diff --git a/jans-auth-server/server/integrations/idfirst/alter_login.xhtml b/jans-linux-setup/static/extension/person_authentication/other/idfirst/alter_login.xhtml similarity index 100% rename from jans-auth-server/server/integrations/idfirst/alter_login.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/idfirst/alter_login.xhtml diff --git a/jans-auth-server/server/integrations/idfirst/idfirst.py b/jans-linux-setup/static/extension/person_authentication/other/idfirst/idfirst.py similarity index 100% rename from jans-auth-server/server/integrations/idfirst/idfirst.py rename to jans-linux-setup/static/extension/person_authentication/other/idfirst/idfirst.py diff --git a/jans-auth-server/server/integrations/idfirst/idfirst_login.xhtml b/jans-linux-setup/static/extension/person_authentication/other/idfirst/idfirst_login.xhtml similarity index 100% rename from jans-auth-server/server/integrations/idfirst/idfirst_login.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/idfirst/idfirst_login.xhtml diff --git a/jans-auth-server/server/integrations/inwebo/inwebo.py b/jans-linux-setup/static/extension/person_authentication/other/inwebo/inwebo.py similarity index 100% rename from jans-auth-server/server/integrations/inwebo/inwebo.py rename to jans-linux-setup/static/extension/person_authentication/other/inwebo/inwebo.py diff --git a/jans-auth-server/server/integrations/inwebo/iw_creds.json b/jans-linux-setup/static/extension/person_authentication/other/inwebo/iw_creds.json similarity index 100% rename from jans-auth-server/server/integrations/inwebo/iw_creds.json rename to jans-linux-setup/static/extension/person_authentication/other/inwebo/iw_creds.json diff --git a/jans-auth-server/server/integrations/inwebo/iw_va.xhtml b/jans-linux-setup/static/extension/person_authentication/other/inwebo/iw_va.xhtml similarity index 100% rename from jans-auth-server/server/integrations/inwebo/iw_va.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/inwebo/iw_va.xhtml diff --git a/jans-auth-server/server/integrations/inwebo/iwauthenticate.xhtml b/jans-linux-setup/static/extension/person_authentication/other/inwebo/iwauthenticate.xhtml similarity index 100% rename from jans-auth-server/server/integrations/inwebo/iwauthenticate.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/inwebo/iwauthenticate.xhtml diff --git a/jans-auth-server/server/integrations/inwebo/iwlogin.xhtml b/jans-linux-setup/static/extension/person_authentication/other/inwebo/iwlogin.xhtml similarity index 100% rename from jans-auth-server/server/integrations/inwebo/iwlogin.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/inwebo/iwlogin.xhtml diff --git a/jans-auth-server/server/integrations/inwebo/iwlogin_without_password.xhtml b/jans-linux-setup/static/extension/person_authentication/other/inwebo/iwlogin_without_password.xhtml similarity index 100% rename from jans-auth-server/server/integrations/inwebo/iwlogin_without_password.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/inwebo/iwlogin_without_password.xhtml diff --git a/jans-auth-server/server/integrations/inwebo/iwpushnotification.xhtml b/jans-linux-setup/static/extension/person_authentication/other/inwebo/iwpushnotification.xhtml similarity index 100% rename from jans-auth-server/server/integrations/inwebo/iwpushnotification.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/inwebo/iwpushnotification.xhtml diff --git a/jans-auth-server/server/integrations/inwebo/oxauth.properties b/jans-linux-setup/static/extension/person_authentication/other/inwebo/oxauth.properties similarity index 100% rename from jans-auth-server/server/integrations/inwebo/oxauth.properties rename to jans-linux-setup/static/extension/person_authentication/other/inwebo/oxauth.properties diff --git a/jans-auth-server/server/integrations/obconnect/UpdateToken.py b/jans-linux-setup/static/extension/person_authentication/other/obconnect/UpdateToken.py similarity index 100% rename from jans-auth-server/server/integrations/obconnect/UpdateToken.py rename to jans-linux-setup/static/extension/person_authentication/other/obconnect/UpdateToken.py diff --git a/jans-auth-server/server/integrations/obconnect/documentation/README.txt b/jans-linux-setup/static/extension/person_authentication/other/obconnect/documentation/README.txt similarity index 100% rename from jans-auth-server/server/integrations/obconnect/documentation/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/obconnect/documentation/README.txt diff --git a/jans-auth-server/server/integrations/obconnect/documentation/larger_picture.png b/jans-linux-setup/static/extension/person_authentication/other/obconnect/documentation/larger_picture.png similarity index 100% rename from jans-auth-server/server/integrations/obconnect/documentation/larger_picture.png rename to jans-linux-setup/static/extension/person_authentication/other/obconnect/documentation/larger_picture.png diff --git a/jans-auth-server/server/integrations/obconnect/obconnectExternalAuthentication.py b/jans-linux-setup/static/extension/person_authentication/other/obconnect/obconnectExternalAuthentication.py similarity index 100% rename from jans-auth-server/server/integrations/obconnect/obconnectExternalAuthentication.py rename to jans-linux-setup/static/extension/person_authentication/other/obconnect/obconnectExternalAuthentication.py diff --git a/jans-auth-server/server/integrations/obconnect/redirect.xhtml b/jans-linux-setup/static/extension/person_authentication/other/obconnect/redirect.xhtml similarity index 100% rename from jans-auth-server/server/integrations/obconnect/redirect.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/obconnect/redirect.xhtml diff --git a/jans-auth-server/server/integrations/oneid/oneidlogin.xhtml b/jans-linux-setup/static/extension/person_authentication/other/oneid/oneidlogin.xhtml similarity index 100% rename from jans-auth-server/server/integrations/oneid/oneidlogin.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/oneid/oneidlogin.xhtml diff --git a/jans-auth-server/server/integrations/oneid/oneidpostlogin.xhtml b/jans-linux-setup/static/extension/person_authentication/other/oneid/oneidpostlogin.xhtml similarity index 100% rename from jans-auth-server/server/integrations/oneid/oneidpostlogin.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/oneid/oneidpostlogin.xhtml diff --git a/jans-auth-server/server/integrations/otp/Properties description.md b/jans-linux-setup/static/extension/person_authentication/other/otp/Properties description.md similarity index 63% rename from jans-auth-server/server/integrations/otp/Properties description.md rename to jans-linux-setup/static/extension/person_authentication/other/otp/Properties description.md index 0b59d26045d..6e89b62ea40 100644 --- a/jans-auth-server/server/integrations/otp/Properties description.md +++ b/jans-linux-setup/static/extension/person_authentication/other/otp/Properties description.md @@ -1,4 +1,6 @@ -This is a person authentication module for oxAuth that enables one-time password for user authentication. +Script contents [here](https://github.com/JanssenProject/jans/jans-linux-setup/static/extension/person_authentication/OtpExternalAuthenticator.py) + +This is a person authentication script for jans-auth-server which enables one-time password for user authentication. The module has a few properties: @@ -7,17 +9,17 @@ The module has a few properties: Example: hotp 2) issuer - It's mandatory property. It's company name. - Example: Gluu Inc + Example: Janssen Inc 3) otp_conf_file - It's mandatory property. It's specify path to OTP configuration JSON file. Example: /etc/certs/otp_configuration.json 4) label - It's label inside QR code. It's optional property. - Example: Gluu OTP + Example: Janssen OTP 5) qr_options - Specify width and height of QR image. It's optional property. Example: qr_options: { width: 400, height: 400 } 6) registration_uri - It's URL to page where user can register new account. It's optional property. - Example: https://ce-dev.gluu.org/identity/register + Example: https://ce-dev.jans.org/identity/register \ No newline at end of file diff --git a/jans-auth-server/server/integrations/otp/img/gluu_otp_integration_authentication_workflow.png b/jans-linux-setup/static/extension/person_authentication/other/otp/img/gluu_otp_integration_authentication_workflow.png similarity index 100% rename from jans-auth-server/server/integrations/otp/img/gluu_otp_integration_authentication_workflow.png rename to jans-linux-setup/static/extension/person_authentication/other/otp/img/gluu_otp_integration_authentication_workflow.png diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/_remote.repositories b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/_remote.repositories similarity index 98% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/_remote.repositories rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/_remote.repositories index 7d24ce56ef1..095939909cc 100644 --- a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/_remote.repositories +++ b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/_remote.repositories @@ -1,6 +1,6 @@ -#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. -#Mon Sep 26 13:13:34 MSK 2016 -oath-otp-keyprovisioning-0.0.1-SNAPSHOT.pom>= -oath-otp-keyprovisioning-0.0.1-SNAPSHOT-javadoc.jar>= -oath-otp-keyprovisioning-0.0.1-SNAPSHOT.jar>= -oath-otp-keyprovisioning-0.0.1-SNAPSHOT-sources.jar>= +#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. +#Mon Sep 26 13:13:34 MSK 2016 +oath-otp-keyprovisioning-0.0.1-SNAPSHOT.pom>= +oath-otp-keyprovisioning-0.0.1-SNAPSHOT-javadoc.jar>= +oath-otp-keyprovisioning-0.0.1-SNAPSHOT.jar>= +oath-otp-keyprovisioning-0.0.1-SNAPSHOT-sources.jar>= diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/maven-metadata-local.xml b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/maven-metadata-local.xml diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT-javadoc.jar b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT-javadoc.jar similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT-javadoc.jar rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT-javadoc.jar diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT-sources.jar b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT-sources.jar similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT-sources.jar rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT-sources.jar diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT.jar b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT.jar similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT.jar rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT.jar diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT.pom b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT.pom similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT.pom rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/0.0.1-SNAPSHOT/oath-otp-keyprovisioning-0.0.1-SNAPSHOT.pom diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/maven-metadata-local.xml b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/maven-metadata-local.xml similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/maven-metadata-local.xml rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp-keyprovisioning/maven-metadata-local.xml diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/_remote.repositories b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/_remote.repositories similarity index 97% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/_remote.repositories rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/_remote.repositories index 5eafaf6270f..865f16cf7b5 100644 --- a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/_remote.repositories +++ b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/_remote.repositories @@ -1,6 +1,6 @@ -#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. -#Mon Sep 26 13:13:32 MSK 2016 -oath-otp-0.0.1-SNAPSHOT.jar>= -oath-otp-0.0.1-SNAPSHOT-sources.jar>= -oath-otp-0.0.1-SNAPSHOT.pom>= -oath-otp-0.0.1-SNAPSHOT-javadoc.jar>= +#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. +#Mon Sep 26 13:13:32 MSK 2016 +oath-otp-0.0.1-SNAPSHOT.jar>= +oath-otp-0.0.1-SNAPSHOT-sources.jar>= +oath-otp-0.0.1-SNAPSHOT.pom>= +oath-otp-0.0.1-SNAPSHOT-javadoc.jar>= diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/maven-metadata-local.xml b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/maven-metadata-local.xml diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT-javadoc.jar b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT-javadoc.jar similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT-javadoc.jar rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT-javadoc.jar diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT-sources.jar b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT-sources.jar similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT-sources.jar rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT-sources.jar diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.jar b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.jar similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.jar rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.jar diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.pom b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.pom similarity index 97% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.pom rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.pom index ad165d3b8c0..624ebdcc397 100644 --- a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.pom +++ b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/0.0.1-SNAPSHOT/oath-otp-0.0.1-SNAPSHOT.pom @@ -1,19 +1,19 @@ - - 4.0.0 - - com.lochbridge.oath - oath-parent - 0.0.1-SNAPSHOT - - oath-otp - OATH OTP - A module for generating and validating OTPs. - - - - com.google.guava - guava - - + + 4.0.0 + + com.lochbridge.oath + oath-parent + 0.0.1-SNAPSHOT + + oath-otp + OATH OTP + A module for generating and validating OTPs. + + + + com.google.guava + guava + + \ No newline at end of file diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/maven-metadata-local.xml b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/maven-metadata-local.xml similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-otp/maven-metadata-local.xml rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-otp/maven-metadata-local.xml diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/_remote.repositories b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/_remote.repositories similarity index 98% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/_remote.repositories rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/_remote.repositories index 766175c8d64..d0af97df1ca 100644 --- a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/_remote.repositories +++ b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/_remote.repositories @@ -1,3 +1,3 @@ -#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. -#Mon Sep 26 13:13:30 MSK 2016 -oath-parent-0.0.1-SNAPSHOT.pom>= +#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. +#Mon Sep 26 13:13:30 MSK 2016 +oath-parent-0.0.1-SNAPSHOT.pom>= diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/maven-metadata-local.xml b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/maven-metadata-local.xml diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/oath-parent-0.0.1-SNAPSHOT.pom b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/oath-parent-0.0.1-SNAPSHOT.pom similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/oath-parent-0.0.1-SNAPSHOT.pom rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/0.0.1-SNAPSHOT/oath-parent-0.0.1-SNAPSHOT.pom diff --git a/jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/maven-metadata-local.xml b/jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/maven-metadata-local.xml similarity index 100% rename from jans-auth-server/server/integrations/otp/repository/com/lochbridge/oath/oath-parent/maven-metadata-local.xml rename to jans-linux-setup/static/extension/person_authentication/other/otp/repository/com/lochbridge/oath/oath-parent/maven-metadata-local.xml diff --git a/jans-auth-server/server/integrations/otp/sample/otp_configuration.json b/jans-linux-setup/static/extension/person_authentication/other/otp/sample/otp_configuration.json similarity index 100% rename from jans-auth-server/server/integrations/otp/sample/otp_configuration.json rename to jans-linux-setup/static/extension/person_authentication/other/otp/sample/otp_configuration.json diff --git a/jans-auth-server/server/integrations/otp/sequence_diagram.txt b/jans-linux-setup/static/extension/person_authentication/other/otp/sequence_diagram.txt similarity index 100% rename from jans-auth-server/server/integrations/otp/sequence_diagram.txt rename to jans-linux-setup/static/extension/person_authentication/other/otp/sequence_diagram.txt diff --git a/jans-auth-server/server/integrations/passport/PassportExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/passport/PassportExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/passport/PassportExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/passport/PassportExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/passport/README.md b/jans-linux-setup/static/extension/person_authentication/other/passport/README.md similarity index 100% rename from jans-auth-server/server/integrations/passport/README.md rename to jans-linux-setup/static/extension/person_authentication/other/passport/README.md diff --git a/jans-auth-server/server/integrations/passport/sample/passport_script_entry.ldif b/jans-linux-setup/static/extension/person_authentication/other/passport/sample/passport_script_entry.ldif similarity index 100% rename from jans-auth-server/server/integrations/passport/sample/passport_script_entry.ldif rename to jans-linux-setup/static/extension/person_authentication/other/passport/sample/passport_script_entry.ldif diff --git a/jans-auth-server/server/integrations/phonefactor/pflogin.xhtml b/jans-linux-setup/static/extension/person_authentication/other/phonefactor/pflogin.xhtml similarity index 100% rename from jans-auth-server/server/integrations/phonefactor/pflogin.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/phonefactor/pflogin.xhtml diff --git a/jans-auth-server/server/integrations/postauthn/postauthn.py b/jans-linux-setup/static/extension/person_authentication/other/postauthn/postauthn.py similarity index 100% rename from jans-auth-server/server/integrations/postauthn/postauthn.py rename to jans-linux-setup/static/extension/person_authentication/other/postauthn/postauthn.py diff --git a/jans-auth-server/server/integrations/registration/read.txt b/jans-linux-setup/static/extension/person_authentication/other/registration/read.txt similarity index 98% rename from jans-auth-server/server/integrations/registration/read.txt rename to jans-linux-setup/static/extension/person_authentication/other/registration/read.txt index ba84fcee1b7..d3b048deb0b 100644 --- a/jans-auth-server/server/integrations/registration/read.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/registration/read.txt @@ -1,6 +1,6 @@ -This is a person authentication module for oxAuth that allows user to register first and login to server. - -Required Custom property (key/value) - -1) generic_register_attributes_list = email,fname,lname,email,phone,pwd -2) generic_local_attributes_list = uid,givenName,sn,mail,telephoneNumber,userPassword - +This is a person authentication module for oxAuth that allows user to register first and login to server. + +Required Custom property (key/value) - +1) generic_register_attributes_list = email,fname,lname,email,phone,pwd +2) generic_local_attributes_list = uid,givenName,sn,mail,telephoneNumber,userPassword + diff --git a/jans-auth-server/server/integrations/registration/register.py b/jans-linux-setup/static/extension/person_authentication/other/registration/register.py similarity index 100% rename from jans-auth-server/server/integrations/registration/register.py rename to jans-linux-setup/static/extension/person_authentication/other/registration/register.py diff --git a/jans-auth-server/server/integrations/saml-passport/SamlPassportAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/saml-passport/SamlPassportAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/saml-passport/SamlPassportAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/saml-passport/SamlPassportAuthenticator.py diff --git a/jans-auth-server/server/integrations/saml/Gluu Inbound SAML Design (no Session).png b/jans-linux-setup/static/extension/person_authentication/other/saml/Gluu Inbound SAML Design (no Session).png similarity index 100% rename from jans-auth-server/server/integrations/saml/Gluu Inbound SAML Design (no Session).png rename to jans-linux-setup/static/extension/person_authentication/other/saml/Gluu Inbound SAML Design (no Session).png diff --git a/jans-auth-server/server/integrations/saml/INSTALLATION.txt b/jans-linux-setup/static/extension/person_authentication/other/saml/INSTALLATION.txt similarity index 100% rename from jans-auth-server/server/integrations/saml/INSTALLATION.txt rename to jans-linux-setup/static/extension/person_authentication/other/saml/INSTALLATION.txt diff --git a/jans-auth-server/server/integrations/saml/README.txt b/jans-linux-setup/static/extension/person_authentication/other/saml/README.txt similarity index 100% rename from jans-auth-server/server/integrations/saml/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/saml/README.txt diff --git a/jans-auth-server/server/integrations/saml/SamlExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/saml/SamlExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/saml/SamlExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/saml/SamlExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar.md5 b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar.md5 similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar.md5 rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar.md5 diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar.sha1 b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar.sha1 similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar.sha1 rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.jar.sha1 diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom.md5 b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom.md5 similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom.md5 rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom.md5 diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom.sha1 b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom.sha1 similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom.sha1 rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/1.0.1.gluu/gcm-server-1.0.1.gluu.pom.sha1 diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml.md5 b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml.md5 similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml.md5 rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml.md5 diff --git a/jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml.sha1 b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml.sha1 similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml.sha1 rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/repository/com/google/gcm/gcm-server/maven-metadata.xml.sha1 diff --git a/jans-auth-server/server/integrations/super_gluu/sample/super_gluu_creds.json b/jans-linux-setup/static/extension/person_authentication/other/super_gluu/sample/super_gluu_creds.json similarity index 100% rename from jans-auth-server/server/integrations/super_gluu/sample/super_gluu_creds.json rename to jans-linux-setup/static/extension/person_authentication/other/super_gluu/sample/super_gluu_creds.json diff --git a/jans-auth-server/server/integrations/toopher/tpauthenticate.xhtml b/jans-linux-setup/static/extension/person_authentication/other/toopher/tpauthenticate.xhtml similarity index 100% rename from jans-auth-server/server/integrations/toopher/tpauthenticate.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/toopher/tpauthenticate.xhtml diff --git a/jans-auth-server/server/integrations/toopher/tppair.xhtml b/jans-linux-setup/static/extension/person_authentication/other/toopher/tppair.xhtml similarity index 100% rename from jans-auth-server/server/integrations/toopher/tppair.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/toopher/tppair.xhtml diff --git a/jans-auth-server/server/integrations/twilio_sms/README.txt b/jans-linux-setup/static/extension/person_authentication/other/twilio_sms/README.txt similarity index 68% rename from jans-auth-server/server/integrations/twilio_sms/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/twilio_sms/README.txt index 3ca0409d359..aa5463138bc 100644 --- a/jans-auth-server/server/integrations/twilio_sms/README.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/twilio_sms/README.txt @@ -4,4 +4,5 @@ This is a two step authentication workflow. The first step is standard username against the local Gluu Server LDAP. The second step requires the person to enter a code that is sent via SMS to the person's mobile number. -See all details at https://gluu.org/docs/ce/authn-guide/sms-otp/ +Script contents [here](https://github.com/JanssenProject/jans/jans-linux-setup/static/extension/person_authentication/twilio2FA.py) + diff --git a/jans-auth-server/server/integrations/uaf/Properties description.md b/jans-linux-setup/static/extension/person_authentication/other/uaf/Properties description.md similarity index 62% rename from jans-auth-server/server/integrations/uaf/Properties description.md rename to jans-linux-setup/static/extension/person_authentication/other/uaf/Properties description.md index 5c7e6385c1b..eb33c3d9ad4 100644 --- a/jans-auth-server/server/integrations/uaf/Properties description.md +++ b/jans-linux-setup/static/extension/person_authentication/other/uaf/Properties description.md @@ -1,9 +1,11 @@ -This is a person authentication module for oxAuth that enables [UAF](https://www.noknok.com) for user authentication. +Script contents [here](/home/jgomer/gluu/git-projects/jans/jans-linux-setup/static/extension/person_authentication/UafExternalAuthenticator.py) + +This is a person authentication script for jans-auth-server that enables [UAF](https://www.noknok.com) for user authentication. The module has a few properties: 1) uaf_server_uri - It's mandatory property. It's URL to UAF server. - Example: https://ce-dev.gluu.org + Example: https://ce-dev.jans.org 2) uaf_policy_name - Specify UAF policy name. It's optional property. Example: default @@ -14,7 +16,7 @@ The module has a few properties: Example: false 4) registration_uri - It's URL to page where user can register new account. It's optional property. - Example: https://ce-dev.gluu.org/identity/register + Example: https://ce-dev.jans.org/identity/register 5) qr_options - Specify width and height of QR image. It's optional property. Example: qr_options: { width: 400, height: 400 } diff --git a/jans-auth-server/server/integrations/uaf/UafExternalAuthenticator.py b/jans-linux-setup/static/extension/person_authentication/other/uaf/UafExternalAuthenticator.py similarity index 100% rename from jans-auth-server/server/integrations/uaf/UafExternalAuthenticator.py rename to jans-linux-setup/static/extension/person_authentication/other/uaf/UafExternalAuthenticator.py diff --git a/jans-auth-server/server/integrations/uaf/img/gluu_uaf_integration_authentication_workflow.png b/jans-linux-setup/static/extension/person_authentication/other/uaf/img/gluu_uaf_integration_authentication_workflow.png similarity index 100% rename from jans-auth-server/server/integrations/uaf/img/gluu_uaf_integration_authentication_workflow.png rename to jans-linux-setup/static/extension/person_authentication/other/uaf/img/gluu_uaf_integration_authentication_workflow.png diff --git a/jans-auth-server/server/integrations/uaf/img/oob_qr_code.png b/jans-linux-setup/static/extension/person_authentication/other/uaf/img/oob_qr_code.png similarity index 100% rename from jans-auth-server/server/integrations/uaf/img/oob_qr_code.png rename to jans-linux-setup/static/extension/person_authentication/other/uaf/img/oob_qr_code.png diff --git a/jans-auth-server/server/integrations/uaf/img/typical_uaf_architecture.png b/jans-linux-setup/static/extension/person_authentication/other/uaf/img/typical_uaf_architecture.png similarity index 100% rename from jans-auth-server/server/integrations/uaf/img/typical_uaf_architecture.png rename to jans-linux-setup/static/extension/person_authentication/other/uaf/img/typical_uaf_architecture.png diff --git a/jans-auth-server/server/integrations/uaf/img/uaf_device_integration_models.png b/jans-linux-setup/static/extension/person_authentication/other/uaf/img/uaf_device_integration_models.png similarity index 100% rename from jans-auth-server/server/integrations/uaf/img/uaf_device_integration_models.png rename to jans-linux-setup/static/extension/person_authentication/other/uaf/img/uaf_device_integration_models.png diff --git a/jans-auth-server/server/integrations/uaf/sequence_diagram.txt b/jans-linux-setup/static/extension/person_authentication/other/uaf/sequence_diagram.txt similarity index 100% rename from jans-auth-server/server/integrations/uaf/sequence_diagram.txt rename to jans-linux-setup/static/extension/person_authentication/other/uaf/sequence_diagram.txt diff --git a/jans-auth-server/server/integrations/wikid/wikidlogin.xhtml b/jans-linux-setup/static/extension/person_authentication/other/wikid/wikidlogin.xhtml similarity index 100% rename from jans-auth-server/server/integrations/wikid/wikidlogin.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/wikid/wikidlogin.xhtml diff --git a/jans-auth-server/server/integrations/wikid/wikidregister.xhtml b/jans-linux-setup/static/extension/person_authentication/other/wikid/wikidregister.xhtml similarity index 100% rename from jans-auth-server/server/integrations/wikid/wikidregister.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/wikid/wikidregister.xhtml diff --git a/jans-auth-server/server/integrations/wwpass/INSTALLATION.md b/jans-linux-setup/static/extension/person_authentication/other/wwpass/INSTALLATION.md similarity index 100% rename from jans-auth-server/server/integrations/wwpass/INSTALLATION.md rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/INSTALLATION.md diff --git a/jans-auth-server/server/integrations/wwpass/README.md b/jans-linux-setup/static/extension/person_authentication/other/wwpass/README.md similarity index 100% rename from jans-auth-server/server/integrations/wwpass/README.md rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/README.md diff --git a/jans-auth-server/server/integrations/wwpass/pages/auth/wwpass/checkemail.xhtml b/jans-linux-setup/static/extension/person_authentication/other/wwpass/pages/auth/wwpass/checkemail.xhtml similarity index 100% rename from jans-auth-server/server/integrations/wwpass/pages/auth/wwpass/checkemail.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/pages/auth/wwpass/checkemail.xhtml diff --git a/jans-auth-server/server/integrations/wwpass/pages/auth/wwpass/wwpass.xhtml b/jans-linux-setup/static/extension/person_authentication/other/wwpass/pages/auth/wwpass/wwpass.xhtml similarity index 100% rename from jans-auth-server/server/integrations/wwpass/pages/auth/wwpass/wwpass.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/pages/auth/wwpass/wwpass.xhtml diff --git a/jans-auth-server/server/integrations/wwpass/pages/auth/wwpass/wwpassbind.xhtml b/jans-linux-setup/static/extension/person_authentication/other/wwpass/pages/auth/wwpass/wwpassbind.xhtml similarity index 100% rename from jans-auth-server/server/integrations/wwpass/pages/auth/wwpass/wwpassbind.xhtml rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/pages/auth/wwpass/wwpassbind.xhtml diff --git a/jans-auth-server/server/integrations/wwpass/static/js/wwpass-frontend.js b/jans-linux-setup/static/extension/person_authentication/other/wwpass/static/js/wwpass-frontend.js similarity index 99% rename from jans-auth-server/server/integrations/wwpass/static/js/wwpass-frontend.js rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/static/js/wwpass-frontend.js index 5f9361f808b..aeb1d82d55a 100644 --- a/jans-auth-server/server/integrations/wwpass/static/js/wwpass-frontend.js +++ b/jans-linux-setup/static/extension/person_authentication/other/wwpass/static/js/wwpass-frontend.js @@ -2823,138 +2823,138 @@ var maskPattern_6 = maskPattern.applyMask; var maskPattern_7 = maskPattern.getBestMask; - var EC_BLOCKS_TABLE = [ - // L M Q H - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 2, 2, - 1, 2, 2, 4, - 1, 2, 4, 4, - 2, 4, 4, 4, - 2, 4, 6, 5, - 2, 4, 6, 6, - 2, 5, 8, 8, - 4, 5, 8, 8, - 4, 5, 8, 11, - 4, 8, 10, 11, - 4, 9, 12, 16, - 4, 9, 16, 16, - 6, 10, 12, 18, - 6, 10, 17, 16, - 6, 11, 16, 19, - 6, 13, 18, 21, - 7, 14, 21, 25, - 8, 16, 20, 25, - 8, 17, 23, 25, - 9, 17, 23, 34, - 9, 18, 25, 30, - 10, 20, 27, 32, - 12, 21, 29, 35, - 12, 23, 34, 37, - 12, 25, 34, 40, - 13, 26, 35, 42, - 14, 28, 38, 45, - 15, 29, 40, 48, - 16, 31, 43, 51, - 17, 33, 45, 54, - 18, 35, 48, 57, - 19, 37, 51, 60, - 19, 38, 53, 63, - 20, 40, 56, 66, - 21, 43, 59, 70, - 22, 45, 62, 74, - 24, 47, 65, 77, - 25, 49, 68, 81 - ]; - - var EC_CODEWORDS_TABLE = [ - // L M Q H - 7, 10, 13, 17, - 10, 16, 22, 28, - 15, 26, 36, 44, - 20, 36, 52, 64, - 26, 48, 72, 88, - 36, 64, 96, 112, - 40, 72, 108, 130, - 48, 88, 132, 156, - 60, 110, 160, 192, - 72, 130, 192, 224, - 80, 150, 224, 264, - 96, 176, 260, 308, - 104, 198, 288, 352, - 120, 216, 320, 384, - 132, 240, 360, 432, - 144, 280, 408, 480, - 168, 308, 448, 532, - 180, 338, 504, 588, - 196, 364, 546, 650, - 224, 416, 600, 700, - 224, 442, 644, 750, - 252, 476, 690, 816, - 270, 504, 750, 900, - 300, 560, 810, 960, - 312, 588, 870, 1050, - 336, 644, 952, 1110, - 360, 700, 1020, 1200, - 390, 728, 1050, 1260, - 420, 784, 1140, 1350, - 450, 812, 1200, 1440, - 480, 868, 1290, 1530, - 510, 924, 1350, 1620, - 540, 980, 1440, 1710, - 570, 1036, 1530, 1800, - 570, 1064, 1590, 1890, - 600, 1120, 1680, 1980, - 630, 1204, 1770, 2100, - 660, 1260, 1860, 2220, - 720, 1316, 1950, 2310, - 750, 1372, 2040, 2430 - ]; - - /** - * Returns the number of error correction block that the QR Code should contain - * for the specified version and error correction level. - * - * @param {Number} version QR Code version - * @param {Number} errorCorrectionLevel Error correction level - * @return {Number} Number of error correction blocks - */ - var getBlocksCount = function getBlocksCount (version, errorCorrectionLevel$1) { - switch (errorCorrectionLevel$1) { - case errorCorrectionLevel.L: - return EC_BLOCKS_TABLE[(version - 1) * 4 + 0] - case errorCorrectionLevel.M: - return EC_BLOCKS_TABLE[(version - 1) * 4 + 1] - case errorCorrectionLevel.Q: - return EC_BLOCKS_TABLE[(version - 1) * 4 + 2] - case errorCorrectionLevel.H: - return EC_BLOCKS_TABLE[(version - 1) * 4 + 3] - default: - return undefined - } - }; - - /** - * Returns the number of error correction codewords to use for the specified - * version and error correction level. - * - * @param {Number} version QR Code version - * @param {Number} errorCorrectionLevel Error correction level - * @return {Number} Number of error correction codewords - */ - var getTotalCodewordsCount = function getTotalCodewordsCount (version, errorCorrectionLevel$1) { - switch (errorCorrectionLevel$1) { - case errorCorrectionLevel.L: - return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0] - case errorCorrectionLevel.M: - return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1] - case errorCorrectionLevel.Q: - return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2] - case errorCorrectionLevel.H: - return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3] - default: - return undefined - } + var EC_BLOCKS_TABLE = [ + // L M Q H + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 2, 2, + 1, 2, 2, 4, + 1, 2, 4, 4, + 2, 4, 4, 4, + 2, 4, 6, 5, + 2, 4, 6, 6, + 2, 5, 8, 8, + 4, 5, 8, 8, + 4, 5, 8, 11, + 4, 8, 10, 11, + 4, 9, 12, 16, + 4, 9, 16, 16, + 6, 10, 12, 18, + 6, 10, 17, 16, + 6, 11, 16, 19, + 6, 13, 18, 21, + 7, 14, 21, 25, + 8, 16, 20, 25, + 8, 17, 23, 25, + 9, 17, 23, 34, + 9, 18, 25, 30, + 10, 20, 27, 32, + 12, 21, 29, 35, + 12, 23, 34, 37, + 12, 25, 34, 40, + 13, 26, 35, 42, + 14, 28, 38, 45, + 15, 29, 40, 48, + 16, 31, 43, 51, + 17, 33, 45, 54, + 18, 35, 48, 57, + 19, 37, 51, 60, + 19, 38, 53, 63, + 20, 40, 56, 66, + 21, 43, 59, 70, + 22, 45, 62, 74, + 24, 47, 65, 77, + 25, 49, 68, 81 + ]; + + var EC_CODEWORDS_TABLE = [ + // L M Q H + 7, 10, 13, 17, + 10, 16, 22, 28, + 15, 26, 36, 44, + 20, 36, 52, 64, + 26, 48, 72, 88, + 36, 64, 96, 112, + 40, 72, 108, 130, + 48, 88, 132, 156, + 60, 110, 160, 192, + 72, 130, 192, 224, + 80, 150, 224, 264, + 96, 176, 260, 308, + 104, 198, 288, 352, + 120, 216, 320, 384, + 132, 240, 360, 432, + 144, 280, 408, 480, + 168, 308, 448, 532, + 180, 338, 504, 588, + 196, 364, 546, 650, + 224, 416, 600, 700, + 224, 442, 644, 750, + 252, 476, 690, 816, + 270, 504, 750, 900, + 300, 560, 810, 960, + 312, 588, 870, 1050, + 336, 644, 952, 1110, + 360, 700, 1020, 1200, + 390, 728, 1050, 1260, + 420, 784, 1140, 1350, + 450, 812, 1200, 1440, + 480, 868, 1290, 1530, + 510, 924, 1350, 1620, + 540, 980, 1440, 1710, + 570, 1036, 1530, 1800, + 570, 1064, 1590, 1890, + 600, 1120, 1680, 1980, + 630, 1204, 1770, 2100, + 660, 1260, 1860, 2220, + 720, 1316, 1950, 2310, + 750, 1372, 2040, 2430 + ]; + + /** + * Returns the number of error correction block that the QR Code should contain + * for the specified version and error correction level. + * + * @param {Number} version QR Code version + * @param {Number} errorCorrectionLevel Error correction level + * @return {Number} Number of error correction blocks + */ + var getBlocksCount = function getBlocksCount (version, errorCorrectionLevel$1) { + switch (errorCorrectionLevel$1) { + case errorCorrectionLevel.L: + return EC_BLOCKS_TABLE[(version - 1) * 4 + 0] + case errorCorrectionLevel.M: + return EC_BLOCKS_TABLE[(version - 1) * 4 + 1] + case errorCorrectionLevel.Q: + return EC_BLOCKS_TABLE[(version - 1) * 4 + 2] + case errorCorrectionLevel.H: + return EC_BLOCKS_TABLE[(version - 1) * 4 + 3] + default: + return undefined + } + }; + + /** + * Returns the number of error correction codewords to use for the specified + * version and error correction level. + * + * @param {Number} version QR Code version + * @param {Number} errorCorrectionLevel Error correction level + * @return {Number} Number of error correction codewords + */ + var getTotalCodewordsCount = function getTotalCodewordsCount (version, errorCorrectionLevel$1) { + switch (errorCorrectionLevel$1) { + case errorCorrectionLevel.L: + return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0] + case errorCorrectionLevel.M: + return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1] + case errorCorrectionLevel.Q: + return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2] + case errorCorrectionLevel.H: + return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3] + default: + return undefined + } }; var errorCorrectionCode = { diff --git a/jans-auth-server/server/integrations/wwpass/ticket.json b/jans-linux-setup/static/extension/person_authentication/other/wwpass/ticket.json similarity index 100% rename from jans-auth-server/server/integrations/wwpass/ticket.json rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/ticket.json diff --git a/jans-auth-server/server/integrations/wwpass/wwpass.ca.crt b/jans-linux-setup/static/extension/person_authentication/other/wwpass/wwpass.ca.crt similarity index 100% rename from jans-auth-server/server/integrations/wwpass/wwpass.ca.crt rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/wwpass.ca.crt diff --git a/jans-auth-server/server/integrations/wwpass/wwpass.py b/jans-linux-setup/static/extension/person_authentication/other/wwpass/wwpass.py similarity index 100% rename from jans-auth-server/server/integrations/wwpass/wwpass.py rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/wwpass.py diff --git a/jans-auth-server/server/integrations/wwpass/wwpassauth.py b/jans-linux-setup/static/extension/person_authentication/other/wwpass/wwpassauth.py similarity index 100% rename from jans-auth-server/server/integrations/wwpass/wwpassauth.py rename to jans-linux-setup/static/extension/person_authentication/other/wwpass/wwpassauth.py diff --git a/jans-auth-server/server/integrations/yubicloud/README.txt b/jans-linux-setup/static/extension/person_authentication/other/yubicloud/README.txt similarity index 90% rename from jans-auth-server/server/integrations/yubicloud/README.txt rename to jans-linux-setup/static/extension/person_authentication/other/yubicloud/README.txt index eea4807b5ef..8859a6937c2 100644 --- a/jans-auth-server/server/integrations/yubicloud/README.txt +++ b/jans-linux-setup/static/extension/person_authentication/other/yubicloud/README.txt @@ -1,6 +1,8 @@ Yubicloud OTP Validataion ========================= +Script contents [here](https://github.com/JanssenProject/jans/jans-linux-setup/static/extension/person_authentication/YubicloudExternalAuthenticator.py) + This is a single step authentication workflow. Instead of a human entering a password, Yubico's Yubikey OTP will be taken in as password. diff --git a/jans-linux-setup/static/extension/person_authentication/smpp2FA.py b/jans-linux-setup/static/extension/person_authentication/smpp2FA.py index 666e31e7570..6bf40569ca2 100644 --- a/jans-linux-setup/static/extension/person_authentication/smpp2FA.py +++ b/jans-linux-setup/static/extension/person_authentication/smpp2FA.py @@ -1,5 +1,5 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2018, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # Copyright (c) 2019, Tele2 # Author: Jose Gonzalez @@ -15,8 +15,9 @@ from io.jans.model.custom.script.type.auth import PersonAuthenticationType from io.jans.as.server.service import AuthenticationService from io.jans.as.server.service import UserService -from io.jans.as.util import ServerUtil -from io.jans.util import StringHelper, ArrayHelper +from io.jans.as.server.util import ServerUtil +from io.jans.util import ArrayHelper +from io.jans.util import StringHelper from javax.faces.application import FacesMessage from io.jans.jsf2.message import FacesMessages diff --git a/jans-linux-setup/static/extension/person_authentication/twilio2FA.py b/jans-linux-setup/static/extension/person_authentication/twilio2FA.py index 5d0ad5f5735..84ce8072d92 100644 --- a/jans-linux-setup/static/extension/person_authentication/twilio2FA.py +++ b/jans-linux-setup/static/extension/person_authentication/twilio2FA.py @@ -1,7 +1,6 @@ -# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. -# Copyright (c) 2018, Janssen +# Janssen Project software is available under the Apache 2.0 License (2004). See http://www.apache.org/licenses/ for full text. +# Copyright (c) 2020, Janssen Project # -# Author: Jose Gonzalez # Author: Gasmyr Mougang from io.jans.service.cdi.util import CdiUtil @@ -10,8 +9,9 @@ from io.jans.as.server.service import AuthenticationService from io.jans.as.server.service import UserService from io.jans.as.server.service import SessionIdService -from io.jans.as.util import ServerUtil -from io.jans.util import StringHelper, ArrayHelper +from io.jans.as.server.util import ServerUtil +from io.jans.util import StringHelper +from io.jans.util import ArrayHelper from java.util import Arrays from javax.faces.application import FacesMessage from io.jans.jsf2.message import FacesMessages