Hey I'm using PasswordVault for storing user credentials in my windows 8 app.
What I want the app to do on loading is check to see if the PasswordVault/credential manager already has a stored value for my app. if it don't don't I want it to stay on the page so the user can login, but if the credentials are already there then I would like it to go straight to page 2.
I tried using the following code:
private Windows.Security.Credentials.PasswordCredential GetCredentialFromLocker()
{
Windows.Security.Credentials.PasswordCredential credential = null;
var vault = new Windows.Security.Credentials.PasswordVault();
var credentialList = vault.FindAllByResource("MYapp");
if (credentialList.Count > 0)
if (credentialList.Count == 1)
credential = credentialList[0];
else
// User selecor
return credential;
}
and then on page load I have
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var loginCredential = GetCredentialFromLocker();
if (loginCredential != null)
this.Frame.Navigate(typeof(page2));
else
{
loginBigButton.Visibility = Windows.UI.Xaml.Visibility.Visible;
signUpButton.Visibility = Windows.UI.Xaml.Visibility.Visible;
signUpTextBlock.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
}
The problem is that if there is no credential stored with the Resource (MYapp) the code:
var credentialList = vault.FindAllByResource("MYapp");
yields:
WinRT information: Cannot find credential in Vault
Additional information: Element not found.
Method FindAllByResource throws exception when there are no credentials for specified resource, so you need to wrap it with try catch block.
Alternatively you can use 'RetrieveAll' which doesn't throw exception if there are no credentials stored and iterate over each returned PasswordCredential and check it's Resource property.
I'll try to answer this question the best as I can:
Firstable as Tadeusz said FindAllByResource throws an exception when there are no credentials for specified resource, in order to dont crash you app, you would need to wrap you logic within a try-catch block.
the reason to do this is for you to be able to create your resource in case you dont have one. so the way I see it, you logic should look like this:
private Windows.Security.Credentials.PasswordCredential GetCredentialFromLocker()
{
Windows.Security.Credentials.PasswordCredential credential = null;
var vault = new Windows.Security.Credentials.PasswordVault();
try
{
var credential = vault.FindAllByResource("MYapp").FirstOrDefault();
return credential;
}
catch(Exception ex)
{
Debug.WriteLine($"Error retrieving Token: {ex.Message}");
}
return null;
}
now all you have to do is to store a new token in your passwordvault
you have to login first and then you store the token, so next time you try to retrieve your credentials it wont throw an exception since its already store.
by example it should be something like this:
await client.LoginAsync(provider);
then you store your token like this:
PasswordVault.Add(new PasswordCredential("MYapp",
client.CurrentUser.UserId,
client.CurrentUser.MobileServiceAuthenticationToken));
I hope this answer helps in order, sorry for the late answer but, I found myself trying to solve this problem right now and I thought i should give a more detail or complete answer to this question.
Also you should consider token expiration checks and refreshing handling.
Related
I was having a code which was running perfectly to remove a user from an azure group but suddenly It stops working..when I debug the code Remove() method is returning false as a boolean.
Below is the code which is not working.Can anyone please suggest me a quick fix.
public static async Task RemoveUserFromGroup(IGroup group, IUser user)
{
RemoveFromGroupResult result = new RemoveFromGroupResult();
try
{
((Group)group).Members.Remove(user as DirectoryObject);
await group.UpdateAsync();
result.ErrorMsg = string.Empty;
}
catch (Exception e)
{
result.IsAdded = false;
result.ErrorMsg = e.Message;
}
return result;
According to my test, the code((Group)group).Member always returns null List. So we cannot use the code ((Group)group).Members.Remove(user as DirectoryObject); await group.UpdateAsync(); to remove group member.
According to the situation, I suggest you use the Rest API to remove group member
DELETE https://graph.windows.net/myorganization/groups/{object_id}/$links/members/{member_id}?api-version=1.6
I would like to create a layer of security. For example:
User = John (Signed in) has a Session["ipadress"]
Hacker = Unknown (using same session_id) has a same Session["ipadress"] or new one? i need an information..
Well, i would like to check an ip adress and if it's different from registered and logged in user than redirect to sessioninactive.aspx page.
Is it possible to do in global.asax?
This will do the job inside Global.asax:
protected void Application_BeginRequest(object sender, EventArgs e)
{
var ip = HttpContext.Current.Request.UserHostAddress;
//TODO: handle correct list
List<string> validIps = new List<string> { "::1" };
if (!validIps.Contains(ip))
{
HttpContext.Current.Response.StatusCode = 403;
HttpContext.Current.Response.StatusDescription = "Forbidden";
HttpContext.Current.Response.End();
}
}
Add the following methods in Global.asax
Save the IP to session on Session_Start:
protected void Session_Start()
{
string userIp = HttpContext.Current.Request.UserHostAddress;
Session["ipadress"] = userIp;
}
On each request, see if the request IP is same as saved in session:
protected void Application_AcquireRequestState()
{
string userIp = HttpContext.Current.Request.UserHostAddress;
if (Session["ipadress"] != null)
{
string originalUserIp = Session["ipadress"].ToString();
if (originalUserIp != userIp)
{
Response.Redirect("sessioninactive.aspx");
}
}
}
I would do that at the place where I check the user. For example on the login page.
You can simply do something like that:
string sUserHostaddress = Request.UserHostAddress;
Then you can compare your Seesion["ipaddress"] (you can populate that session variable the same way) with sUserHostAddress.
Not sure what you mean with imitating session_id? I wouldn't rely on cookies to manage authenticated state. I think the important aspect is that your login is secure. Password encrypted. I would always check a session cookie against the actual used SessionID and if they don't match I get suspicious (can write code to do something about that).
You might run into a problem if the user uses a proxy which changes the IP address during a sesion. Saw something like that in my log files.
Hope this helps.
I have a piece of functionality that creates a voice message and if authenticated through Twitter, will post a message to their Twitter account. I want the ability for the user to turn off the message posting to Twitter if they desire, so I was curious if there was a way to clear the credentials. I followed an example from the LinqToTwitter documentation:
IOAuthCredentials credentials = new SessionStateCredentials();
if (credentials.ConsumerKey == null || credentials.ConsumerSecret == null)
{
credentials.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
credentials.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
}
auth = new WebAuthorizer
{
Credentials = credentials,
PerformRedirect = authUrl => Response.Redirect(authUrl)
};
if (!Page.IsPostBack && Request.QueryString["oauth_token"] != null)
{
auth.CompleteAuthorization(Request.Url);
}
if (auth.IsAuthorized)
{
twitterCtx = new TwitterContext(auth);
Session["TwitterContext"] = twitterCtx;
twLoginButton.Text = "Logout of Twitter";
}
I've tried the following code and variations:
credentials = null;
or
SessionStateCredentials credentials = Dispose();
But it shows errors for each of these. I was hoping someone could guide me in clearing out
IOAuthCredentials credentials = new SessionStateCredentials();
which is what I think needs to happen. Any advice would be appreciated.
The SessionStateCredentials type has properties that use Session state as their backing store. Here are a few options, with pros and cons of each:
Set the properties to null. e.g.
credentials.ConsumerKey = null;
credentials.ConsumerSecret = null;
// etc ...
This is a little ugly, though you could write a method to encapsulate the statements.
Clear out the individual Session state items. e.g.
Session.Remove("ConsumerKey");
Session.Remove("ConsumerSecret");
// etc ...
This is more explicit. However, it breaks the existing encapsulation and forces you to obtain a reference to the current session.
Derive a new class from SessionStateCredentials with a Clear method that performs the steps from one of the previous methods. This might be the cleanest option.
Here's a link to the SessionStateCredentials class so you can see the internal implementation:
http://linqtotwitter.codeplex.com/SourceControl/latest#LinqToTwitter/OAuth/SessionStateCredentials.cs
This is probably more of a general c# and simple threading question than it is a Facebook SDK question, but I may be wrong. But I could really use some help. I am reusing the sample code that comes with the SDK which includes a FacebookLoginDialog class. I am currently using it like this. In my GetMessages, GetFriendRequests, and other Get* classes, I always try/catch calls like this:
try
{
var result = (IDictionary<string, object>)fb.Get("/me/inbox");
}
catch (FacebookOAuthException e)
{
FacebookSession.Login();
}
Here's my login method in my FacebookSession class
public static void Login()
{
var fbLoginDialog = new FacebookLoginDialog(APP_ID, EXTENDED_PERMISSIONS);
DialogResult dr = fbLoginDialog.ShowDialog();
DisplayAppropriateMessage(fbLoginDialog.FacebookOAuthResult);
}
And here is the constructor in my FacebookLoginDialog class (this is where I have the problem)
public FacebookLoginDialog(string appId, string[] extendedPermissions, bool logout)
{
try
{
var oauth = new FacebookOAuthClient { AppId = appId };
var loginParameters = new Dictionary<string, object>
{
{ "response_type", "token" },
{ "display", "popup" }
};
if (extendedPermissions != null && extendedPermissions.Length > 0)
{
var scope = new StringBuilder();
scope.Append(string.Join(",", extendedPermissions));
loginParameters["scope"] = scope.ToString();
}
var loginUrl = oauth.GetLoginUrl(loginParameters);
if (logout)
{
var logoutParameters = new Dictionary<string, object>
{
{ "next", loginUrl }
};
System.Uri uri =
new Uri("https://www.facebook.com/logout.php?next=" +
"https://www.facebook.com/connect/login_success.html&access_token=" +
FacebookSession._accessToken);
this.navigateUrl = uri;
}
else
{
this.navigateUrl = loginUrl;
}
InitializeComponent(); // crash here... sometimes
}
catch (Exception e)
{
//Log error message
}
}
Sorry for all the code, but now the problem. This code works fine the first time through. If I go to my facebook applications permissions page in Facebook and remove the app (that is, remove its permissions), while my desktop app here is NOT running, when I do start it up, it sees that it does not have permission and shows the login dialog. I can save the access_key and it will work just fine. But if I go to the facebook apps page and yank the permissions while my desktop app is running, then bad things happen. I get an error message about the activex control cannot be instantiated because the current thread is not in a single-threaded apartment. I have seen many posts here that say all you have to do is put [STAThread] above your main(), and my code has that. I have also tried creating a new thread to call the FacebookLoginDialog, but not only did that not work, but since my code is really not designed to run in multiple threads, that started causing more problems.
Is there a simple solution to all this, or do I need to redesign my code so that it properly runs in multiple threads? Or should I just live with the program crashing in those few instances when someone monkeys with the facebook permissions while my app is running?
This morning I discovered a nice method (DirectoryEntry.Exists), that should be able to check whether an Active Directory object exists on the server. So I tried with a simple:
if (DirectoryEntry.Exists(path)) {}
Of course it lacks any overloads to provide credentials with it. Because, if credentials are not provided I get this Exception:
Logon failure: unknown user name or
bad password.
(System.DirectoryServices.DirectoryServicesCOMException)
Is there any other option that gives me the possibility to authenticate my code at the AD server? Or to check the existence of an object?
In this case you can't use the static method Exists as you said :
DirectoryEntry directoryEntry = new DirectoryEntry(path);
directoryEntry.Username = "username";
directoryEntry.Password = "password";
bool exists = false;
// Validate with Guid
try
{
var tmp = directoryEntry.Guid;
exists = true;
}
catch (COMException)
{
exists = false;
}
I know this is an old question, but the source code is now available so you can just Steal and Modify™ to make a version that accepts credentials:
public static bool Exists(string path, string username, string password)
{
DirectoryEntry entry = new DirectoryEntry(path, username, password);
try
{
_ = entry.NativeObject; // throws exceptions (possibly can break applications)
return true;
}
catch (System.Runtime.InteropServices.COMException e)
{
if (e.ErrorCode == unchecked((int)0x80072030) ||
e.ErrorCode == unchecked((int)0x80070003) || // ERROR_DS_NO_SUCH_OBJECT and path not found (not found in strict sense)
e.ErrorCode == unchecked((int)0x800708AC)) // Group name could not be found
return false;
throw;
}
finally
{
entry.Dispose();
}
}
The one change you must make is changing the use of Bind, since that's an internal method and can't be used by mere mortals like us. Instead, I just get the NativeObject property, which calls Bind() for us.
You can use that like this:
var ouExists = Exists("LDAP://hadoop.com/OU=Students,DC=hadoop,DC=com", "username", "password");
There is no way to do this and I have written a connect issue to hopefully resolve it.
DirectoryEntry.Exists Does Not Accept Credentials
Here you can read about impersonation in C#:
http://www.codeproject.com/KB/cs/zetaimpersonator.aspx
http://www.codeproject.com/KB/system/everythingInAD.aspx
So answer to the question: impossible.
Finally write an own method to get the DirectoryEntry by distinguised name, with credentials specified. In both cases of existence/inexistence I got an instance of DirectoryEntry. To check whether it's a valid object returned I do a simple try...catch to see if it results in an Exception. If so, it's invalid.
Nasty check, but it works. Too bad the default .net method DirectoryEntry.Exists doesn't provide an overload to provide credentials just like the DirectoryEntry constructor...
If the user who ran the process doesn't have permissions to call DirectoryEntry.Exists, then you can use impersonation.
This may be helpful (discusses impersonation in an AD context): http://www.codeproject.com/KB/system/everythingInAD.aspx
Btw, if you already have credentials of a user who has access to everything you need, why not just the process with that user (e.g. /runas)?