Java tutorial
/* * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.wso2.carbon.identity.authenticator.wikid; import org.apache.commons.lang.StringUtils; import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException; import org.wso2.carbon.identity.application.authentication.framework.exception.InvalidCredentialsException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; import org.wso2.carbon.identity.application.authenticator.oidc.OpenIDConnectAuthenticator; import org.wso2.carbon.identity.application.authentication.framework.FederatedApplicationAuthenticator; import org.wso2.carbon.identity.application.common.model.Property; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.*; import java.lang.String; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.security.*; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Authenticator of WiKID */ public class WiKIDAuthenticator extends OpenIDConnectAuthenticator implements FederatedApplicationAuthenticator { private static Log log = LogFactory.getLog(WiKIDAuthenticator.class); /** * Check whether the authentication or logout request can be handled by the authenticator */ public boolean canHandle(HttpServletRequest request) { if (log.isDebugEnabled()) { log.debug("Inside WiKIDAuthenticator canHandle method"); } return (StringUtils.isNotEmpty(request.getParameter(WiKIDAuthenticatorConstants.WIKID_REGISTRATION_CODE)) && StringUtils.isNotEmpty(request.getParameter(WiKIDAuthenticatorConstants.WIKID_USER_ID))); } /** * Initiate the authentication request */ @Override protected void initiateAuthenticationRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws AuthenticationFailedException { try { Map<String, String> authenticatorProperties = context.getAuthenticatorProperties(); String username = authenticatorProperties.get(WiKIDAuthenticatorConstants.WIKID_USERNAME); String password = authenticatorProperties.get(WiKIDAuthenticatorConstants.WIKID_PASSWORD); if (StringUtils.isNotEmpty(username) && StringUtils.isNotEmpty(password)) { if (StringUtils.isEmpty(login(username, password))) { log.error("Invalid username or password"); throw new AuthenticationFailedException("Invalid username or password"); } else { String retryParam = ""; if (context.isRetrying()) { retryParam = WiKIDAuthenticatorConstants.RETRY_PARAMS; } String wikidPage = ConfigurationFacade.getInstance().getAuthenticationEndpointURL().replace( WiKIDAuthenticatorConstants.LOGIN_PAGE, WiKIDAuthenticatorConstants.WIKID_PAGE); String queryParams = FrameworkUtils.getQueryStringWithFrameworkContextId( context.getQueryParams(), context.getCallerSessionKey(), context.getContextIdentifier()); response.sendRedirect(response.encodeRedirectURL(wikidPage + ("?" + queryParams)) + WiKIDAuthenticatorConstants.AUTHENTICATORS + getName() + ":" + WiKIDAuthenticatorConstants.LOCAL + "&" + retryParam); } } else { if (log.isDebugEnabled()) { log.debug("Error while retrieving properties. WiKID username and password cannot be null"); } throw new AuthenticationFailedException( "Error while retrieving properties. WiKID username and password cannot be null"); } } catch (IOException e) { throw new AuthenticationFailedException("Exception while redirecting the page: " + e.getMessage(), e); } } /** * Process the response of the WiKID end-point */ @Override protected void processAuthenticationResponse(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws AuthenticationFailedException { String regCode = request.getParameter(WiKIDAuthenticatorConstants.WIKID_REGISTRATION_CODE); String userId = request.getParameter(WiKIDAuthenticatorConstants.WIKID_USER_ID); if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(regCode)) { log.error("Registration Code and User ID cannot not be null"); throw new InvalidCredentialsException("Registration Code and User ID cannot not be null"); } else { String deviceMapId = getDeviceMapId(regCode); if (StringUtils.isNotEmpty(deviceMapId)) { String validateUserResponse = validateUser(regCode, deviceMapId, userId); if (StringUtils.isNotEmpty(validateUserResponse)) { AuthenticatedUser authenticatedUser = AuthenticatedUser .createFederateAuthenticatedUserFromSubjectIdentifier(userId); authenticatedUser.setUserName(userId); context.setSubject(authenticatedUser); } else { log.error("Unable to validate the user"); throw new AuthenticationFailedException("Unable to validate the user"); } } else { log.error("Unable to find device map id"); throw new AuthenticationFailedException("Unable to find device map id"); } } } private String login(String username, String password) { String successMessage = "Current Statistics:"; String urlToLogin = WiKIDAuthenticatorConstants.WIKID_ENDPOINT + WiKIDAuthenticatorConstants.WIKID_LOGIN_ENDPOINT; String loginResponse = sendRESTCall(urlToLogin, WiKIDAuthenticatorConstants.WIKID_USERNAME + "=" + username + "&" + WiKIDAuthenticatorConstants.WIKID_PASSWORD + "=" + password, "", WiKIDAuthenticatorConstants.HTTP_POST); if (!loginResponse.startsWith(WiKIDAuthenticatorConstants.FAILED) && loginResponse.contains(successMessage)) { return WiKIDAuthenticatorConstants.SUCCESS; } return null; } private String getDeviceMapId(String regCode) { String urlToGetAllPreRegisteredUsers = WiKIDAuthenticatorConstants.WIKID_ENDPOINT + WiKIDAuthenticatorConstants.WIKID_VALIDATION_ENDPOINT; String preRegisteredUsersResponse = sendRESTCall(urlToGetAllPreRegisteredUsers, "", "", WiKIDAuthenticatorConstants.HTTP_GET); if (!preRegisteredUsersResponse.startsWith(WiKIDAuthenticatorConstants.FAILED)) { return preRegisteredUsersResponse.substring( preRegisteredUsersResponse.indexOf(WiKIDAuthenticatorConstants.WIKID_REGISTRATION_CODE + "=" + regCode + "&" + WiKIDAuthenticatorConstants.WIKID_DEVICE_MAP_ID + "="), preRegisteredUsersResponse.indexOf("\">" + regCode)); } return null; } private String validateUser(String regCode, String deviceMapId, String userId) { String successMessage = "UserID " + userId + "Registered."; String urlToValidateUser = WiKIDAuthenticatorConstants.MAILING_ENDPOINT + WiKIDAuthenticatorConstants.WIKID_VALIDATION_ENDPOINT; String validateUserResponse = sendRESTCall(urlToValidateUser, WiKIDAuthenticatorConstants.WIKID_ACTION + "=" + WiKIDAuthenticatorConstants.WIKID_ACTION_REGISTER + "&" + WiKIDAuthenticatorConstants.WIKID_REGISTRATION_CODE + "=" + regCode + "&" + WiKIDAuthenticatorConstants.WIKID_DEVICE_MAP_ID + "=" + deviceMapId + "&" + WiKIDAuthenticatorConstants.WIKID_USER_ID + "=" + userId, "", WiKIDAuthenticatorConstants.HTTP_POST); if (!validateUserResponse.startsWith(WiKIDAuthenticatorConstants.FAILED) || validateUserResponse.contains(successMessage)) { return WiKIDAuthenticatorConstants.SUCCESS; } return null; } /** * Send REST call */ private String sendRESTCall(String url, String urlParameters, String formParameters, String httpMethod) { String line; StringBuilder responseString = new StringBuilder(); HttpsURLConnection connection = null; try { setHttpsClientCert( "/media/sf_SharedFoldersToVBox/is-connectors/wikid/wikid-authenticator/org.wso2.carbon.identity.authenticator/src/main/resources/localhostWiKID", "shakila"); SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); URL wikidEP = new URL(url + urlParameters); connection = (HttpsURLConnection) wikidEP.openConnection(); connection.setSSLSocketFactory(sslsocketfactory); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestMethod(httpMethod); connection.setRequestProperty(WiKIDAuthenticatorConstants.HTTP_CONTENT_TYPE, WiKIDAuthenticatorConstants.HTTP_CONTENT_TYPE_XWFUE); if (httpMethod.toUpperCase().equals(WiKIDAuthenticatorConstants.HTTP_POST)) { OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), WiKIDAuthenticatorConstants.CHARSET); writer.write(formParameters); writer.close(); } if (connection.getResponseCode() == 200) { BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); while ((line = br.readLine()) != null) { responseString.append(line); } br.close(); } else { return WiKIDAuthenticatorConstants.FAILED + WiKIDAuthenticatorConstants.REQUEST_FAILED; } } catch (ProtocolException e) { if (log.isDebugEnabled()) { log.debug(WiKIDAuthenticatorConstants.FAILED + e.getMessage()); } return WiKIDAuthenticatorConstants.FAILED + e.getMessage(); } catch (MalformedURLException e) { if (log.isDebugEnabled()) { log.debug(WiKIDAuthenticatorConstants.FAILED + e.getMessage()); } return WiKIDAuthenticatorConstants.FAILED + e.getMessage(); } catch (IOException e) { if (log.isDebugEnabled()) { log.debug(WiKIDAuthenticatorConstants.FAILED + e.getMessage()); } return WiKIDAuthenticatorConstants.FAILED + e.getMessage(); } finally { connection.disconnect(); } return responseString.toString(); } public static void setHttpsClientCert(String certificateFile, String certPassword) { try { if (certificateFile == null || !new File(certificateFile).exists()) { return; } KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); KeyStore keyStore = KeyStore.getInstance("PKCS12"); InputStream keyInput = new FileInputStream(certificateFile); keyStore.load(keyInput, certPassword.toCharArray()); keyInput.close(); keyManagerFactory.init(keyStore, certPassword.toCharArray()); SSLContext context = SSLContext.getInstance("TLS"); context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom()); SSLContext.setDefault(context); } catch (KeyStoreException e) { } catch (NoSuchAlgorithmException e) { } catch (FileNotFoundException e) { } catch (IOException e) { } catch (CertificateException e) { } catch (UnrecoverableKeyException e) { } catch (KeyManagementException e) { } } /** * Get WiKID endpoint. */ protected String getEndpoint() { return WiKIDAuthenticatorConstants.WIKID_ENDPOINT; } /** * Check ID token in WiKID OAuth. */ @Override protected boolean requiredIDToken(Map<String, String> authenticatorProperties) { return false; } /** * Get the friendly name of the Authenticator */ @Override public String getFriendlyName() { return WiKIDAuthenticatorConstants.AUTHENTICATOR_FRIENDLY_NAME; } /** * Get the name of the Authenticator */ @Override public String getName() { return WiKIDAuthenticatorConstants.AUTHENTICATOR_NAME; } @Override protected boolean retryAuthenticationEnabled() { return true; } /** * Get Configuration Properties */ @Override public List<Property> getConfigurationProperties() { List<Property> configProperties = new ArrayList<Property>(); Property userName = new Property(); userName.setName(WiKIDAuthenticatorConstants.WIKID_USERNAME); userName.setRequired(true); userName.setDisplayName("Username"); userName.setDescription("Enter username of WiKID server"); userName.setDisplayOrder(0); configProperties.add(userName); Property password = new Property(); password.setName(WiKIDAuthenticatorConstants.WIKID_PASSWORD); userName.setRequired(true); userName.setConfidential(true); password.setDisplayName("Password"); password.setDescription("Enter the password of WiKID server"); password.setDisplayOrder(1); configProperties.add(password); return configProperties; } }