View Full Version : Where to plug -secret- hashing?
Dec 9th, 2010, 07:55 PM
I am using Spring security 3.0.3 (with spring-security-oauth 3.19.SS3) + Spring 3.05 + Jersey 1.4.
I am securing a bunch of web services. Using 2-legged OAUTH 1.0
Its working fine, but now I want to do 1-way encryption on the consumer secrets in the database, so only the consumers know the secret for their key. But if I do that during secret creation (when I store them in the database), I have a problem with SSOauth3.19 ... I can't figure out where to plug the hashing of the incoming secret during requests... where should I implement that? I was thinking about implementing a filter and run it before the OAuthProviderProcessingFilter is called but I am using HMAC-SHA1 during commmunication so there is a conflict there since that filter will try to hash the secret it gets from the consumer details and compare it to the incoming hashed secret...
I was thinking then about disabling HMAC-SHA1 and send the secret in plain text over SSL... then I dont have to worry about that... but still I need to some how fix the issue of the secret comparison in the filter... it sounds way too much of a hack.. is there a nice elegant way to implement this withing the API? anything to subclass or a contract to implement and then inject the concrete class?
Thanks for any insight!
Dec 10th, 2010, 09:42 AM
I am pinging again, hoping some one has a suggestion..
The spring security oauth filter chain doesn't seem to have a facility to easily inject a different password encoder, not to mention is totally not straight forward to enable plain text at the provider level... the responses I found on that regard are mostly at the consumer level... using the namespace definitions in the context file is not straight forward to enable this...
I am reaching out to see if any one can help out, I need to do the following to resolve the problem mentioned in my first post in this thread:
1. I stopped hashing the secret in the consumer before sending it, instead sending it plain text over SSL, so I need to enable the provider to accept that... I tried configuring the CoreOAuthSignatureMethodFactory to enable that in the spring context file, but it didn't seem to have any effect, any example on how to do that would be of help.
2. Even if enable plain text, the idea is not to store the secrets in plain text in the database, so I need to figure out a way to either extend the org.springframework.security.oauth.provider.Protec tedResourceProcessingFilter or override it to take the plain text secret and use an encoder before comparing the secrets (input and stored one). Similarly to how spring security does it (you can inject any type of passwordEncoder in the DaoAuthenticationProvider)...
[UPDATE] I now realize that by extending "org.springframework.security.oauth.provider.CoreOA uthProviderSupport" and injecting it using the "support-ref" attribute in the oauth provider I can actdually get the PLAINTEXT secret while its being obtained from the request and HASH it. What I don't like about this, is that it still doesn't allow to do (in communication) OAUTH1.0 standard HMAC-SHA1... because if I replace the value with a HASHED version the filter won't work with it... i still can't get the provider to accept PLAINTEXT ...
has any body resolved this problem in a different way? perhaps I am missing something that allows to have the best practice of hashing the secrets in the database and not storing them in plain text????
thanks to any one who can help out... I am kind of stuck on this one.
Dec 10th, 2010, 12:32 PM
Hi. I've never had to do this, but it seems like a reasonable request to allow a PasswordEncoder to be provided. It's just never come up before.
Would you like to open a JIRA issue and/or propose a patch?
Dec 10th, 2010, 02:01 PM
I'll put a jira request ASAP, in the mean time I have to resolve this very quick so I think I can't pursue a patch right now (at least not to do it "the right way", which I think is by following the same approach spring security's authentication manager does, which I have not explore at the source level).
Any pointers you can give me to get the provider to accept PLAINTEXT would be great... I thought I had seen an example somewhere on setting up the context file without using the new namespace (I was hoping that would give me a clue on how to set the signature method factory to accept it). Perhaps something like this:
<beans:bean name="coreOAuthSignatureMethodFactory" class="org.springframework.security.oauth.common.signatur e.CoreOAuthSignatureMethodFactory">
<beans:property name="supportPlainText" value="true"/>
But how to I get the filter to take it? It seems the filter gets initialized before it can take the spring configuration?
Thanks in advance!
Dec 10th, 2010, 04:01 PM
Ok, I added the issue here: https://jira.springsource.org/browse/SECOAUTH-36
If i get to do my suggestion (see issue) I will add a patch to it.
Dec 23rd, 2010, 08:08 PM
I finally got around to looking at this issue. The OAuth spec says that (for HMAC-SHA1 signature method) the value of the secret has to be used to calculate the hash. I could find no way to use an encoder to successfully validate a signature.
Am I missing anything? Can you think of a way to do it?
Dec 24th, 2010, 08:37 AM
I posted this same comment in JIRA:
I dont have permissions to re-open, but my intend with this comment is to hopefully do so.
I should have clarified initially, but this particular feature is for when using PLAINTEXT in the transport (secured through SSL), so assuming the secret arrives in plaintext to the server side. I am aware of the limitation if we were to use HMAC-SHA1 in the transport, then there is no way to store the secret hashed in the database. But, assuming we would rather protect the whole request with SSL (not just the secret by hashing it) and use the PLAINTEXT method, the idea behind this task is to protect the secret stored in the server (in the database), instead of storing the secret in clear when the secret and key are created we store the secret hashed in any encoding picked by the owner) in the database. So, to put it simple the purpose of this is to be able to store hashed secrets in the server side. The flows would be something like this:
1. During secret/key creation, the client receives the secret in "clear'
2. For each request the client sends the key/secret in PLAINTEXT (assuming SSL wrapping to the request due to the lack of hashing on the secret) - another nice feature there would be to enforce SSL when method is PLAINTEXT for this case from the spring configuration (today we can do that by checking the resulting SecurityContext).
3. When the secret arrives to the server, it is hashed using the encoder registered in spring security oauth (for example an encoder that would use a unique salt for each key stored along the hashed secret in the database)
4. The hashed secret is compared against the hashed secret stored in the database
and so on...
On a side note, I wasn't able to make PLAINTEXT work on the server side and this derailed me a bit... if you could provide some light on that regard it would be great.
Jan 12th, 2011, 02:38 PM
Fixed in the M2 released. See https://jira.springsource.org/browse/SECOAUTH-33.
Jan 13th, 2011, 05:39 PM
Although honestly I must be missing something, I am not sure how to enable or use this through the spring configuration in the oauth namespace? right now I have the following for the provider:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:oauth="http://www.springframework.org/schema/security/oauth"
<beans:bean name="oauthProcessingFilterEntryPoint" class="org.springframework.security.oauth.provider.OAuthP rocessingFilterEntryPoint" />
<http auto-config='true' entry-point-ref="oauthProcessingFilterEntryPoint">
<intercept-url pattern="/foo/**" access="ROLE_OAUTH_APP" />
<intercept-url pattern="/bar/**" access="ROLE_OAUTH_APP" />
<intercept-url pattern="/hoo/**" access="ROLE_OAUTH_CAMP" />
<authentication-provider user-service-ref="mycompanyConsumerDetailsService" />
<beans:bean id="mycompanyConsumerDetailsDao" class="com.mycompany.core.oauth.mycompanyConsumerDetailsD aoImpl">
<beans:property name="jdbcTemplate" ref="jdbcTemplate" />
<beans:bean name="mycompanyConsumerDetailsService" class="com.mycompany.core.oauth.mycompanyConsumerDetailsS ervice">
<beans:property name="dao" ref="mycompanyConsumerDetailsDao"/>
<oauth:provider consumer-details-service-ref="mycompanyConsumerDetailsService" />
<oauth:token-services id="tokenServices" />
How do I inject a PasswordEncoder?
Jan 14th, 2011, 10:55 AM
Add another element:
<beans:bean class="org.springframework.security.oauth.common.signatur e.CoreOAuthSignatureMethodFactory">
<beans:property name="supportPlainText" value="true"/>
<beans:property name="plainTextPasswordEncoder" ref="my_encoder"/>
And make sure annotation-based configuration (http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config) is enabled.
Aug 10th, 2011, 07:15 PM
I was wondering if you ever found a solution to this problem. I want to implement the same flow you have described above. All the solutions provided seem to relate to how the consumer would send PLAINTEXT passwords but not how the provider would process the PLAINTEXT once it arrives.
Thanks for your time and attention to this matter.
Aug 12th, 2011, 10:17 AM
After reading the previous post again, I realized simply adding the CoreOAuthSignatureMethodFactory bean def to an annotation-config-enable context file will autowire it to the filters.
Powered by vBulletin® Version 4.2.1 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.