I want the user credentials to be deleted when the window metro app is uninstalled.
Its not hapening when I am using password vault for saving passwords.
Is there any other way to solve my problem ?
There's another way. You can create a LocalSettings key to store bool value like true if user created and use this LocalSettings key (if not found) to clear vault.
You can implement it like this:
Check, whether to clear Credentials from previous install or not
//WILL RUN ONLY WHEN NO USER FOUND (FROM CURRENT INSTALL)
if (!localSettings.ContainsKey("usersExists"))
{
IReadOnlyList<PasswordCredential> userDetailsList = loginVault.RetrieveAll();
foreach (PasswordCredential x in userDetailsList)
{
try { loginVault.Remove(x); }
catch (Exception Error) { Debug.WriteLine(Error); }
}
Debug.WriteLine("\nNo User Found!! LoginVault has been reset. All Previous User Details are removed.");
}
Since User Details from previous install is removed now you can create a new user and add localSettings["usersExists"] = true;
Windows Store apps aren't able to participate in the uninstall process, so you can't do it directly. It does seem that a piece of app state like this should be cleared on uninstall, but it doesn't work that way at present.
You could use your own encryption scheme to store credentials in your own add data, which would be cleared on uninstall. This would be significant work, of course, to be secure.
If you just want to be sure to reacquire credentials after the app is installed, then you can maintain a flag in local app data that indicates whether to load credentials from the locker. On first install, this flag would not exist, so you'd know to collect credentials anew. Once you save in the locker, save a flag in app data that indicates this has happened, so subsequent sessions load from the locker. If the app is uninstalled, the app data contents will be cleared out such that on reinstall and launch you'd collect credentials again.
Related
Question: How can I enforce existing users to set up 2FA in .Net Core 3.1 Identity?
I have seen a couple of answers here already, but I have issues with them as follows:
Redirect user to set up 2FA page on login if they do not have it set up. Problem with this is that the user can simply jump to a different url to avoid this, therefore it is not actually enforced.
Have some on executing filter that checks if the user has 2FA enbaled or not and if not redirect them to MFA set up page. The issue I have with this is that on every single navigation the server must go to the database to check whether the user has this field enabled, thus creating a significant performance hit on each request. I know one trip to the database may not sound like much but I have worked with applications where this was the norm and other things used this method, causing a pile up of pre action db queries. I want to avoid this kind of behavior unless absolutely necessary.
My current idea is to on login:
Check the users credentials but NOT log them in
userManager.CheckPasswordAsync(....)
If the credentials pass, check if the user has 2FA enabled or not. If they do, continue through login flow, if not:
Generate a user token:
userManager.GenerateUserTokenAsync(.......)
and store this along with the username in a server side cache. Then pass a key to the cached items with a redirect to the 2FA setup page, which will not have the [authorize] attribute set, allowing users not logged in to access it.
Before doing anything on the 2FA set up page, retrieve the cached items with the provied key andverify the token and username:
userManager.VerifyUserTokenAsync(......)
If this doesn't pass, return Unauthorized otherwise continue and get the current user from the supplied UserName in the url that was passed via a cache key. Also dump the cached items and key so that should the url be snatched by a dodgy browser extension it can't be used again.
Continue to pass a new cache key to new user tokens and usernames to each 2FA page to authenticate the user as they navigate.
Is this an appropriate use of user tokens? And is this approach secure enough? I'm concerned that having the user not logged in presents security issues, but I think it is necessary in order to avoid the previously mention problem of going to the database on every request to check 2FA, as with this method trying to navigate away will just redirect to login.
I implemented this via a Filter Method
I have a BasePageModel which all my pages inherit
public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
{
if (!User.Identity.IsAuthenticated)
{
await next.Invoke();
return;
}
var user = await UserManager.GetUserAsync(User);
var allowedPages = new List<string>
{
"Areas_Identity_Pages_Account_ConfirmEmail",
"Areas_Identity_Pages_Account_ConfirmEmailChange",
"Areas_Identity_Pages_Account_Logout",
"Areas_Identity_Pages_Account_Manage_EnableAuthenticator",
"Areas_Identity_Pages_Account_ResetPassword",
"Pages_AllowedPageX",
"Pages_AllowedPageY",
"Pages_Privacy"
};
var page = context.ActionDescriptor.PageTypeInfo.Name;
if (!user.TwoFactorEnabled && allowedPages.All(p => p != page))
{
context.Result = RedirectToPage("/Account/Manage/EnableAuthenticator", new { area = "Identity" });
}
else
{
await next.Invoke();
}
}
I then changed both the Disable2fa and ResetAuthenticator pages to redirect to the main 2fa page
public IActionResult OnGet() => RedirectToPage("./TwoFactorAuthentication");
And removed the reset/disable links from that page
I chose to implement a more modern and OAuth friendly solution (which is inline with .Net Core Identity).
Firstly, I created a custom claims principal factory that extends UserClaimsPrincipalFactory.
This allows us to add claims to the user when the runtime user object is built (I'm sorry I don't know the official name for this, but its the same thing as the User property you see on controllers).
In here I added a claim 'amr' (which is the standard name for authentication method as described in RFC 8176). That will either be set to pwd or mfa depending on whether they simply used a password or are set up with mfa.
Next, I added a custom authorize attribute that checks for this claim. If the claim is set to pwd, the authorization handler fails. This attribute is then set on all controllers that aren't to do with MFA, that way the user can still get in to set up MFA, but nothing else.
The only downside with this technique is the dev needs to remember to add that attribute to every non MFA controller, but aside from that, it works quite well as the claims are stored in the users' cookie (which isn't modifiable), so the performance hit is very small.
Hope this helps someone else, and this is what I read as a base for my solution:
https://damienbod.com/2019/12/16/force-asp-net-core-openid-connect-client-to-require-mfa/
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/mfa?view=aspnetcore-5.0#force-aspnet-core-openid-connect-client-to-require-mfa
I have already implemented a user authentication, in which the user can log in again or register.
I would now like to avoid that the user must register again after each closing of the app. For this reason I have to request a refresh token at certain intervals (Max 1 hour, as long as the cookie is valid). my question: how do I do that best? the refresh should work for both open and closed apps. I saw the possibility of the React Native Background task, but apparently only runs when the app is closed.
You have to create a flag in AsyncStorage when the user is authenticated.
And then you have to check that flag each time on opening the app.
Here is the sample snippet.
AsyncStorage.setItem('loggedIn', true);
And in your app.js you can check this flag in constructor
AsyncStorage.getItem('loggedIn').then((value) => {
if (value) {
//user logged in logic goes here
} else {
// user logged out. You need to login him again
}
});
Considering that you need to persist user's login forever and still be able to refresh the token, one possible way is to store the user's credentials (username and password) in some secure storage like react-native-keychain and then refresh the token every time the user opens the app.
Or more precisely, automate the login with the credentials you stored whenever the user launches the app with the help of useEffect hook(componentDidMount).
Note: This is not a good implementation if your app uses push notifications. Push notifications demand the user to be authorized all the time.
What is the best way to use Expos SecureStore to save login credentials (say Email + Password) so that the iOS Keychain (and Android's Keystore system at the same time if possible) can associate it with the App that stores the credentials?
Of interest here is the third param of SecureStore.setItemAsync(…, …, options). It would be optimal if the options map was set to save the credentials in a way that iOS will (automatically) allow the User to retrieve them from the Keychain when the App is started and the User needs to log in in the future.
Using SecureStore automatically associates the keychain with the saving app. As long as you use the same key (the first parameter) your app should be able to retrieve the value (the second parameter).
There is no option exposed to automatically retrieve the app when the app is started, but you can achieve the same effect by retrieving the keys using getItemAsync when you load the root view of your app.
The options parameter controls if you need extra security around when the app can retrieve the value using the key (for instance if it can access the keys while the device is locked, or after the app is moved to a new device)
https://docs.expo.io/versions/latest/sdk/securestore
I want to implement the app in worklight using JsonStore protection i want to store password based on logined user and add those password to options in WL.JSONStore.init(collections,options). The rest of the details in data object data={};
and how do i extract the password saved WL.JSONStore.init(collections,options) options object for making api calls for rest of the functions?
My take on the question:
Storing the password in the device is indeed not a good practice to follow.
There is also the additional question of where the username and password are coming from originally? When does the sign-up (rather than log-in) happens? This is IMO crucial information.
In one of my applications I have initialized a JSONStore and encrypted it using the user's password and in the collection I saved the username.
This way, the next time the user tries to open the JSONStore (read: "to log-in"), it will try to do so with the inputted password. If this step is successful, it will then compare the inputted username with the stored username. If this step is successful as well, valid login credentials can be assumed.
var collections = {
userCredentials : {
searchFields : {
username: 'string'
}
}
};
var username, password;
username = $("#username").val();
password = $"("#password").val();
WL.JSONStore.init(collections, {password:password})
// first step is successful
.then(function() {
return WL.JSONStore.get("myCollectionName").find({username:username});
})
// second step is successful
.then(function(searchResult) {
if (searchResult[0].json.username == username) {
// valid login.
}
})
.fail(function() {
alert ("Invalid credentials, try again.);
})
Note that the above code is a bit abstract and "generic", and you will need to handle all sort of edge cases.
I highly recommend to thoroughly read all of the JSONStore documentation and training modules.
You have two options (though I am not a security expert):
Ask to user that uses the app (and therefore the JSONStore) to enter the password each time you open the app and then in the WL.JSONStore.init method check the password (if the password is correct, the store will open, otherwise, the method will fail).
Store the password in a secure storage - Keychains. For iOS see this link. For Android, I think this is the equivalent link.
So, the first time the user opens the app, you store the password and each time the user opens the app, you retrieve the password and pass it to WL JSONStore. If the user wants to update the password (e.g. you have security policy to follow), you have to update the password in the Keychain.
Of course, if you go hybrid, you will need some sort of Cordova plugin that add, reads, updates, resets the password in the keychain so you can make these actions from JavaScript.
Hope it helps!
I am trying to implement a Remember me feature in a ServiceStack-based project. I don't want to use Basic Authentication because it requires storing password in clear text in a browser cookie, so I need to come up with an alternative approach that will be easy to maintain and customized to my existing database.
I understand that ServiceStack's own support for Remember me is based on caching the IAuthSession instance in the server-side cache, which by default is an in-memory data structure that is wiped out when the website restarts (not good). Alternatively, the cache can also be based on Redis or Memcached, which is better (cached data survives website restarts) but adds more moving parts to the picture than I care to add to it.
Instead, I would like to implement the this functionality using my own database:
Table Users:
UserID (auto-incremented identity)
Username
Password
Email
Name
etc...
Table Sessions:
SessionID (auto-incremented identity)
UserID (FK to Users)
StartDateTime
EndDateTime
SessionKey (GUID)
The way I see things working is this:
On login request, AuthService creates an empty instance of my UserAuthSession class (implements IAuthSession) and calls my custom credentials provider's TryAuthenticate method, which authenticates the user against the Users table, populates UserAuthSession with relevant user data and inserts a new record into the Session table.
Then the auth session is cached in the in-memory cache and ServiceStack session cookies (ss-id and ss-pid) are created and sent to the browser.
If the user checks Remember me then additionally my custom credential provider's OnAuthenticate method creates a permanent login cookie that contains the user's username and the auto-generated Sessions.SessionKey. This cookie will help us track the user on subsequent visits even if the auth session is no longer in the cache.
Now, suppose the site has been restarted, the cache is gone, so when our user returns to the site his auth session is nowhere to be found. The current logic in AuthenticateAttribute redirects the user back to the login screen, but instead I want to change the flow so as to to try to identify the user based on my custom login cookie, i.e.:
look up the latest Sessions record for the username extracted from the login cookie
check if its SessionKey matches the key in the login cookie
if they match, then:
read the user's data from the Users table
create my custom auth session instance, fill it with user data and cache it (just like at initial login)
insert a new Sessions record with a new SessionKey value
send back to the browser a new login cookie to be used next time
if the keys don't match then send the user back to the login screen.
Does the above logic make sense?
Has anyone already implemented anything similar using ServiceStack?
If I were to proceed with this approach, what is the best course of action that doesn't involve creating my own custom version of AuthenticateAttribute? I.e. which hooks can I use to build this using the existing ServiceStack code?
This is already built for you! Just use the OrmLiteCacheClient.
In your AppHost.Configure() method, add this:
var dbCacheClient = new OrmLiteCacheClient {
DbFactory = container.Resolve<IDbConnectionFactory>()
};
dbCacheClient.InitSchema();
container.Register<ICacheClient>(dbCacheClient);
I am not sure when this particular feature was added, perhaps it wasn't available when you originally asked. It's available in v4.0.31 at least.