I'm looking for simple way of verifying an arbitrary Azure Table connection string that uses a SAS such as the one below using the Azure Storage's Java SDK:
https://example.table.core.windows.net/example?sig=aaabbbcccdddeeefffggghhh%3D&se=2020-01-01T00%3A00%3A00Z&sv=2015-04-05&tn=example&sp=raud
I tried a bunch of different methods exposed by the CloudTable api, but none of them works.
CloudTable.exists() throws a StorageException, regardless of whether the credentials are valid
getName(), getStorageUri(), getUri(), and other getters - all work locally, regardless of the credentials
getServiceClient().downloadServiceProperties() and getServiceClient().getServiceStats() also throw various exceptions, while getServiceClient().getEndpoint() and getServiceClient().getCredentials() and others always work locally.
Why don't I just query the Table for a row or two? Well, in many cases I need to verify a SAS that gives only write or update premissions (without delete or read permissions), and I do not want to execute a statement that changes something in the table just to check the credentials.
To answer your questions:
CloudTable.exists() throws a StorageException, regardless of whether
the credentials are valid
I believe there's a bug with the SDK when using this method with SAS Token. I remember running into the same issue some time back.
getName(), getStorageUri(), getUri(), and other getters - all work
locally, regardless of the credentials
These will work as they don't make network call. They simply use the data available to them in the different instance variables and return the data.
getServiceClient().downloadServiceProperties() and
getServiceClient().getServiceStats() also throw various exceptions,
while getServiceClient().getEndpoint() and
getServiceClient().getCredentials() and others always work locally.
In order for getServiceClient().someMethod() to work using SAS, you would need Account SAS instead of Service SAS (which you're using right now).
Why don't I just query the Table for a row or two? Well, in many cases
I need to verify a SAS that gives only write or update premissions
(without delete or read permissions), and I do not want to execute a
statement that changes something in the table just to check the
credentials.
One possible way to check the validity of a SAS Token for write operation is to perform a write operation which you know will fail with an error. For example, you can try to insert an entity which is already there. In this case, you should get a Conflict (409) error. Other thing you could try to do is perform an optimistic write by specifying some random Etag value and check for Precondition Failed (412) error. If you get a 403 error or 404 error, that would indicate there's something wrong with your SAS token.
Related
I have created a java program that has a login screen. It takes two inputs, discordID and key.
The discordID and key are located inside of an JSON file that is automatically updated by a Discord bot that i have. The bot is made in Python.
I want to use MySQL for handling the user login requests. So my question is...
Can i open up the server for public and handle user login requests? And if that works i want to return True or False depending if the credetials match the ones in the DataBase.
Was thinking at mongoDB for example. There you can return True or False depending if the credentials from the user equals to the ones you have in the database.
It is possible if you create another app just to accept this info over RESTful API but my concern is a different one. Have you given a thought how you would transfer the ID and Key. Are you planning on setting up SSL/HTTPS because that's what you would need to prevent man-in-the-middle attacks.
I have a java application running in ECS in which I want to read data from table in account 1 (source_table) and write it to a table in account 2 (destination_table). I created two dynamodb clients with different credential providers - for source_table client I'm using an STSAssumeRoleSessionCredentialsProvider with the arn of a role in account 1; for destination client I'm using DefaultAWSCredentialsProviderChain.
The assume role bit works and I'm able to read using the source client but using the destination client does not work - it still tries to use the assumed role credentials when trying to write to destination_table and fails with unauthorized error (assumed-role is not authorized to perform Put Item).
I tried using EC2ContainerCredentialsProviderWrapper on the destination client but same error.
Should this work? Or are the credentials shared under the hood which makes it impossible to have two different AWSCredentialProviders running simultaneously like this?
I noticed this answer which uses static credentials and apparently works, so I'm at a loss why this doesn't work.
I figured it out with some help from AWS support. It was a problem with my IAM configuration on the role in account 2. I was misled by the error message which said 'assumed-role is not authorized to perform Put Item' when in fact my original account 2 role itself was unable to do so.
We are trying to access the kerberized Hadoop cluster(Cloudera distribution) using code(java) but getting the below exception.
Caused by: javax.security.auth.login.LoginException: Unable to obtain
password from user at
com.sun.security.auth.module.Krb5LoginModule.promptForPass(Krb5LoginModule.java:897)
at
com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5Login
Module.java:760) at
com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
We have used the property "hadoop.security.authentication" as kerberos,fs.defaultFS as hdfs://devha:8020 and passed the keytabfilepath in the userinformationgroup.
First, read the comments on your question. Good stuff.
Taking a step back since that information can be overwhelming there's two possible ways to authenticate to a Hadoop cluster. A user will normally use a username (principal) and password. An application will normally use a principal and a keytab file. A keytab file is created by the Kerberos administrator using the 'kadmin' application.
Furthermore there's the concept of a "Login" user - an application wide default, or a "Current" user that could be specific to your current need. You'll often use the former to access resources on your local cluster and the latter to access resources on an external cluster.
Since I'm using the latter I can give you a quick code snippet to get you started. For initialization:
UserGroupInformation.setConfiguration(configuration);
where "configuration" is either read from the standard location (/etc/hadoop) or generated on the fly. Note - that sets a static value so you need to be very careful!
For the individual user (application) I use
UserGroupApplication user = UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal, keytabFile);
there are several variants of this method - e.g., do they take username or keytab file? Do they set the "Login" user or do they return a new UserGroupInformation object? Be careful you understand the consequences of which one you're using since some set global values.
You now have to wrap your calls to the cluster in a doAs() call:
user.doAs(new PrivilegedExceptionAction<Void>() {
public Void run() throws Exception {
// do all of your hadoop calls here
return null;
}
}
I don't recall if you need to do this if you're always using the "Login" user. We need to support both local and external clusters and for us it's easiest to always wrap everything like this. It means we only need to set "user" once, at the start of the action.
See the resources mentioned above if you want details on user impersonation, using SSL encryption (rpc.privacy), etc.
I have this registration page which works fine ,but for the email field I need to make sure that the email is correct and valid
1 : Correct
2 : Valid
for the correct email add i am using java script validation for maintaining
abc#def.com
well that is working fine
but my question is , Is there any web service or java API to make sure whether the mail ID actually is existing and registered
Like my mail id is : hussainABCD#gmail.com
this is actually a existing ID
but i may try hussain5555#gmail.com,hussain1111#gmail.com,hussain8888#gmail.com,
these will pass the java script validation but are not existing in reality
do we have any way to make sure that the mail id exists ??
The only way to check if an email address actually exists is to send an email to it and let the user respond on that.
For example:
a confirmation code that needs to be filled in your website
a link, going to your website, that needs to be visited
And still it is uncertain whether the email is existing afterwards, as it is easy to simply create a temporary email to pass the validation and delete it afterwards.
Instead of validating email addresses you can use the Google API to let your users sign in using their account. It is also possible to use OpenID on a similar way.
This probably isn't possible using existing services and/or API's, since it could be quite a security risk. Use an email with a validation link if you want to be sure the address exists. Or OpenID, as mentioned by BalusC.
I am new to grails and trying to create a form which allows a user to change the email address associated with his/her account for a site I am creating.
It asks for the user for their current password and also for the new email address they want to use.
If the user enters the wrong password or an invalid email address then it should reject them with an appropriate error message.
Now the email validation can be done through constraints in grails, but the password change has to match their current password. I have implemented this check as a method on a service class.
See code below:
def saveEmail =
{
def client = ClientUser.get(session.clientUserID)
client.email = params.email
if(clientUserService.checkPassword(session.clientUserID , params.password) ==false)
{
flash.message = "Incorrect Password"
client.discard()
redirect(action:'changeEmail')
}
else if(!client.validate())
{
flash.message = "Invalid Email Address"
redirect(action:'changeEmail')
}
else
{
client.save();
session.clientUserID = null;
flash.message = "Your email address has been changed, please login again"
redirect(controller: 'clientLogin' , action:'index')
}
}
Now what I noticed that was odd was that if I entered an invalid email then it would not save the changes (as expected) BUT if I entered the wrong password and a valid email then it would save the changes and even write them back into the database even though it would give the correct "invalid password" error message.
I was puzzled so set break points in all the if/else if/else blocks and found that it was hitting the first if statement as expected and not hitting the others , so it would never come accross a call to the save() method, yet it was saved anyway.
After a little research I came accross documentation for the discard() method which you can see used in the code above. So I added this but still no avail. I even tried using discard then reloading the client object from the DB again but still no dice.
This is very frustrating and I would be grateful for any help, since I think that this should surely not be a complicated requirement!
Grails closes your Hibernate session at the end of the web request, which will flush out the changed object. The object's connected to your Hibernate session because you got hold of it via Hibernate (get()). If you want to avoid having the change flushed, you need to use discard().
This is done automatically by a failing validator, which is why you're not having to do it for a validation fail.
You'd simplify the code, however, by either moving this logic to a custom validator on one of your ClientUser fields, which would automatically discard the object on failure, or by using a Grails command object, which could also encapsulate the verification logic. Then you'd just check for errors on the command object.
Using get() method retrieve data in read-write mode, so if you change anything it will be persist.Use read() method that can retrieve data in read-only mode so if you change anything then need to use save() method.That will resolve your problem.
Take a look at this http://grails.org/doc/latest/guide/GORM.html#basicCRUD
Use read method that retrieves an instance of the domain class for the specified id in a read-only state.
See the Grails documentation about read.
You are just doing flash which has nothing to do with rolling back transaction.
In the event of error throw RuntimeException and it will roll back your changes to the database.
After an R & D, I figure out that we need to clear a whole session like:
session.clear()
According to the documentation :
Completely clear the session. Evict all loaded instances and cancel
all pending saves, updates and deletions. Do not close open iterators
or instances of ScrollableResults.
We need to properly cleanup the hibernate session. In result the session is return to usable state and for future use it will not impact by the earlier error.