Authenticate .Net Webapp with ADFS
miniOrange provides a ready to use solution for .Net web application. Log in to your .Net web application with ADFS or any other social or enterprise credential store.

.Net Webapp with ADFS using miniOrange


Follow the Step-by-Step Guide given below to integrate your .Net web app with ADFS.

Step 1: Create ADFS as Identity Source in miniOrange

Step 2: Configure miniOrange as relying party in ADFS

Step 3: Creating an external app in miniOrange

Step 4: Integrate sample code in your .Net Webapp

Creating the Authentication Request token

Pre-requisites:
Customer Key – for creating the final Endpoint URL
App Secret – for creating the token
Customer Token Key – for encrypting the generated token

Creating the Request token:
The request token must be in the following format:{Current_Timestamp_In_Milliseconds}:{App_Secret}
For example:1454392823570:abcdefghijklmnop
NOTE: Each Token is valid for 60 seconds.

When the token is created, you will need to encrypt the token value using the Customer Token Key. Use the following method to encrypt the token:
Encryption method: AES
Operation Mode: ECB
Padding Scheme: PKCS5 Padding

You can refer to sample code for few languages-
protected void SSORedirect_Click(object sender, EventArgs e) { DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); long milliseconds = (long) (DateTime.UtcNow - Jan1st1970).TotalMilliseconds; String username = Session["currentUser"]; String appSecret = "Enter app secret noted from miniOrange admin console"; String token = milliseconds + ":" + username + ":" + appSecret; String encryptedToken = encrypt(token); String customerId = "<YOUR_CUSTOMER_KEY>"; encryptedToken = HttpUtility.UrlEncode(encryptedToken); Response.Redirect("http://localhost:8080/broker/login/http/"+ customerId + "?token=" + encryptedToken ); } private string encrypt(string value) { AesManaged tdes = new AesManaged(); String encryptionKey = "<YOUR_TOKEN_KEY>"; tdes.Key = Encoding.UTF8.GetBytes(encryptionKey); tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform crypt = tdes.CreateEncryptor(); byte[] plain = Encoding.UTF8.GetBytes(value); byte[] cipher = crypt.TransformFinalBlock(plain, 0, plain.Length); return Convert.ToBase64String(cipher); }

public void ssoRedirect(HttpServletRequest request, HttpServletResponse response) { Long timestamp = System.currentTimeMillis(); String username = request().getSession().getAttribute("currentUser"); String appSecret = "Enter app secret noted from miniOrange admin console"; String token = timestamp + ":" + username + ":" + appSecret; String encryptedToken = encrypt(token); String customerId = "<YOUR_CUSTOMER_KEY>"; encryptedToken = URLEncoder.encode(encryptedToken, "UTF-8"); response.sendRedirect("http://localhost:8080/broker/login/http/"+ customerId + "?token=" + encryptedToken ); } private String encrypt(String value) throws Exception { String encryptionKey = "<YOUR_TOKEN_KEY>"; AesCipherService service = new AesCipherService(); service.setMode(OperationMode.ECB); service.setPaddingScheme(PaddingScheme.PKCS5); ByteSource byteSource = service.encrypt(data.getBytes(), key.getBytes()); return byteSource.toBase64(); }

public function ssoRedirect($value){ $timestamp = round( microtime(true) * 1000 ); $username = $_SESSION['currentUser']; $app_secret = "Enter app secret noted from miniOrange admin console"; $token = number_format($timestamp, 0, '', ''). ':' .$username . ':' . $app_secret; $encryptedToken = encrypt($token); $encryptedToken = urlencode( $token_params_encode ); $customerId = "<YOUR_CUSTOMER_KEY>"; $redirectURL = "http://localhost:8080/broker/login/http/". customerId ."?token=" . encryptedToken; header('Location: '.$redirectURL); } private function encrypt($token){ $encryption_key = "<YOUR_TOKEN_KEY>"; $blocksize = 16; $pad = $blocksize - ( strlen( $token ) % $blocksize ); $token = $token . str_repeat( chr( $pad ), $pad ); $token_params_encrypt = mcrypt_encrypt( MCRYPT_RIJNDAEL_128,$encryption_key, $token, MCRYPT_MODE_ECB ); return base64_encode( $token_params_encrypt ); }

If the Customer Token Key used to encrypt the above token is: klmnopqrstuvwxyz
The encrypted value for the above mentioned token should be:PJm8sn7Q1BYjdu7nXLAoATJOwuCecSxFeEz2MJzQShc=

Once the encrypted token is created, URL encode the encrypted token and append it to the miniOrange endpoint and redirect the user. Here is the final URL where you should redirect the user:
http://localhost:8080/broker/login/http/{YOUR_CUSTOMER_KEY}?token=PJm8sn7Q1BYjdu7nXLAoATJOwuCecSxFeEz2MJzQShc%3D
Replace {YOUR_CUSTOMER_KEY} with the Customer Key you have.

Receiving and Verifying the Encrypted token in your .Net Webapp

//receive the http post request from miniOrange protected void Page_Load(object sender, EventArgs e) { String status = Request["STATUS"]; if (status != null && status.Contains("SUCCESS")) { String username = Request["NameID"]; if (username != null && username != "") { username = decryptUser(username); Session["currentUser"] = username; } } } private String decryptUser(String encryptedUser){ String encryptionKey = "<YOUR_TOKEN_KEY>"; byte[] encryptedUserBytes = Convert.FromBase64String(encryptedUser); AesManaged tdes = new AesManaged(); tdes.Key = Encoding.UTF8.GetBytes(encryptionKey); tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform crypt = tdes.CreateDecryptor(); byte[] cipher = crypt.TransformFinalBlock(encryptedUserBytes, 0, encryptedUserBytes.Length); return Encoding.UTF8.GetString(cipher); }

//receive the http post request from miniOrange public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String status = request.getParameter("STATUS"); if (status != null && StringUtils.equals(status, "SUCCESS")) { String username = request.getParameter("NameID"); if (username != null && username != "") { try { username = decryptUser(username); response.getSession().setAttribute("currentUser", username); response.sendRedirect(); } catch (Exception e) { e.printStackTrace(); return; } } } } private String decryptUser(String encryptedUser){ String encryptionKey = "<YOUR_TOKEN_KEY>"; byte[] base64decoded = Base64.decodeBase64(encryptedUser.getBytes()); AesCipherService decryptService = new AesCipherService(); decryptService.setMode(OperationMode.ECB); decryptService.setPaddingScheme(PaddingScheme.PKCS5); ByteSource decrypt = decryptService.decrypt(base64decoded, key.getBytes()); return new String(decrypt.getBytes()); }

//receive the http post request from miniOrange public function getSSOUser() { $status = $_POST['STATUS']; if (status != null && strcmp(status, "SUCCESS")) { $username = $_POST['NameID']; if ( $username != null && $username != "") { try { $username = decryptUser($username); $_SESSION["currentUser"] = $username; } catch (Exception $e) { exit; } } } } private function decryptUser($encryptedUser){ $encryption_key = "<YOUR_TOKEN_KEY>"; $strIn = base64_decode($encryptedUser); $plainText = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $strIn, MCRYPT_MODE_ECB); $pad = ord($plainText{strlen($plainText) - 1}); if ($pad > strlen($plainText)) return false; if (strspn($plainText,$plainText{strlen($plainText) - 1}, strlen($plainText) - $pad) != $pad) { return false; } return substr($plainText, 0, -1 * $pad); }