private AADOAuth2AccessToken ReadOAuthTokenCookie(HttpContextBase context) { var request = context.Request; // read oauthtoken cookie var cookies = request.Cookies; var strb = new StringBuilder(); int index = 0; while (true) { var cookieName = OAuthTokenCookie; if (index > 0) { cookieName += index.ToString(CultureInfo.InvariantCulture); } var cookie = cookies[cookieName]; if (cookie == null) { break; } strb.Append(cookie.Value); ++index; } if (strb.Length == 0) { return null; } var bytes = Convert.FromBase64String(strb.ToString()); var oauthToken = DecodeCookie(bytes); if (oauthToken == null || !oauthToken.IsValid()) { try { if (oauthToken != null) { oauthToken = AADOAuth2AccessToken.GetAccessTokenByRefreshToken(oauthToken.TenantId, oauthToken.refresh_token, oauthToken.resource); } } catch (Exception) { oauthToken = null; } if (oauthToken == null) { RemoveSessionCookie(context); return null; } WriteOAuthTokenCookie(context, oauthToken); } return oauthToken; }
private byte[] EncodeCookie(AADOAuth2AccessToken token) { var bytes = token.ToBytes(); for (int i = 0; i < DefaultCookieTransforms.Length; ++i) { bytes = DefaultCookieTransforms[i].Encode(bytes); } return bytes; }
private AADOAuth2AccessToken DecodeCookie(byte[] bytes) { try { for (int i = DefaultCookieTransforms.Length - 1; i >= 0; --i) { bytes = DefaultCookieTransforms[i].Decode(bytes); } return AADOAuth2AccessToken.FromBytes(bytes); } catch (Exception) { // bad cookie return null; } }
private void WriteOAuthTokenCookie(HttpContextBase context, AADOAuth2AccessToken oauthToken) { var request = context.Request; var response = context.Response; var bytes = EncodeCookie(oauthToken); var cookie = Convert.ToBase64String(bytes); var chunkCount = cookie.Length / CookieChunkSize + (cookie.Length % CookieChunkSize == 0 ? 0 : 1); for (int i = 0; i < chunkCount; ++i) { var setCookie = new StringBuilder(); setCookie.Append(OAuthTokenCookie); if (i > 0) { setCookie.Append(i.ToString(CultureInfo.InvariantCulture)); } setCookie.Append('='); int startIndex = i * CookieChunkSize; setCookie.Append(cookie.Substring(startIndex, Math.Min(CookieChunkSize, cookie.Length - startIndex))); setCookie.Append("; path=/; secure; HttpOnly"); response.Headers.Add("Set-Cookie", setCookie.ToString()); } var cookies = request.Cookies; var index = chunkCount; while (true) { var cookieName = OAuthTokenCookie; if (index > 0) { cookieName += index.ToString(CultureInfo.InvariantCulture); } if (cookies[cookieName] == null) { break; } // remove old cookie response.Headers.Add("Set-Cookie", String.Format(DeleteCookieFormat, cookieName)); ++index; } }
private bool AuthenticateUser(string credentials, out AADOAuth2AccessToken token) { token = null; try { var encoding = Encoding.GetEncoding("iso-8859-1"); credentials = encoding.GetString(Convert.FromBase64String(credentials)); int separator = credentials.IndexOf(':'); string name = credentials.Substring(0, separator); string password = credentials.Substring(separator + 1); if (NetworkHelper.IsValidDomainUser(name, password) || NetworkHelper.IsValidLocalUser(name, password)) { token = CreateTokenWithX509SigningCredentials(NetworkHelper.GetFullyQualifiedUserName(name)); return(true); } } catch (FormatException) { } return(false); }
public bool TryAuthenticateRequest(HttpContextBase context) { ClaimsPrincipal principal = null; var request = context.Request; var response = context.Response; response.Headers["Strict-Transport-Security"] = "max-age=0"; if (request.Url.Scheme != "https") { response.Redirect(String.Format("https://{0}{1}", request.Url.Authority, request.Url.PathAndQuery), endResponse: true); return false; } if (request.Url.PathAndQuery.StartsWith("/logout", StringComparison.OrdinalIgnoreCase)) { RemoveSessionCookie(context); var logoutUrl = GetLogoutUrl(context); response.Redirect(logoutUrl, endResponse: true); return false; } string tenantId; if (SwitchTenants(context, out tenantId)) { RemoveSessionCookie(context); var loginUrl = GetLoginUrl(context, tenantId, "/token"); response.Redirect(loginUrl, endResponse: true); return false; } var id_token = request.Form["id_token"]; var code = request.Form["code"]; var state = request.Form["state"]; if (!String.IsNullOrEmpty(id_token) && !String.IsNullOrEmpty(code)) { principal = AuthenticateIdToken(context, id_token); var tenantIdClaim = principal.Claims.FirstOrDefault(c => c.Type == TenantIdClaimType); if (tenantIdClaim == null) { throw new InvalidOperationException("Missing tenantid claim"); } var base_uri = request.Url.GetLeftPart(UriPartial.Authority); var redirect_uri = base_uri + "/manage"; var token = AADOAuth2AccessToken.GetAccessTokenByCode(tenantIdClaim.Value, code, redirect_uri); WriteOAuthTokenCookie(context, token); response.Redirect(base_uri + state, endResponse: true); return true; } else { var token = ReadOAuthTokenCookie(context); if (token != null) { if (!token.IsValid()) { token = AADOAuth2AccessToken.GetAccessTokenByRefreshToken(token.TenantId, token.refresh_token, ManagementResource); WriteOAuthTokenCookie(context, token); } principal = new ClaimsPrincipal(new ClaimsIdentity("AAD")); request.ServerVariables["HTTP_X_MS_OAUTH_TOKEN"] = token.access_token; } } if (principal == null) { var loginUrl = GetLoginUrl(context); response.Redirect(loginUrl, endResponse: true); return false; } HttpContext.Current.User = principal; Thread.CurrentPrincipal = principal; return true; }