I have a problem with my ASP.NET website, it got hacked. One hacker found a bug in my login system and he can login with every account he wants, even if the account is normal user, moderator or administrator. He can delete everything he wants.
Please can anyone help me, tell me if there is any vulnerable function or something
P.S. I'm not myself an ASP.NET programmer, I know only PHP, so please tell me exactly what I need to edit in the code, because I don't know ASP.NET at all.
ThanksAS
public void loginButton_Click(object sender, EventArgs e)
{
string username = nicknameTextBox.Text;
string password = passwordTextBox.Text;
string returnUrl = Request.QueryString["returnUrl"];
if (returnUrl == null) returnUrl = Convert.ToBase64String(Encoding.ASCII.GetBytes(Request.Url.ToString()));
string message = CurrentPlayer.LoginRequest(username, password, returnUrl);
if(message != null)
Response.Redirect("AccountLogin.aspx?returnUrl=" + returnUrl);
}
LoginRequest:
public static string LoginRequest(string username, string password, string returnUrl)
{
Player player = null;
string message = InputValidator.CheckLoginRequest(username, password, out player);
if (message != null) return message;
message = LoginCookie.CheckLoginRequest(player);
if (message != null) return message;
SessionPlayer sessionPlayer = new SessionPlayer(
player.ID, player.ActivationGuid, (PlayerRole)player.IdRole,
player.Nickname, player.CreationDate);
SessionMessages sessionMessages = new SessionMessages(player.ID);
SessionOwnedCounts ownedCounts = new SessionOwnedCounts(player.ID);
SessionGuestCounts guestCounts = new SessionGuestCounts(player.ID);
SessionMatchCounts matchCounts = new SessionMatchCounts(player.ID);
CurrentPlayer.Login(sessionPlayer, sessionMessages, ownedCounts, guestCounts, matchCounts);
Player.UpdateLastLogin(player.ID);
returnUrl = Encoding.ASCII.GetString(Convert.FromBase64String(returnUrl));
HttpContext.Current.Response.Redirect(returnUrl);
return null;
}[/code]
Login:
private static void Login(SessionPlayer player, SessionMessages messages, SessionOwnedCounts ownedCounts, SessionGuestCounts guestCounts, SessionMatchCounts matchCounts)
{
HttpContext.Current.Session["player"] = player;
HttpContext.Current.Session["messages"] = messages;
HttpContext.Current.Session["ownedCounts"] = ownedCounts;
HttpContext.Current.Session["guestCounts"] = guestCounts;
HttpContext.Current.Session["matchCounts"] = matchCounts;
if (LoginCookie.Exists() == false)
LoginCookie.AddForFirstTime(player.Nickname, player.Guid);
else
LoginCookie.SetToLoginAction();
}
And checkloginrequest:
public static string CheckLoginRequest(string username, string password, out Player player)
{
player = null;
object lastLoginTryDateObj = HttpContext.Current.Session["lastLoginTryDate"];
if (lastLoginTryDateObj == null)
{
HttpContext.Current.Session["lastLoginTryDate"] = DateTime.Now;
HttpContext.Current.Session["lastLoginTryCount"] = 1;
}
else
{
DateTime lastLoginTryDate = (DateTime)HttpContext.Current.Session["lastLoginTryDate"];
int lastLoginTryCount = (int)HttpContext.Current.Session["lastLoginTryCount"];
TimeSpan ts = DateTime.Now - lastLoginTryDate;
if (ts.TotalSeconds < 60)
{
if (lastLoginTryCount >= Settings.AllowedLoginTriesPerMinute)
{
return "Ai depasit numarul maxim de incercari pe minut .<br/>Vino inapoi dupa " + (60 - (int)ts.TotalSeconds).ToString() + " secunde.";
}
else
{
HttpContext.Current.Session["lastLoginTryCount"] = lastLoginTryCount + 1;
}
}
else
{
HttpContext.Current.Session["lastLoginTryDate"] = DateTime.Now;
HttpContext.Current.Session["lastLoginTryCount"] = 1;
}
}
player = Player.GetPlayer(username, password);
if (player == null)
{
return "Usernameul si parola nu se potrivesc.";
}
if (player != null && player.IsActive == false)
{
return "Contul a fost creat dar nu e activat.<br/> Verifica mailul " + player.Email + " si activeaza-ti contul.";
}
PlayerSuspended ps = BLL.PlayerSuspended.SuspendedGet(player.ID);
if (ps != null)
{
return "Contul tau e suspendat pana in data de " + ps.SuspendedEndDate.ToString("dd-MM-yyyy") + ".<br/>Motivul: " + ps.SuspendedReason;
}
return null;
}
GetPlayer:
public static Player GetPlayer(string nickname, string password)
{
Player player = null;
object[] values = DAL.Player.GetPlayer(nickname, password);
if (values != null)
{
player = new Player();
player.SetFromValues(values);
}
return player;
}
DAL.Player.GetPlayer:
public static object[] GetPlayer(string nickname, string password)
{
password = Convert.ToBase64String(Encoding.ASCII.GetBytes(password));
List<SqlParameter> sqlParams = new List<SqlParameter>();
sqlParams.Add(new SqlParameter("#Nickname", nickname));
sqlParams.Add(new SqlParameter("#Password", password));
return DataBase.GetFirstRow("[spPlayer.Get]", sqlParams);
}
Your site is vulnerable to session fixation
Why are you not using asp.net forms authentication and membership?
Related
I have implemented Citrus Payment gatway request/Response pages I am struck with Enquiry API integration,Where i have to implement it in code ?what is the page name i have to give ?
this is the guide given to me by citrus to implement enquiry api ..
http://developers.citruspay.com/api/miscellaneous/Enquiry.html#/
Request.aspx page code -
{
string formPostUrl = "https://sandbox.citruspay.com/sslperf/xyzdoman";
string secret_key = "xxxxxxxxxxxxxxx";
//Need to change with your Vanity URL Key from the citrus panel
string vanityUrl = "xxxxxyy";
//Should be unique for every transaction
string merchantTxnId = System.DateTime.Now.ToString("yyyyMMddHHmmssffff");
//Need to change with your Order Amount
string orderAmount = "10";
string currency = "INR";
string data = vanityUrl + orderAmount + merchantTxnId + currency;
//Need to change with your Return URL
string returnURL = "http://www.xxxxxyy.com/Response.aspx";
//Need to change with your Notify URL
string notifyUrl = "http://www.xxxxxyy.com/Response.aspx";
System.Security.Cryptography.HMACSHA1 myhmacsha1 = new System.Security.Cryptography.HMACSHA1(Encoding.ASCII.GetBytes(secret_key));
System.IO.MemoryStream stream = new System.IO.MemoryStream(Encoding.ASCII.GetBytes(data));
string securitySignature = BitConverter.ToString(myhmacsha1.ComputeHash(stream)).Replace("-", "").ToLower();
%>
Response.aspx page code
{
string secret_key = "xxxxxxxxxxxxxxxxxxxxx";
string data="";
string txnId=Request["TxId"];
string txnStatus=Request["TxStatus"];
string amount=Request["amount"];
string pgTxnId=Request["pgTxnNo"];
string issuerRefNo=Request["issuerRefNo"];
string authIdCode=Request["authIdCode"];
string firstName=Request["firstName"];
string lastName=Request["lastName"];
string pgRespCode=Request["pgRespCode"];
string zipCode=Request["addressZip"];
string resSignature=Request["signature"];
bool flag = true;
if (txnId != null) {
data += txnId;
}
if (txnStatus != null) {
data += txnStatus;
}
if (amount != null) {
data += amount;
}
if (pgTxnId != null) {
data += pgTxnId;
}
if (issuerRefNo != null) {
data += issuerRefNo;
}
if (authIdCode != null) {
data += authIdCode;
}
if (firstName != null) {
data += firstName;
}
if (lastName != null) {
data += lastName;
}
if (pgRespCode != null) {
data += pgRespCode;
}
if (zipCode != null) {
data += zipCode;
}
System.Security.Cryptography.HMACSHA1 myhmacsha1 = new System.Security.Cryptography.HMACSHA1(Encoding.ASCII.GetBytes(secret_key));
System.IO.MemoryStream stream = new System.IO.MemoryStream(Encoding.ASCII.GetBytes(data));
string signature = BitConverter.ToString(myhmacsha1.ComputeHash(stream)).Replace("-", "").ToLower();
if(resSignature !=null && !signature.Equals(resSignature)) {
flag = false;
}
if (flag) {
%>
Your Unique Transaction/Order Id : <%=txnId%><br/>
Transaction Status : <%=txnStatus%><br/>
<% } else { %>
<label width="125px;">Citrus Response Signature and Our (Merchant) Signature Mis-Mactch</label>
<% } %>
I have created a login page in asp.net using c# but I am having difficulty trying to only allow a certain group to have access. Right now I am accessing everyone but I can't seem to just filter the group that I need so only those person(s) can have access to my application.
Any help would be great so I can just permission this application out to that one group within Active Directory.
Here is my class that I am using to pass the groups:
public class LdapAuthentication
{
private string _path;
private string _filterAttribute;
public LdapAuthentication(string path)
{
_path = path;
}
public bool IsAuthenticated(string domain, string username, string pwd)
{
string domainAndUsername = domain + #"\" + username;
DirectoryEntry entry = new DirectoryEntry( _path, domainAndUsername, pwd);
try
{
// Bind to the native AdsObject to force authentication.
Object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if(null == result)
{
return false;
}
// Update the new path to the user in the directory
_path = result.Path;
_filterAttribute = (String)result.Properties["cn"][0];
}
catch (Exception ex)
{
throw new Exception("Error authenticating user. " + ex.Message);
}
return true;
}
public string GetGroups()
{
DirectorySearcher search = new DirectorySearcher(_path);
search.Filter = "(cn=" + _filterAttribute + ")";
search.PropertiesToLoad.Add("memberOf");
StringBuilder groupNames = new StringBuilder();
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
String dn;
int equalsIndex, commaIndex;
for (int propertyCounter = 0; propertyCounter < propertyCount;
propertyCounter++)
{
dn = (String)result.Properties["memberOf"][propertyCounter];
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if (-1 == equalsIndex)
{
return null;
}
groupNames.Append(dn.Substring((equalsIndex + 1),
(commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
}
catch (Exception ex)
{
throw new Exception("Error obtaining group names. " +
ex.Message);
}
return groupNames.ToString();
}
public bool isMember( String groupname )
{
DirectorySearcher search = new DirectorySearcher(_path);
search.Filter = "(cn=" + _filterAttribute + ")";
search.PropertiesToLoad.Add("memberOf");
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
for (int propertyCounter = 0; propertyCounter < propertyCount;
propertyCounter++)
{
String dn = (String)result.Properties["memberOf"][propertyCounter];
// The comma in the regex is important to prevent accidental matches
if ( Regex.IsMatch( dn, #"cn="+groupname+",.*", RegexOptions.IgnoreCase))
return true;
}
}
catch (Exception ex)
{
// Some logging here probably
}
return false;
}
}
It has to be in the Get groups function but I am not sure how to pass the group I am looking for. If anyone can help that would be greatly appreciated. Thanks in advance.
Here is my button click event:
protected void btnLogin_Click(object sender, EventArgs e)
{
// Path to you LDAP directory server.
// Contact your network administrator to obtain a valid path.
string adPath = "LDAP://domain.com";
LdapAuthentication adAuth = new LdapAuthentication(adPath);
String myGroupName = "Some_Group";
try
{
if (true == adAuth.IsAuthenticated(txtDomainName.Text, txtLoginID.Text, txtPassword.Text))
{
if( adAuth.isMember( myGroupName ) )
{
// User is authenticated and a member of the group.
// Create your auth ticket, cookie, and whatnot
// Retrieve the user's groups
string groups = adAuth.GetGroups();
// Create the authetication ticket
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, // version
txtLoginID.Text,
DateTime.Now,
DateTime.Now.AddMinutes(60),
false, groups);
// Now encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
// Create a cookie and add the encrypted ticket to the
// cookie as data.
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
// Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie);
// Redirect the user to the originally requested page
//Response.Redirect(FormsAuthentication.GetRedirectUrl(txtLoginID.Text, false));
Response.Redirect("LookupEdit.aspx");
}
else
{
lblError.Text = "Authorization failed. You are not a member of the "+myGroupName+" group";
}
}
else
{
lblError.Text = "Authentication did not succeed. Check user name and password.";
}
}
catch(Exception ex)
{
lblError.Text = "Error authenticating. " + ex.Message;
}
}
OK so after your comments, here's what you should do:
Create an isMember(String) function in your LdapAuthentication class:
public boolean isMember( String groupname )
{
DirectorySearcher search = new DirectorySearcher(_path);
search.Filter = "(cn=" + _filterAttribute + ")";
search.PropertiesToLoad.Add("memberOf");
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
for (int propertyCounter = 0; propertyCounter < propertyCount;
propertyCounter++)
{
String dn = (String)result.Properties["memberOf"][propertyCounter];
// The comma in the regex is important to prevent accidental matches
if ( Regex.IsMatch( dn, #"cn="+groupname+",.*", RegexOptions.IgnoreCase)
return true;
}
}
catch (Exception ex)
{ // Some logging here probably
}
return false;
}
Next, add this as your btnlogin_Click code:
<script runat=server>
void btnlogin_Click(Object sender, EventArgs e)
{
String adPath = "LDAP://your.domain.com"; //Enter your domain name here
LdapAuthentication adAuth = new LdapAuthentication(adPath);
String myGroupName = "auth-group-name"; //Enter your group's name (cn) here
try
{
if(true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
{
if( adAuth.isMember( myGroupName ) )
{
// User is authenticated and a member of the group.
// Create your auth ticket, cookie, and whatnot
}
else
{
errorLabel.Text = "Authorization failed. You are not a member of the "+myGroupName+" group";
}
}
else
{
errorLabel.Text = "Authentication did not succeed. Check user name and password.";
}
}
catch(Exception ex)
{
errorLabel.Text = "Error authenticating. " + ex.Message;
}
}
</script>
This should do the trick for you. Obviously you should create some code after the isMember() check to create a secure cookie that allows other pages to check the authenticated state of the user.
Good luck.
I was also having issues with this. I use pretty much the same class as you do to do the AD authentication. I was using a different way to connect to AD but was having some strange problems. I implemented a Role Provider before I changed to this code and I'm still using that Role provider to deny and grant access. This is how I basically did it. Follow this link as it will help you set up the roles.
The only thing I changed up was the "GetRolesForUser" with..
public override string[] GetRolesForUser(string username)
{
var allRoles = new List();
var ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);
if (user != null)
{
var groups = user.GetGroups();
allRoles.AddRange(groups.Select(x => x.Name));
}
return allRoles.ToArray();
}
This way, you can deny and grant groups within the web.config.
I do it like this..
<location path="TestPage.aspx">
<system.web>
<authorization>
<allow roles="SoftwareDevelopers" />
<deny users="*" />
</authorization>
</system.web>
</location>
So I'm denying everyone access to the TestPage.aspx besides the AD group SoftwareDevelopers.
I hope this helps.
EDIT: If you are using the link that is in the comment to do this active directory, one way to get the group is using the authentication ticket that's created when you login.
if (Request.Cookies["ADAuthCookie"] != null)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
string cookiePath = ticket.CookiePath;
DateTime expiration = ticket.Expiration;
bool expired = ticket.Expired;
bool isPersistent = ticket.IsPersistent;
DateTime issueDate = ticket.IssueDate;
string name = ticket.Name;
string userData = ticket.UserData;
int version = ticket.Version;
System.Diagnostics.Debug.WriteLine(cookiePath);
System.Diagnostics.Debug.WriteLine(expiration);
System.Diagnostics.Debug.WriteLine(expired);
System.Diagnostics.Debug.WriteLine(isPersistent);
System.Diagnostics.Debug.WriteLine(issueDate);
System.Diagnostics.Debug.WriteLine(name);
System.Diagnostics.Debug.WriteLine(userData);
System.Diagnostics.Debug.WriteLine(version);
if (userData.Contains("SoftwareDevelopers"))
{
lblMessage.Text = "You're a software developer.";
}
}
You will have to decrypt the ticket to be able to read the information. I have provided how to write it to the console so you could see how it works. If you wanted to, the if statement provided above is one way you can restrict/show parts of a page.
However, I'm finding that the link in this answer on how to set up the ADRoleProvider is probably going to be your best route.
You want to check if the user is a member of the correct group, right?
Why not create a function that accepts a group name and returns boolean, like this:
public boolean isMember( String username, String groupname )
{
DirectorySearcher search = new DirectorySearcher(_path);
search.Filter = "(cn=" + username + ")";
search.PropertiesToLoad.Add("memberOf");
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
for (int propertyCounter = 0; propertyCounter < propertyCount;
propertyCounter++)
{
String dn = (String)result.Properties["memberOf"][propertyCounter];
// The comma in the regex is important to prevent accidental matches
if ( Regex.IsMatch( dn, #"cn="+groupname+",.*", RegexOptions.IgnoreCase)
return true;
}
}
catch (Exception ex)
{ // Some logging here probably
}
return false;
}
The best way is to let LDAP do the membership iteration, by specifying the groupname in your search. However that requires the groupname to be the complete group DN (e.g. cn=mygroup,ou=groups,dc=xxx,dc=xxx) so this might not be feasible for you:
public boolean isMember( String username, String groupdn )
{
DirectorySearcher search = new DirectorySearcher(_path);
// Escaping the input strings is advisable from a security standpoint!
search.Filter = "(&(cn=" + username + ")(memberOf=" + groupdn + "))";
search.PropertiesToLoad.Add("cn");
try
{
SearchResult result = search.FindOne();
// The LDAP server has done the matching for us
if ( result != null )
return true;
}
catch (Exception ex)
{ // Some logging here probably
}
return false;
}
Good luck!
I have hosted a Windows Web API using a basic authentication header with username and password.
I'm trying to create a login form that takes a username and password and sends back a token.
so i have the following code.
I'm using a Attributed method
public class BasicAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
private IPromiseRepository promiseRepository;
public BasicAuthenticationAttribute()
{
this.promiseRepository = new EFPromiseRepository(new PropellorContext());
//repository = promiseRepository;
}
public BasicAuthenticationAttribute(IPromiseRepository promiseRepository, INewsFeedRepository newsfeedRepository)
{
this.promiseRepository = promiseRepository;
}
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext.Request.Headers.Authorization == null)
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
else
{
string authToken = actionContext.Request.Headers.Authorization.Parameter;
string decodedToken = authToken;
// Encoding.UTF8.GetString(Convert.FromBase64String(authToken));
string username = decodedToken.Substring(0, decodedToken.IndexOf(":"));
string password = decodedToken.Substring(decodedToken.IndexOf("^")+1);
string APIToken = decodedToken.Substring(decodedToken.IndexOf("="));
APIToken = APIToken.Replace("=", string.Empty);
password = password.Replace("=", string.Empty);
if (!string.IsNullOrEmpty(APIToken))
{
password = password.Replace(APIToken, string.Empty);
}
if (username != null && password != null)
{
try
{
var user = promiseRepository.GetUserByName(username);
var salt = user.PasswordSalt;
System.Security.Cryptography.SHA512Managed HashTool = new System.Security.Cryptography.SHA512Managed();
Byte[] PasswordAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(password, salt));
Byte[] EncryptedBytes = HashTool.ComputeHash(PasswordAsByte);
HashTool.Clear();
var hashedpass = Convert.ToBase64String(EncryptedBytes);
if (hashedpass == user.Password)
{
if (string.IsNullOrEmpty(user.APIToken))
{
String guid = System.Guid.NewGuid().ToString();
user.APIToken = guid;
promiseRepository.UpdateUser(user);
promiseRepository.Save();
}
if (user != null)
{
user = promiseRepository.GetUserByUserID(user.UserID);
HttpContext.Current.User = new GenericPrincipal(new ApiIdentity(user), new string[] { });
base.OnActionExecuting(actionContext);
}
}
if (APIToken != null)
{
if (user.APIToken == APIToken)
{
var userbytoken = promiseRepository.GetUserByAPIToken(APIToken);
HttpContext.Current.User = new GenericPrincipal(new ApiIdentity(userbytoken), new string[] { });
base.OnActionExecuting(actionContext);
}
}
}
catch (Exception)
{
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
base.OnActionExecuting(actionContext);
}
throw;
}
}
}
}
}
This works with Fiddler when the correct credentials are passed
I'm attempting to produce the same authentication in my windows phone application.
Passes a username and password into the basic authentication http header.
However I'm not sure how to do this after a large amount of diggging on the internet alot of the exmaples are windows phone 7 and certain methods don't exist anymore.
This is the code i have arrived at.
private void Login1_Click(object sender, RoutedEventArgs e)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:5650/api/start");
NetworkCredential credentials = new NetworkCredential(userName.Text + ":^",password.Text + "=");
request.Credentials = credentials;
request.BeginGetResponse(new AsyncCallback(GetSomeResponse), request);
Hopefully someone can guide me into the right direction.
it should be simple in principle :(
Here is a sample using HttpClient:
public static async Task<String> Login(string username, string password)
{
HttpClient Client = new HttpClient();
Client.DefaultRequestHeaders.Add("Authorization", "Basic " + Convert.ToBase64String(StringToAscii(string.Format("{0}:{1}", username, password))));
var response = await Client.GetAsync(new Uri(new Uri("http://yourdomain.com"), "/login"));
var status= await response.Content.ReadAsAsync<String>();
return status;
}
And of course you can find the ToBase64String function on the internet. The tricky part here is the Authorization header.
I am getting "Logon failure: unknown user name or bad password" error when I try to get the groups a user belongs to. User authentication works fine and this is what I can't understand. How can I properly authenticate a user against AD but can't get his group names?
I get user's ID and password. I have a class that deals with authentication.
if ((true == adAuth.IsAuthenticated(sDomain, sID, sPassword)))
{
string sGroups = adAuth.GetGroups();
This is the authentication class:
public class LdapAuthentication
{
string _path;
string _filterAttribute;
public LdapAuthentication(string path)
{
_path = path;
}
public bool IsAuthenticated(string domain, string username, string pwd)
{
string domainAndUsername = domain + "\\" + username;
DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
try {
//Bind to the native AdsObject to force authentication.
object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if ((result == null)) {
return false;
}
//Update the new path to the user in the directory.
_path = result.Path;
_filterAttribute = Convert.ToString(result.Properties["cn"][0]);
}
catch (Exception ex) {
throw new Exception("Error authenticating user. " + ex.Message);
//return false;
}
return true;
}
public string GetGroups()
{
//DirectorySearcher search = new DirectorySearcher(_path);
// Use following two lines instead of the above to handle cases of authenticatin against an LDAP server other than local AD domain
DirectoryEntry deSearchRoot = new DirectoryEntry(_path);
DirectorySearcher search = new DirectorySearcher(deSearchRoot);
search.Filter = "(cn=" + _filterAttribute + ")";
search.PropertiesToLoad.Add("memberOf");
StringBuilder groupNames = new StringBuilder();
try {
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
string dn = null;
int equalsIndex = 0;
int commaIndex = 0;
int propertyCounter = 0;
for (propertyCounter = 0; propertyCounter <= propertyCount - 1; propertyCounter++) {
dn = Convert.ToString(result.Properties["memberOf"][propertyCounter]);
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if ((equalsIndex == -1)) {
return null;
}
groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
} catch (Exception ex) {
throw new Exception("Error obtaining group names. " + ex.Message);
}
return groupNames.ToString();
}
IsAuthnticated passes and works fine; GetGroups() returns "Error obtaining group names" followed by "Logon failure: unknown user name or bad password" (i.e. the exception in GetGroups()).
It works fine when I run the app from VS but when I publish it (on the same server), it behaves like this.
Any ideas greatly appreciated.
Never mind; operator error. Code works fine.
I've had some Page Tab apps working, just basic authorization as I don't need anything except name / id for what I'm doing - but I've tried the same method with the canvas app and it's not working. It seems to be with the redirect back, and I really can't see where I'm going wrong based on facebook's documentation for canvas apps http://developers.facebook.com/docs/appsonfacebook/tutorial/#auth
On loading I show a button, on clicking that it tries to get authorisation but it's not working. I've checked and double checked that I'm using the canvas url as the redirect but all I'm getting is a 404 (which is wrong as the page definitely exists, or else the button wouldn't appear). The URL on the 404 page is what really bemuses me, it's:
http://apps.mydomain.co.uk/myappname/https%3a%2f%2fwww.facebook.com%2fdialog%2foauth%3fclient_id%3d999999999999%26redirect_uri%3dhttp%253a%252f%252fapps.mydomain.co.uk%252fmyappname%252f
It has to be something to do with the redirection - any help would be appreciated.
Here's my code (shortened for clarity, urls changed):
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string error = Request.QueryString["error_reason"];
if (String.IsNullOrEmpty(error))
{
if (Request.Form["signed_request"] != null)
{
signedRequest();
}
if (String.IsNullOrEmpty(_auth))
{
intro.Visible = true;
main.Visible = false;
}
else
{
intro.Visible = false;
main.Visible = true;
}
}
else
{
// show intro page
intro.Visible = true;
main.Visible = false;
}
}
}
protected void Authorise_Click(object sender, EventArgs e)
{
// redirect if needs auth
if (String.IsNullOrEmpty(_auth))
{
// get authorisation
string id = "999999999999";
string canvas = Server.UrlEncode("http://apps.mydomain.co.uk/myappname/");
string redir = Server.UrlEncode("https://www.facebook.com/dialog/oauth?client_id="+ id +"&redirect_uri=" + canvas); // test
Response.Write("<script>top.location.href='" + redir + "'</script>");
}
else
{
// already authorised
// go straight to main page
}
}
private void signedRequest()
{
string sreq = Request.Form["signed_request"];
string[] splitPayload = sreq.Split('.');
string sig = splitPayload[0];
string payload = splitPayload[1];
Dictionary<string, string> JSONpayload = DecodePayload(payload);
_auth = JSONpayload["user_id"].ToString();
_code = JSONpayload["oauth_token"].ToString();
if (!String.IsNullOrEmpty(JSONpayload["oauth_token"]))
{
var fb = new FacebookClient(JSONpayload["oauth_token"]);
var result = (IDictionary<string, object>)fb.Get("/me");
_name = (string)result["name"];
//Response.Write("<br /><br />RESULT: " + result);
ViewState["name"] = _name;
Session["name"] = _name;
}
ViewState["id"] = _auth;
Session["id"] = _auth;
}
private Dictionary<string, string> DecodePayload(string payload)
{
var encoding = new UTF8Encoding();
var decodedJson = payload.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '='));
var json = encoding.GetString(base64JsonArray);
var jObject = JObject.Parse(json);
Response.Write("jObject: " + jObject);
var parameters = new Dictionary<string, string>();
parameters.Add("user_id", (string)jObject["user_id"] ?? "");
parameters.Add("oauth_token", (string)jObject["oauth_token"] ?? "");
var expires = ((long?)jObject["expires"] ?? 0);
parameters.Add("expires", expires > 0 ? expires.ToString() : "");
parameters.Add("profile_id", (string)jObject["profile_id"] ?? "");
if (jObject["page"] != null)
{
var jObjectPage = JObject.Parse(jObject["page"].ToString());
bool isPageLiked = bool.Parse(jObjectPage["liked"].ToString());
parameters.Add("is_Liked", isPageLiked.ToString() ?? "");
}
else
{
_liked = false;
}
return parameters;
}