Authentication with Spring Security with usersByUsernameQuery - java

Combination of corporateId and username is unique for us in the user table.
I know spring provide a mechanism to write custom query for the authentication.
<bean id="authenticationDao"
class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref bean="dataSource" />
<property name="usersByUsernameQuery">
<value>
SELECT username,password,enabled
FROM User WHERE username=? and corporateId=?
</value>
</property>
</bean>
But problem here is we have two bind variables in the query instead of one. I am not sure how do I use spring security framework with this db structure.
Primary key of User table is UserId. Is there any to put preprocessor before calling authenticate method by which I can fetch userId by the combination of username and corporateId and then use this SELECT username,password,enabled
FROM User WHERE userid=? query.
Any help would be highly appericated.

I think you need your own authentication provider since you plan on attempting to match against username, password AND corporate id, the userDetailsService returns the object once the authentication is successful.
take a look at this question and answer, I think it will lead you down the right path
Creating a custom authentication with Acegi/Spring Security

If default JdbcDaoImpl doesn't meet your needs, you may implement your own UserDetailsService:
<bean id="authenticationDao"
class="... your implementation class ..." />

Related

Omit schema in the DERBY Query

I have created a database named 'movie_db', set default schema to APP.
Then created a sample table named 'USERS'.
My connection to DB is as follows:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="url" value="jdbc:derby://localhost:1527/movie_db"/>
<property name="username" value="root"/>
<property name="password" value="pass"/>
</bean>
Now I want to write some tests and try to execute the following query:
SELECT * FROM USERS;
What I get:
java.sql.SQLSyntaxErrorException: Table/View 'USERS' does not exist.
When I specify exactly the schema I'm using:
SELECT * FROM APP.USERS
everything works fine.
How can I omit schema name in my query?
UPDATE:
Like Bryan said, I've created a user with the name of my default schema and authorize with this login. This is the most simple way to omit schema name in the query. But still if I want to use multiple schemas the only way is to set schema explicitly.
There are basically two ways to control the default schema name:
Issue the SET SCHEMA statement after you have connected to the database.
Login as the user with the same name as the schema you wish to use.
If you haven't issued a SET SCHEMA statement, then Derby will use your username as the schema name.
So if you login as user "APP", and don't issue a SET SCHEMA statement, then your schema name will be APP.

calling methods in Spring configurations

I am tying to migrate hard coded database dependencies into the spring framework
so
Mongo m = new Mongo("192.168.0.0.1");
DB db = m.getDB("db name");
db.authenticate("user", "pass".toCharArray());
would become:
<mongo:mongo host="192.168.0.0.1" port="27017" />
<bean id="mongoDatabase"
factory-bean="mongo"
factory-method="getDB">
<constructor-arg value="db name" />
</bean>
But I am not sure how to call authenticate. It would be nice to know the best way to do this generally.
(Usernames and passwords have been changed to protect the innocent)
You can use <mongo:db-factory>.

Spring-WS SecurityInterceptor operation level

I have a Spring-WS service using PayloadRootAnnotationMethodEndpointMapping that has several interceptors:
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
<property name="interceptors">
<list>
<ref local="loggingInterceptor"/>
<ref local="validatingInterceptor"/>
<ref local="securityInterceptor"/>
</list>
</property>
</bean>
My securityIntercetor is a Wss4jSecurityInterceptor interceptor.
Everything works fine, except that the securityIntercetor is at the #Endpoint level, I want it to be at the #PayloadRoot (operation).
The way I authenticate users is using UsernameToken, then I go against LDAP and get the roles and depending on the role I want to allow/prohibit the user to execute an operation.
I assume there isn't a out of the box solution for this.
So my question is: how in the securityIntercetor can I get what operation is being called so I can check depending on my settings to allow or not the execution of a specific operation.
Or maybe you have other ideas.
Thanks.
There is no standard way of doing this.
What I did is I created another interceptor (and placing him first in the list of interceptor being called), that would save the current operation and then when Spring hits my security interceptor I will get the method from a request scoped bean that was created by my first interceptor.

Spring Security 3.0 with jdbc

I read the "Spring Security 3 database authentication with Hibernate"! But I don't know how I should implementate it into my project!
In which document I have to set the password/username/drivers/url for the database?
I have different column titles like OPERATOR_ID/USR_ID/PASSWORD
OPERATOR_ID should be the login name, USR_ID the role and the password for the login
Please, maybe you could post an example which implements my questions? Maybe for a checkout or a *.war file?
I dont think there is any configuration as such for doing this. You have to implement the UserDetailsService which has only one method loadUserByUsername to load the user and you have to implement the same to load your user information from your database using hibernate.
See here
You would need to configure a JDBCDaoImpl bean which takes a Datasource as a parameter. How you retrieve the Datasource is up to you, you may grab it from the app server or use something like Spring's DriverManagerDatasource Here is some (pseudo) config
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>your.driver.classname</value></property>
<property name="url"><value>yourDatabaseUrl</value></property>
<property name="username"><value>yourUsername</value></property>
<property name="password"><value>yourPassword</value></property>
</bean>
<bean id="dao" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="DataSource" ref="datasource" />
...
</bean>

Short-cut/Bypass Spring Security 2.0 authentication using custom AuthenticationManager

For an existing working app, I want to provide a secondary AuthenticationProvider, probably with a DaoAuthenticationProvider. Let's say it's for authenticating a "back up" password, or a prior password that was changed due to strict password policies and the user forgot the new password. ;-)
For proof of concept, what would the implementation look like for this secondaryAuthenticationProvider that will always authenticate the user regardless of the incoming credentials? (something that returns an authenticated Authentication object)
Which one of the MANY org.springframework.security.providers & subpackage classes and methods should I look at?
Example config:
<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<ref local="secondaryAuthenticationProvider"/> <!-- new AuthProv -->
<ref local="rememberMeAuthenticationProvider"/>
</list>
</property>
</bean>
If you have only one alternative password, you can declare a second DaoAuthenticationProvider backed by a special UserDetailsService, which will produce UserDetails with that alternative password.
Otherwise, you can create a custom AuthenticationProvider. Credentials check in DaoAuthenticationProvider occurs in additionalAuthenticationChecks(), so if you want to change that logic you can create a subclass of DaoAuthenticationProvider and override this method with your implementation.
For example, if you want to authenticate the user regardless of its credentials, you can override this method with an empty implementation.
Sounds to me like you should just create your own UserDetailsService that has this behavior - that would be by far the easiest way to do it.

Categories

Resources