I have been struggling with this problem all day.
I am developing a Windows 8 app using JavaScript and HTML5. I need to restrict some functionality on the app depending of the active directory group where an user account is assigned.
The question is: how I can check if a user account belongs to a Active Directory group?
I have tried using Windows.System.UserProfile.UserInformation and Windows.Security.Credentials.UI.CredentialPicker, but none of them returns either a way to test if a user account belongs to a group, or the group where the user account is assigned.
Thanks in advance for your help.
I found a solution to perform this, which was the one I implemented, and it works. You can create a web service that validates the credentials against Active Directory, where you pass the domain, username and password, then call it from the app using WinJS.xhr. To ask for the credentials, you can use the CredentialPicker control, which returns, the domain, username, and password entered by the user.
Here is the code:
Web Service Code:
ValidateUserResult vur = new ValidateUserResult();
try
{
using (PrincipalContext context =
new PrincipalContext(ContextType.Domain, domain))
{
vur.UserCredentialsAreValid = context
.ValidateCredentials(username, password);
if (vur.UserCredentialsAreValid)
{
vur.ProcessMessageText = "Ok";
vur.ProcessMessageCode = 0;
}
else
{
vur.ProcessMessageText =
"Credenciales invalidas";
vur.ProcessMessageCode = -1;
}
}
}
catch (Exception ex)
{
vur.UserCredentialsAreValid = false;
vur.ProcessMessageText = ex.Message;
vur.ProcessMessageCode = ex.HResult;
}
return vur;
Windows 8 App:
WinJS.xhr({
type: "get"
, url: {Web Service Url}
+ "/json/{Web Service Method Name}?domain="
+ domain + "&username=" + username
+ "&password=" + password
}).then(
function (result) {
if (result.status === 200) {
// Place code here.
}
},
function (error) {
// If an error occurs, manage here
});
Related
I created a login page on my mobile app using a node js file to test the credentials. If the credentials are correct you get to the homepage, but It doesn’t remember the logged-in user, so every time you clean the RAM you have to login again.
I'm trying to save the token I get back from the backend in the device using #ionic/storage, but that's how far I can go on the logic and code. I don't really know what to do with the token. Some explaining of the logic could help a lot, or some code, or a link. I would really appreciate any help I can get!
I’m using Ionic Angular [5] and Capacitor.
My code if needed:
.ts file
senduserdata(){
var dataToSend = {
username:this.Username,
password:this.Password,
usertype:this.getSelectedSubject,
}
var url = 'http://localhost:3000/login';
this.http.post(url,{data:JSON.stringify(dataToSend)},{responseType: 'text'}).subscribe(
(data)=>{
let decoded = helper.decodeToken(data);
console.log('Decoded: ', decoded);
//the code to save it in storage
this.storage.set('loggedToken', decoded);
if(decoded.usertype === "Customer")
{
alert('Hello Customer')
}
else if(decoded.usertype === "Staff")
{
alert('Hello Staff')
}
}
)
}
node js file
//Login
app.post('/login', function (_req, res) {
var data = JSON.parse(_req.body.data);
var username = data.username;
var password = data.password;
var usertype = data.usertype;
mysqlConnection.connect(function () {
if(usertype ==="Customer"){
var query = "SELECT * from " + usertype + " Where Username = '" + username + "' And Password = '" + sha1(password) + "'";
}
else{
var query = "SELECT * from Staff Where Username = '" + username + "' And Password = '" + password + "'";
}
mysqlConnection.query(query, function (err, results, _fields) {
if (err) {
res.send(err);
}
else {
if (results.length > 0 && usertype === "Customer") {
if(results[0].Subscription === "True"){
passs = sha1(password)
const token = jwt.sign({username, passs, usertype}, 'my_secret_key_customer');
console.log(token);
res.send(token);
}
else{
console.log("Email not verified!");
res.send('Email not verified! Check your email for the verification email!');
}
}
else if (results.length > 0 && usertype === "Staff") {
passs = sha1(password)
const token1 = jwt.sign({username, passs, usertype}, 'my_secret_key_staff');
console.log(token1);
res.send(token1);
}
else {
console.log("The password or username is incorrect!");
res.send('The Password or Username is incorrect!');
}
}
})
})
});
you can use that decoded value that you saved in ionic storage as and 'id' of the user (you can read about JWT that is a way of doing this that is a standard) so you can use that value when making new requests to your node-js server so you can know which user is sending the request (it is the equivalent of been logged in on REST). you can also use the value to change which is the default page of the app when you are logged in (login page when not logged in and home page when logged in for example.)
You need to setup authentication Guards to restrict pages based on storage and also add HTTP intercept to override HTTP header and passing the JWT token to backend on each and every API call's.
JWT is a JSON based web token to securely transfer data between Backend and JSON Objects. It may contain USER ID and other some secure information. You can pass your customized data using JWT.
I am trying to seperate two different logins for the different types of users that are in the account. One of the users is a regular consumer who is able to search through the app. The other is a business dashboard where businesses get to see what users are checkedin to their business.
The problem is that when I check my two different database references, it seems it checks both of them instead of validating the first check and proceeds to pull and error saying one of my nodes is null.
The case it apprently fails is the first if check but in my database the node userType is set properly:
The problem seems to be it auth().onStateChanged where it looks for the uid of in both database references. When I try to login with a business account it successfully enters that statement and redirects, when I log in with a consumer account it tries to check the business refs if and then pulls out the error userType is null cannot read
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// This prompts the user to allow for location access
// When logged in it would allow us to show the
// nearby businesses to the user
var uid = user.uid
if(window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition(function(position){
})
}
var uid = user.uid
console.log(uid)
business.child(uid).on("value", snap => {
if(snap.val().userType == "business") {
alert("This is not a consumer account!")
firebase.auth().signOut()
window.location.href = "businesslogin.html"
} else {
consumer.child(uid).on("value", snap => {
if(snap.val().userType == "consumer") {
if(snap.val().isPhoneVerified == true) {
window.location.href = 'nearbyBusinesses.html'
} else {
window.location.href = 'loginVerification.html'
}
if(snap.val().isUserCheckedin == true){
window.location.href = "leave.html" + '#' + snap.val().checkedInBusinessId
} else {
window.location.href = "nearbyBusinesses.html"
}
}
})
}
})
}
})
The bug is in this line if(snap.val() == "business"). It needs to be if(snap.val().userType == "business"). Atleast that is what i can see imediately. Try that and see if it solves your problem
I've got a form which is used to update a user's information, both in the Firebase JSON tree and the seperate database which holds the email + password combination for the users. Whenever you want to update either the email or password, you need to provide an email + password combination for it to work.
However, when you only want to update the JSON tree you can do it without a password. My form requires you to enter your current password before anything can happen, but if you type in the wrong password it will still update the display name of the user.
So my question is, is there a way that I can require the correct password before actually updating anything in the database?
The code in my controller:
//If the user has entered a new display name
if (sharedInfo.getUser().displayName !== $scope.user.displayName) {
var isNameChanged = userLogic.changeDisplayName($scope.user);
isNameChanged.then(function(isSuccessful) {
if (isSuccessful === true) {
$scope.isSuccessful = true;
}
else {
$scope.error = 'Update failed';
}
});
}
Function in my service:
changeDisplayName: function(user) {
//Get the user ID
var userData = sharedInfo.getAuthState();
return fbRef.getSyncedReference('users/' + userData.uid).$update({displayName: user.displayName}).then(function() {
return true;
}, function(error) {
return false;
});
}
I would like to know how how to get the current user. I am making a function where the user is creating a group and would like to add the user making the group to it at the same time. I can make the group fine, that was simple enough. But I do not know how to get to the user object outside of the simple login object.
I'm sorry if there are several topics stating this already, but I have been looking for hours and have not been able to find anything that explains it. Any help would be appreciated.
The currently logged in user is returned from Simple Login's callback. This callback runs when your user authenticates, or if your user is already authenticated, it runs at the time of page load.
Take this code form the simple login docs:
var myRef = new Firebase("https://<your-firebase>.firebaseio.com");
var authClient = new FirebaseSimpleLogin(myRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log("User ID: " + user.uid + ", Provider: " + user.provider);
} else {
// user is logged out
}
});
The user object is exposed in the callback. It's only in scope during the execution of that callback, so if you want to use it outside, store it in a variable for reuse later like this:
var currentUser = {};
var myRef = new Firebase("https://<your-firebase>.firebaseio.com");
var authClient = new FirebaseSimpleLogin(myRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
currentUser = user;
} else {
// user is logged out
}
});
...
// Later on in your code (that runs some time after that login callback fires)
console.log("User ID: " + currentUser.uid + ", Provider: " + currentUser.provider);
I'm performing server-side validation in the "Accounts.onCreateUser" function so that I can pass the options object as well. I wasn't able to figure out how to do this with the validate user function.
First, I'm totally open for correct if I'm going the wrong direction so please advise.
I can't figure out how to validate password length server-side. Is it because it's already converted prior to the creation? When testing, if I enter in a single character for password it doesn't throw an error.
Accounts.onCreateUser(function (options, user) {
if (options.profile) {
user.profile = options.profile;
user.profile.user_status = "new user";
}
// Error checking
var errors = "";
if (user.username.length === 0) {
errors = errors + '<li>Email is required</li>';
}
if (user.username.length !== 0 && user.username.length < 4) {
errors = errors + '<li>Email too short</li>';
}
if (user.profile.firstname.length === 0) {
errors = errors + '<li>First name is required</li>';
}
if (user.profile.firstname.length !== 0 && user.profile.firstname.length < 2) {
errors = errors + '<li>First name is too short</li>';
}
if (user.profile.lastname.length === 0) {
errors = errors + '<li>Last name is required</li>';
}
if (user.profile.lastname.length !== 0 && user.profile.lastname.length < 2) {
errors = errors + '<li>Last name is too short</li>';
}
if (user.services.password.length === 0) {
errors = errors + '<li>Please enter a password</li>';
}
if (user.services.password.length < 7) {
errors = errors + '<li>Password requires 7 or more characters</li>';
}
if (errors) {
throw new Meteor.Error(403, errors);
} else {
return user;
}
});
I'm not using Accounts-ui. Trying to roll out my own... Being completely new with Meteor it has been a bit of a battle trying to understand account creation and verification. If there's a way to do this with ValidateNewUser function should I be using that instead?
Thank you for all your help.
I've figured out the best manner to perform this. Hope this will help others.
I'm using a method on server side to validate and returning error if there is one. Then proceeding with the Account Creation.
Meteor.call('Validate_Registration', email, password, cpassword, firstname, lastname, terms, function(error) {
if (error) {
error = error.reason;
$('#Error-Block').fadeIn().children('ul').html(error);
console.log(error);
} else {
Accounts.createUser({
username: email,
email: email,
password: password,
profile: {
firstname: firstname,
lastname: lastname
}
}, function(error) {
if (error) {
error = error.reason;
$('#Error-Block').fadeIn().children('ul').html(error);
} else {
var uid = Accounts.connection.userId();
Meteor.call('Verify_Email', uid, email);
Router.go('/email-instructions');
}
});
}
});
The only thing I'm unsure of at this point is if it's correct to use:
var uid = Accounts.connection.userId();
This seems to be local to the current user only, and is stored in local storage to the user.
Accounts-password uses SRP, which is a bit complicated so I won't describe it fully here. The actual check of the hashed tokens happens around here Basically, the password does not arrive at the server as a plain text string therefore you will not be able to enforce password policy on the server, while using SRP.
Also notably around here there is a DDP only "plaintext" login option for those who (understandably) don't want to implement SRP on their own. As advertised, it should only be used if the user is connected w/ SSL. I would probably start there.
In the meantime, you can at least do some client side enforcing until you can roll your server-side login handler.
You may also want to check out this meteorhacks article for a custom login handler tutorial.
According to the documentation, the password "is not sent in plain text over the wire", so the password string you're looking at on the server side is not the same as what the user typed in.
EDIT: At least, that's what I think.
EDIT2: Found a comment in another question that confirms it.