So, I new with Spring Security. I'm using password hashing with salt.In security xml file, it looks like:
<beans:bean id="saltSource" class="bla.bla.MyOwnSalt" scope="singleton" />
<password-encoder hash="md5" >
<salt-source ref="saltSource" />
MyOwnSalt implements SaltSource.
So passwords hash creating with salt.
Sometimes I need to create users and their passwords directly in database.
The main question is: How can I create a hash using only MD5 calculator, if I have password and salt?
I was trying to create hash from "passwordsalt". Spring password-encoder with salt-source works like: PasswordEncoder.encode("password{salt}");
So, the problem was with missed{ }
All I had to - is to look at the PasswordEncoder source code.
Related
Context
I've build a RESTful API server in Actix-Web with Rust that's hosted on a Heroku paid plan. It has n amount of publicly available endpoints to access content, alongside 3 strictly admin-only endpoints (for creating, editing, and deleting public content).
I am the only developer who'd ever need to access the admin-only endpoints - and infrequently at that. Several random users will be using the publicly available endpoints daily.
Normally, I'd implement an authentication/authorization strategy akin to this using JWTs (but obviously in Rust for my case). However, the added complexity that comes with this "more common" solution seems overkill for my simple use-case.
My theorized solution
Could I add a username and password field to the .env file in my project like so in order to match against a username and password passed in the admin-only handler functions?
... OTHER KEYS ...
USERNAME = my_really_long_random_username
PASSWORD = my_really_long_random_password
At first glance I'm storing passwords in plain text... but, there's only 1 and it's in my .env file, which is private by default.
All I'd do for the admin-only routes then is this (pseudo-code):
pub fn router_handler(passed_data) -> HttpResponse {
if passed_data.username == env.username && passed_data.password == env.password {
// CONSIDER THEM ADMIN
} else {
// BLOCK THEM AS THEY'RE NOT AUTHENTICATED
}
}
What I've tried
I have yet to try this strategy, but I'm curious about your opinions on it.
Question
Is my theorized solution secure? Does it seem reasonable given my use-case?
Response to question: jthulhu - is this what I do?
So, my .env file should look something like this:
... OTHER KEYS ...
USERNAME = a98ysnrn938qwyanr9c8yQden
PASSWORD = aosdf83h282huciquhr8291h91
where both of those hashes are the results of running my pre-determined username and password through my to_hash function which I added below (likely using a lib like this).
Then, my handler should be like this (psuedo-code):
pub fn router_handler(passed_data) -> HttpResponse {
if to_hash(passed_data.username) == env.username && to_hash(passed_data.password) == env.password {
// CONSIDER THEM ADMIN
} else {
// BLOCK THEM AS THEY'RE NOT AUTHENTICATED
}
}
You should never store passwords in plain text in a server, because if someones breaks in your server, and can read that file, they now have access to everything (whereas they might previously not). Not only that, but most people tend to reuse passwords, so storing one password in plain text means exposing several services where that password is used.
Instead, you should hash the passwords and store the hash. To perform a login, check if the hash of the given password corresponds to the one stored. This mechanism can be used with files or with databases alike, and is pretty much independent on how you actually store the hashes.
I had to migrate a legacy database with clear text password to a PostgresSQL database. I've looked up what's the best way to encrypt password in a database and found the pgcrypto extension with slow algorithm. (see pgcrypto documentation for 8.4)
The migration is done for data and everything is working well.
Now I have to write a CRUD application to handle this data.
I'm wondering what's the best way to use this strong encryption with grails ?
In my model, I've used the afterInsert event to handle this :
def afterInsert() {
Compte.executeUpdate("update Compte set hashpass=crypt(hashpass, gen_salt('bf', 8)) where id = (:compteId)", [compteId: this.id])
}
I guess that I should also check if the hashpass field is modified whenever the model is saved. But before that, is there another (best) way to achieve my goal ?
Edit : I cannot use the Spring Security bcrypt plugin here. The CRUD application that I'm writing use SSO CAS so I don't need such a plugin. The CRUD application manages accounts for another application that I don't own. I just need to create a new account, modify or delete an existing one. This is very simple. The tricky part is to hack grails so that it takes into account the password field and use a specific sql to store it to a postgreSQL database.
Edit 2 :
I've come up with the following code but it doesn't work
def beforeInsert() {
hashpass = encodePassword(hashpass);
}
def encodePassword(cleartextpwd) {
// create a key generator based upon the Blowfish cipher
KeyGenerator keygenerator = KeyGenerator.getInstance("Blowfish");
// create a key
SecretKey secretkey = keygenerator.generateKey();
// create a cipher based upon Blowfish
Cipher cipher = Cipher.getInstance(ALGORITHM);
// initialise cipher to with secret key
cipher.init(Cipher.ENCRYPT_MODE, secretkey);
// get the text to encrypt
String inputText = cleartextpwd;
// encrypt message
byte[] encrypted = cipher.doFinal(inputText.getBytes("UTF-8"));
return Base64.encodeBase64String(encrypted);
}
I get a hash that is not a blowfish hash (beginning with $2a$08$ )
Edit 3 :
I've finally came up with a cleaner grails solution after reading this wiki page : grails.org/Simple+Dynamic+Password+Codec (not enough reputation to put more than 2 links so add http:// before) and the bug report jira.grails.org/browse/GRAILS-3620
Following advice from #lukelazarovic, I've also used the algorithm from the spring security plugin.
Here is my password encoder to put into grails/utils :
import grails.plugin.springsecurity.authentication.encoding.BCryptPasswordEncoder;
class BlowfishCodec {
static encode(target) {
// TODO need to put the logcount = 8 in configuration file
return new BCryptPasswordEncoder(8).encodePassword(
target, null)
}
}
I've updated my Compte model to call my password encoder before saving / updating the data :
def beforeInsert() {
hashpass = hashpass.encodeAsBlowfish();
}
def beforeUpdate() {
if(isDirty('hashpass')) {
hashpass = hashpass.encodeAsBlowfish();
}
}
The tricky part is to hack grails so that it takes into account the
password field and use a specific sql to store it to a postgreSQL
database.
Is there any particular reason to do the hashing in database?
IMHO it's better to hash the password in Grails, therefore have a code that is not database-specific and easier to read.
For hashing passwords using Blowfish algorithm using Java or Groovy see Encryption with BlowFish in Java
The resulting hash begins with algorithm specification, iteration count and salt, separated with dollar sign - '$'. So the hash may look like "$2a$08$saltCharacters" where 2a is a algorithm, 08 is iteration count, then follows salt and after salt is the hash itself.
For broader explanation see http://www.techrepublic.com/blog/australian-technology/securing-passwords-with-blowfish. Don't mind that it concerns to Blowfish in PHP, the principles applies for Java or Groovy as well.
I'm inserting users into a H2 database as follows:
insert into users (id,username,password) VALUES(1,'user','password');
I'm also using spring security. Usually to hash passwords I'd configure Spring like this:
<bean id = "encoder" class = "org.springframework.security.crypto.password.StandardPasswordEncoder"/>
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<security:password-encoder ref="encoder" />-->
</security:authentication-provider>
</security:authentication-man
and put a hash function into the insert statement. The H2 documentation suggests I need to do this:
insert into users (id,username,password) VALUES(1 vg,'user',HASH('SHA256', STRINGTOUTF8('Password'), 1000));
but when I do, the passwords don't seem to match. I expect I'm not configuring something properly, but google isn't helping me.
Do the convesion in java, using spring
final StandardPasswordEncoder encoder = new StandardPasswordEncoder();
String hashedPassword = encoder.encode(aStringVarOfThePassword);
[WCS 7, FixPack 7, Feature Pack 6]
I need to generate a feed with certain catalog entry (product) information such as name, image(s), category, price, seo-url, descriptive attributes and so on.
To generate this feed i will use the scheduler framework and created a controller command which will be invoked after a certain time has passed.
Now i need to receive the catalog entry data of each item in a specific store/catalog.
As far as i know there are several ways to achieve this:
Access Beans
SOA (new Access Profile with specific SQL)
I tried to use Access Beans to get all necessary information but I got stuck with seo-url, price etc.
Are there more ways and what is the best practice to get a specific set of catalog entry attributes?
I suggest you study/investigate in your WCS Development environment how site map generation schedule command is implemented (SitemapGenerateCmd) and how it is calling the JSP template file (sitemap.jsp)
you need to modify a bit in your command to create a jsp template for your feed and call that template from your scheduler command you've created .
calling template command for messaging system, make sure to use following properties in ActionForward tag to register the JSP for messaging from back-end:
example:
<forward className="com.ibm.commerce.struts.ECActionForward"
name="SitemapIndexView" path="/SitemapIndex.jsp">
<set-property property="direct" value="true"/>
<set-property property="resourceClassName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommandImpl"/>
<set-property property="interfaceName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommand"/>
<set-property property="properties" value="storeDir=no"/>
<set-property property="implClassName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommandImpl"/>
</forward>
then the logic for extracting data from your product/catalog beans will be handled inside the JSP and you can easily form the output data as you want (XML, CSV, JSON .. etc)
the advantages and benefits of using this way are you can leverage Commerce Server OOTB JSTL tags , WCF tags for retrieving all information and using wcf:url for SEO URLS OOTB even you can call BOD/SOA commands using <wcf:getData tag and finally your will get more structured design that can easily maintain and reuse in future .
sitemap.jsp is a good resource for you how to iterate through catalog and sub-catalog to extract product info.
hope that those help you find your solution. need some search and understanding of existing sitemap generation utility .
Thanks.
Abed
I really appreciate it if you could ask my question.
After I call myObjectContext.myEntitySet.ToList() method in my entity framework context, the password part from connectionstring in myObjectContext.Connection.ConnectionString is gone.is it a bug?
thanks very much for your help.
This is by design. The password is removed to protect you. If you really want to keep the password there you can add the following to your connection string: Persist Security Info=True;
So then your connection string should look something like this:
Data Source=server;Initial Catalog=database;User ID=user;Password=password;Persist Security Info=True;
Be aware that this is a security risk. If your database server supports windows authentication you should use that instead. Then your connection string would be as follows:
Data Source=server;Initial Catalog=database;Integrated Security=True
As you can see this connection string doesn't contain a user name or password. Instead your windows user name and password is used. If you can you should use this instead of the former.