Using mysql database to authenticate users in Spring security? - mysql

I want to use Spring security to authenticate users in my web application..
Since am not a matured user to Spring framework ,i can't get a clear idea about how we can do the configuration settings to use jdbc-user-service ..
i had done the following configurations.but its not working
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="myDataSource"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<beans:property name="url" value="jdbc:mysql://localhost:3306/testDB"/>
<beans:property name="username" value="admin"/>
<beans:property name="password" value="admin"/>
</beans:bean>
..can anyone please help me to solve the issue with a sample config file.
Thanks in advance.

another way to do this is to create tables using the standard spring security database schema (http://static.springsource.org/spring-security/site/docs/3.0.x/reference/appendix-schema.html). Then you can simply use spring's jdbc-userservice:
<security:authentication-provider >
<security:jdbc-user-service data-source-ref="dataSource" />
<security:password-encoder hash="sha" />
</security:authentication-provider>
Or if you want to use your own schema you can override the queries like this:
<security:authentication-provider>
<securiy:jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="select username, password from users where username=?"
authorities-by-username-query="select username, roleName from role..."
role-prefix="ROLE_"
/>
</security:authentication-provider>

You usually do it with a custom UserDetailsService. The UserDetailsService is a DAO used to load data about a user when they attempt login. Have a look at the loadUserByUsername(String username) method and the UserDetails class in spring.
Yo need to define it in your context:
<bean id="myDetailsService"
class="com.company.service.impl.MyDetailsService" />
To use it you can add this to your security config:
<authentication-manager>
<authentication-provider user-service-ref="myDetailsService" />
</authentication-manager>
and all you security filters will use it.
You can ask a more specific question if you need help implementing it, but you won't have trouble IMO.

Add these lines to your <authentication-provider> tag:
<authentication-provider>
<password-encoder hash="sha-256" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="
SELECT username, password, enabled
FROM user WHERE username = ?"
authorities-by-username-query="
SELECT u.username, r.role_name
FROM user u, user_role r, assigned_role a
WHERE u.id = a.username
AND r.id = a.role_id
AND u.username = ?"
/>
</authentication-provider>
Of course you'll have to tweak the queries to match your table names.

Related

Apache Ignite use table names instead of cachename in a query

i have an application made in java that queries a schema many times (about 1000) for each request made by the user.
This was initially designed in this way many years ago and currently the code refactor would be too risky for the complexity of the methods.
Anyway, in order to leverage the DB effort i thought to introduce an Ignite layer to cache the biggest part of the data queried that is basically static, so i would expect that many of those queries will be faster and not on the DB anymore.
I've configured ignite properly on the server to cache the tables I need, and everything's fine until I tried to query on DBEaver or Squirrel and i discovered that the name of the tables to query on the Ignite DB is what in the ignite configuration is called property name=cacheName".
I don't want to put the hands on the code to change the queries one by one, so i would assume there's a way to keep the queries as the same as those are on the Oracle DB.
Example
In oracle DB i have
<Schema_Name>.<Table_Name>
and my queries in the code are something like
"select * from <Table_Name> where x"
In Ignite schema instead i have
cacheName.<Table_Name>
so in order to query this my query should be transformed in something like
"select * from cacheName.<Table_Name> where x"
Seems like in Ignite the cacheName is considered as a Schema, the problem is that each single table has different schema in this way. Should I consider to refactor all the queries or is there a way to mantain the same query format?
my configuration is something like this
Taken from one table configuration
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="<TableName>Cache"/>
<property name="cacheMode" value="PARTITIONED"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="cacheStoreFactory">
<bean class="org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory">
<property name="dataSourceBean" value="dsOracle"/>
<property name="dialect">
<bean class="org.apache.ignite.cache.store.jdbc.dialect.OracleDialect">
</bean>
</property>
<property name="types">
<list>
<bean class="org.apache.ignite.cache.store.jdbc.JdbcType">
<property name="cacheName" value="<TableName>Cache"/>
<property name="keyType" value="package.obfuscated.key"/>
<property name="valueType" value="package.obfuscated.type"/>
<property name="databaseSchema" value="<DBSchemaName>"/>
<property name="databaseTable" value="<TableName>"/>
<property name="keyFields">
<list>
<bean class="org.apache.ignite.cache.store.jdbc.JdbcTypeField">
.
.
.
[list of table fields]
.
.
Thanks a lot
In your cache definition, you can set the SQL Schema:
var cacheConfiguration = new CacheConfiguration<PersonKey,Person>()
.setName("PERSON_CACHE")
.setSqlSchema("MY_SCHEMA")
.setCacheMode(CacheMode.PARTITIONED)
.setIndexedTypes(PersonKey.class, Person.class);
var cache = ignite.<PersonKey,Person>getOrCreateCache(cacheConfiguration);
This creates a table that's visible in SQL as MY_SCHEMA.Person.

REST API failure - org.hibernate.exception.SQLGrammarException: could not prepare statement

I'm working on a Java EE 7 project that connects to a MySQL database. When I try to make any API calls via Swagger Inspector (while the server is running and the .war is deployed, of course), I get the below errors:
org.hibernate.exception.SQLGrammarException: could not prepare statement
and
`Caused by: org.h2.jdbc.JdbcSQLException: Table "APARTMENTS" not found; SQL statement:
select apartment0_.id as id1_0_, apartment0_.apt as apt2_0_, apartment0_.city as city3_0_, apartment0_.country as country4_0_, apartment0_.numberOfBedrooms as numberOf5_0_, apartment0_.postalCode as postalCo6_0_, apartment0_.state as state7_0_, apartment0_.street as street8_0_ from apartments apartment0_ order by apartment0_.postalCode [42102-197]`
The things that stand out to me are that, first, I'm not using Hibernate to my knowledge. Pretty sure I'm using JPQL. Second, I'm not trying to connect to a H2 database. So why would I get errors related to technology I'm not using?
I'm using Intellij and was able to add the correct MySQL DB within the IDE.
Here's an example of one of the SQL query methods, in case I really am somehow using incorrect syntax:
public List findAll() {
TypedQuery query = em.createQuery("SELECT a from Apartment a order by a.postalCode",Apartment.class);
return query.getResultList();
}`
Pretty lost and confused, and new to this, so any help would be appreciated!
Edit (8/11/21 5:11PM CST) to add persistence.xml:
` <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
version="3.0">
<persistence-unit name="rentRantPU">
<class>com.rentRant.rentRant.model.Apartment</class>
<class>com.rentRant.rentRant.model.User</class>
<class>com.rentRant.rentRant.model.Review</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/rentRant"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="****"/>
</properties>
</persistence-unit>
</persistence>`

Can Spring Batch use MySQL for its internal BATCH_ tables?

I have been using Oracle for this without any trouble but I then had to switch it all over to use MySQL and am seeing this error during initialization:
org.springframework.dao.DataAccessResourceFailureException: Could not obtain sequence value; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown table 'BATCH_JOB_SEQ' in field list
The tables are present so its something else going wrong here. After debugging I captured the actual sql it was trying to perform to get the sequence:
select BATCH_JOB_SEQ.nextval from dual;
Which is obviously an Oracle statement!
My config states this to setup the connection:
<bean id="springDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://10.252.205.5:3306/MASKNG" />
<property name="username" value="MASKNG" />
<property name="password" value="maskng" />
</bean>
Any help appreciated...
jobRepositoryFactoryBean.setDatabaseType(“mysql”)
Seems like there is no BATCH_JOB_SEQ created here in MySQL.
You need to create the sequence for that. Refer How do I create a sequence in MySQL? for creating sequence.

Auto creation of database tables using JDO

I am new to JDO and MySQL. In my project, i want that all entities should be converted in table automatically.
I had start using the JDO and defined properties like this,
javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.api.jdo.JDOPersistenceManagerFactory
datanucleus.autoCreateSchema=true
datanucleus.validateTables=false
datanucleus.validateConstraints=false
datanucleus.query.sql.allowAll = true
javax.jdo.option.ConnectionDriverName=com.mysql.jdbc.Driver
javax.jdo.option.ConnectionURL=jdbc:mysql://127.0.0.1:3306/db_name
javax.jdo.option.ConnectionUserName=user
javax.jdo.option.ConnectionPassword=123456
javax.jdo.option.Mapping=hsql
Sample entity:
#PersistenceCapable(identityType = IdentityType.APPLICATION, table = "heartbeat")
public class HeartBeat implements Serializable{
#PrimaryKey
#Column(length=128)
private String userId;
.......
}
Now, when i compile or run my application the tables are not being auto created. I am not sure which property i should use for auto creation of tables based on the entities created.
Please bear with my question as i am new to JDO and MySQL integration.
Thanks in advance.
For JDO, if you want to create the schema for "tables" during the persistence process you tell DataNucleus by using this property, datanucleus.schema.autoCreateTables.
To auto create "columns" use datanucleus.schema.autoCreateColumns, and for "constraints" use datanucleus.schema.autoCreateConstraints. Set the properties to true.
<property name="datanucleus.schema.autoCreateTables" value="true"/>
<property name="datanucleus.schema.autoCreateColumns" value="true"/>
<property name="datanucleus.schema.autoCreateConstraints" value="true"/>
Shortcut for the three, use datanucleus.schema.autoCreateAll and set to true.
<!-- shortcut for the three -->
<property name="datanucleus.schema.autoCreateAll" value="true"/>
You can check the documentations here http://www.datanucleus.org/products/accessplatform_4_1/jdo/schema.html
Defined your JDO properties like this;
datanucleus.schema.autoCreateTables=true
datanucleus.schema.autoCreateColumns=true
datanucleus.schema.autoCreateConstraints=true
or shortcut
datanucleus.schema.autoCreateAll=true

Create a cover index with "Include" columns using nhibernate mapping file

I need to create a non-clustered index with INCLUDE columns (see the <create> tag below). Here's the mapping file:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="MyApp" assembly="MyApp">
<class name="User" table="user" >
<id name="Id" type="Guid" column="user_id">
<generator class="guid.comb"/>
</id>
<property name="Name" column="name" not-null="true" />
<property name="Phone" column="phone" />
<property name="Zipcode" column="zipcode" />
</class>
<database-object>
<create>
CREATE NONCLUSTERED INDEX [IX_user_zipcode_id]
ON User (Zipcode)
INCLUDE (Name, Phone)
</create>
<drop>
DROP INDEX IX_user_zipcode_id
</drop>
<dialect-scope name="NHibernate.Dialect.MsSql2000Dialect"/>
<dialect-scope name="NHibernate.Dialect.MsSql2005Dialect"/>
<dialect-scope name="NHibernate.Dialect.MsSql2008Dialect"/>
</database-object>
</hibernate-mapping>
The problem I'm having is the index is not created at all. Nothing appears to be happening. This is my first time using <database-object> so I may be doing something wrong here.
I'm guessing INCLUDE is Sql Server specific which is why the dialect-scope is there. I know how to create a single and multi-column index, but this is not what I want. I want a single column index on zipcode and all other columns in the User table part of the INCLUDE clause of the query. Is there any way to create this type of index using the mapping file or some other way?
This is probably a long shot, but it would be nice to not have to specify every column but the indexed one in the INCLUDE part of the query... Instead to just let nhibernate add any new columns to the index that are added as properties to the mapping file.
So part of the problem was indeed my lack of understanding the database-object tag due mostly to poor documentation. From what I've gathered, the <create> and <drop> tags are only used when using SchemaExport like so:
Dim schemaExport As SchemaExport = New SchemaExport(NhibernateConfiguration)
schemaExport.Execute(False, True, False)
My app doesn't create the schema using that class. Instead it uses SchemaUpdate so the schema isn't blown away every time (the database may already exist on the users machine):
Dim schemaUpdate As SchemaUpdate = New SchemaUpdate(NhibernateConfiguration)
schemaUpdate.Execute(False, True)
That was the problem. The next logical question to ask is then how do you execute sql using SchemaUpdate. The answer... you can't. See this post: https://forum.hibernate.org/viewtopic.php?f=6&t=969584&view=next
Alas I am left to use raw sql. Maybe some day they will add an <update> tag.