Tomcat/Spring no longer sending emails to SMTP server using authentication - spring

I've got a strange problem with either tomcat or spring. I put up a major revision to my site and emails are no longer being delivered. I use authsmtp, which requires authentication (so they can properly account for my using of their services). No problem, I have this config in spring:
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="mail.authsmtp.com"/>
<property name="username" value="my_authsmtp_username"/>
<property name="password" value="my_authsmtp_password"/>
</bean>
works great normally. However, now I get this error:
Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 513 5.0.0 Your email system must authenticate before sending mail.
My log4j emails continue to work fine though. A test telnet to port 25 of mail.authsmtp.com worked good with a sample SMTP conversation as well. I did a diff of that mailSender config above with the previous version of the site and there are no differences (was thinking maybe I had a character off in the password). What could be the problem?
The only thing I can think of is that I initially started the server without the username/password elements above (was a bug in our deployment mechanism). So initially actually this made complete sense. Since then I've corrected it and added the username/password elements, but the problem persists. I'm thinking maybe the old config is cached somewhere? Would tomcat cache this anywhere? I've deleted the work and temp directories to no avail. Though I've actually changed the host to abcd1234authsmtp.com and it appropriately failed with this error:
Mail server connection failed; nested exception is javax.mail.MessagingException: Unknown SMTP host: mail.abcd1234authsmtp.com;
nested exception is:
java.net.UnknownHostException: mail.abcd1234authsmtp.com
So I know I'm working with the correct config and tomcat/spring sees the latest version, for some reason Spring just no longer authenticates... I'm using the same version of Spring (v3.0.2) as before as well. Any ideas?

Try adding
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">false</prop>
</props>
</property>
`

Related

Spring Security Twitter Access Token

I'm trying to get the ability to write to someone's Twitter account through Java and Spring Social.
Whenever I request write access through my application on twitter, I get the following exception:
org.springframework.social.NotAuthorizedException: Invalid or expired token
org.springframework.social.twitter.api.impl.TwitterErrorHandler.handleClientErrors(TwitterErrorHandler.java:104)
org.springframework.social.twitter.api.impl.TwitterErrorHandler.handleError(TwitterErrorHandler.java:58)
org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:537)
However, when I turn off access, I don't get this exception, but I (obviously) lose the ability to write. From all the research I have done, I have yet to be able to find anything about spring social except that I need an access token. I cannot find Spring Social documentation that tells me where to get that.
Anyway, this is in my controller:
#Autowired
ConnectionRepository connectionRepository
private Twitter getTwitter() {
connectionRepository.findPrimaryConnection(Twitter.class).api
}
#RequestMapping(value = "/connect/twitter/connect/twitter")
String loggedIn(Model model) {
if (twitter?.authorized) {
model.addAttribute("screenName", twitter.userOperations().screenName)
twitter.timelineOperations().updateStatus("Welcome to Miami #helloWorld")
HOME
}
else {
"redirect:/twitter"
}
}
My ConnectionRepository implementation is a basic one for MongoDB. I don't think it is the issue, but if it is it is nearly identical to:
https://github.com/CarloMicieli/spring-social-mongo/blob/master/src/main/java/org/springframework/social/connect/mongo/MongoConnectionRepository.java
Here is my dispatch xml:
<bean class="org.springframework.social.connect.web.ConnectController">
<property name="applicationUrl" value="http://localhost:8081/MinnesotaCows/" />
</bean>
<bean class="org.springframework.social.connect.web.ProviderSignInController">
<property name="applicationUrl" value="http://localhost:8081/MinnesotaCows/" />
<property name="signUpUrl" value="/register" />
</bean>
<bean id="twitterConnectionFactory"
class="org.springframework.social.twitter.connect.TwitterConnectionFactory">
<constructor-arg value="bUC8VEWgkfkeTXuTBuxCg" />
<constructor-arg value="5I1CNYKBCkNbsbgL2JfTNdSnSA9JVY4KHI4myxV7k4" />
</bean>
<bean id="connectionFactoryLocator"
class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
<property name="connectionFactories">
<list>
<ref bean="twitterConnectionFactory" />
</list>
</property>
</bean>
<bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors"
factory-method="noOpText" />
Note: I'm running at localhost. Could the problem be that? Since there is no callback? Also, I'm not using the signUpUrl in the ProviderSignInController for anything. I'm not quite sure what that is for either.
Anyone have any ideas on what I might be doing wrong - or how I can exactly get the access token through the API?
Thanks for your time!
I haven't tested CarloMicieli's mongo based connection repositories, but looking the code I can see that primary connection is the first connection created. This is the same behavior that the built in jdbc based repository in Spring Social has. But I think it's wrong, primary connection should be always the last issued connection/login to the provider (the connection with rank 1 can be expired even though there are newer connections).
You could try to empty the connections collection in your mongo db and test if your code works after that. If the token works then, it is the issue that I described.
I have created my own mongo based social repositories that rank the connections by timestamp and order them so that the last issued connection is the primary one. That way you can issue multiple logins and the last login will be the primary connection.
See reference from github: https://github.com/trautonen/spring-social-mongodb/tree/master/src/main/java/org/eluder/spring/social/mongodb
You also defined ConnectController which map the social provider connection paths. You can initialize login flow by doing POST request to /connect/twitter and if completed without problems should result a working connection in your connections collection in mongodb.
See full reference here: http://docs.spring.io/spring-social/docs/1.1.0.RELEASE/reference/htmlsingle/#creating-connections-with-connectcontroller

Hibernate datasource config based on login user credentials

I am developing a Java webapp with Spring 3.2.1 and Hibernate 4.1.9 tied to Postgres Advanced Server backend (for row level security). The problem I am trying to solve is how to tie the webapp login user to the to the Hibernate session. To be specific, if user A logs in, then I want the webapp connection to the database to use A' credentials (only then I will be able to filter records that A has permissions to view / alter). Webapp & database users are validated against the same ldap server.
My config info is as follows:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>com.mycom.proj.model.A</value>
<value>com.mycom.proj.model.B</value>
<value>com.mycom.proj.model.C</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${db.hibernate.dialect}</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
</bean>
Based on the above config, dataSource and sessionFactory beans are singleton's.
One approach I could take is to set the dataSource and sessionFactory to "session" scope. I am hesitant to take that approach for the following reasons:
a) If the database connection is at a session scope, then I cannot make use of connection pooling. (I think I may have to live with it)
b) I am afraid that setting the sessionFactory to session scope will mess up the Hibernate' cache mechanism.
Any thoughts / ideas about how I could solve this issue?
Thanks in advance.
Another alternative is to make all connections as an unprivileged user that has NOINHERIT membership of all the user roles. You then SET ROLE to the logged in user before running queries. If you fail to SET ROLE due to a programming error harm is minimized because you haven't granted the unprivileged user you're connecting with any rights and it hasn't inherited any, so it can't do anything.
It should be pretty easy to do this with servlet filters (if you use one connection for a whole request), CDI interceptors, a wrapper around your connection pool, using hooks provided by your connection pool implementation, or various other options to make sure it always happens.
It'd be nice if you could use SET SESSION AUTHORIZATION instead, but that requires a superuser connection. I don't recommend that applications use superuser connections even if they're just going to decrease their rights. One mistake could have very serious consequences.
I wrote in a lot more detail about this in response to a DBA question a while ago.
Usually connections pools handle per user pooled connections, so you only need an adapter to redirect getConnection() calls to getConnection(user, passwd).
Spring provides one, see: org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter
you can set the credentials on the Datasource via setCredentialsForCurrentThread() method in the login filter, for example.

Websphere, Spring, Hibernate, JAX-WS Global Transactions

I am attempting to write a demo of a JAX-WS service participating in a global transaction. This is a model my organization will be doing more of as time goes on and we need to figure it out, but I am struggling.
I have a WSDL service being invoked from a client (which is also in a Java EE servlet with the same config...in fact it is the same server, but I can see that it is calling out over the wire to itself). Both are updating their rows, and then I throw an exception but the service will not rollback.
I have annotated a method that invokes both a local DAO update and the WSDL service client with #Transactional(propagation=Propagation.REQUIRED). That service in turn invokes another method, also anotated in the same way, which in turn calls a dao method to do another db update.
app-config.xml:
<jee:jndi-lookup id="wsdlDataSource" jndi-name="${es.ds.jndi}" />
<bean id="wsdlSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="wsdlDataSource" />
<property name="packagesToScan" value="com.wsdl" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>
<prop key="hibernate.connection.driver_class">com.ibm.db2.jcc.DB2Driver</prop>
<prop key="hibernate.bytecode.provider">javassist</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.default_schema">k702prdr</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
<prop key="jta.UserTransaction">java:comp/UserTransaction</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.wsdl.db.DBTrans</value>
<value>com.wsdl.db.UsrTrans</value>
</list>
</property>
</bean>
<!-- END Data sources -->
<!-- BEGIN Hibernate config and dependencies -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager" >
</bean>
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />
I have followed some tutorials that had me go in to the Services view and add the WSTRansaction policy sets and bindings o the client and service (both generated initially from the RAD wizard), and then again into Admin Console applications->application Types->Websphere enterprise apps->my app->Service provider/client policy sets and bindings. There I added WSTransaction to client and service respectively at the parent application level (the policy inherits down to the endpoint).
But at the end of the day, no rollback is happening. Help! What am I missing? What have I misconfigured?
(update) - I found how to turn on the websphere transaction trace log in the admin console. It says (edited for brevity):
No transaction context found
Exit
Entry parm0=Operation: isAlive
No transaction context from incoming request
getTransactionManager parm0=com.ibm.ws.tx.jta.TranManagerSet#306e306e
These messages come with a bunch of what appear to be inspections of objects, and they repeat many times. Okay, so I appear to not be sending a transaction context from my client. But I still don't understand why. Anyone?
(update 2) - I discovered that my WSTRansaction policy sets for the service and client was not set to share, so i set it to share via the wsdl, and the trace log now seems to indicate that it is finding the transaction context...or at least, it's no longer explicitly saying it can't as above. It is saying some things like the following that may or may not means what i think they mean (again, edited for brevity if there is something meaningful you are not seeing, tell me, there is alot more info in there):
Entry parm0=XATransactionWrapper# 5f175f17 XAResource: com.ibm.ws.rsadapter.spi.WSRdbXaResourceImpl#5b7d5b7d enlisted: falseHas Tran Rolled Back = false mcWrapper.hashCode()490085686 parm1=XARESOURCE_NOTASSOCIATED
xa_start with flag: 0=TMNOFLAGS
setResourceStatus parm0=from NONE to REGISTERED
[at this point I see a log stmt that indicates my first update in the service]
setResourceStatus parm0=from REGISTERED to COMPLETING_ONE_PHASE
**setResourceStatus parm0=from COMPLETING_ONE_PHASE to COMMITTED**
setResourceStatus parm0=from NONE to REGISTERED
[at this point I see a log stmt that indicates my second update, which is done in the client]
setResourceStatus parm0=from REGISTERED to COMPLETING
setResourceStatus parm0=from COMPLETING to ROLLEDBACK
[at this point I see the stack trace of the hardcoded exception I am throwing]
So it seems pretty clear that while the transaction manager now sees both the client and service transaction, it thought it was supposed to complete the transaction on the service side as soon as that part was done, not realizing it was supposed to continue. Somehow I triggered a premature commit I guess. Ideas?

Can't seem to get a JNDI JDBC resource working in Liferay

No joy in the Liferay forum on this issue and the clock is ticking on this project. This may be caused by my lack of knowledge of Spring.
I have a JNDI global resource defined in server.xml and a resource link in context.xml in my Tomcat 7 /conf folder. I KNOW the JNDI resource is being loaded because I see the validation query being run as the server starts up. So far so good.
I have a portlet that just provides services to other portlets. In that portlet I have a hibernate.cfg.xml which has a session-factory that also points to the JDBC resource (don't know if this is needed or not). I also have an ext-spring.xml file in the services portlet that has the following:
<bean id="liferayHibernateSessionFactory" class="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration" >
<property name="dataSource" ref="MyJDBCResource" />
</bean>
<bean id="MyJDBCResource" class="org.springframework.jndi.JndiObjectFactoryBean" >
<property name="jndiName" value="java:comp/env/jdbc/MyJDBCResource" />
</bean>
Adding the above in ext-spring.xml fixed an issue with a bean error on that services portlet upon deployment. In that service builder built portlet, a services jar was created and I put that service jar in the Tomcat_Home/lib/ext folder so that I could use the services provided by the portlet in my portlet. So far so good. But, when I invoke the portlet method which calls the services provided by the other portlet with the JNDI references, I get a "user lacks privilege or object not found" error. It is definitely object not found. When the query is run I see absolutely NO activity on the JDBC connection specified by the JNDI resource entry and in drilling down on the connection properties I only see the HSQLDB driver in use. It should be using the MSSQL driver specified in my global resource JNDI entry as far as I understand it.
SO WHAT AM I DOING WRONG? Do I need to add some configuration entries in the portlet that invokes the services?
This seems so simple. In reading the many posts that give instructions on using JNDI/JDBC resources I seem to have followed them correctly. Is there some trick to using JNDI/JDBC resources in LR 6.1.1 and Tomcat 7 that I have missed?
Thanks (and really hoping for some answers!).
First, you could try rewrite JNDI resource reference like this:
<bean id="MyJDBCResource" class="org.springframework.jndi.JndiObjectFactoryBean" >
<property name="jndiName" value="jdbc/MyJDBCResource" />
</bean>
also, you could try different approach on JNDI resource lookup in Spring:
<jee:jndi-lookup id="MyJDBCResource" jndi-name="jdbc/MyJDBCResource" expected-type="javax.sql.DataSource" />
Not sure about first approch, but second will definitively fail early in case no JNDI resource could be found.
Hope this helps.

Why does Fusion Middleware forwarding cause issues with my Spring Security authentication process?

We have Fusion Middleware set up to handle our certificates. It's configured on port 443 and forwards its requests after handling the certification process to an instance of weblogic 11g set up on port 8001. That instance handles the authentication and returns the response through Middleware. We're using Spring 2.5.6 & Spring Security 2.0.4. It's a flex-based web application. Using firebug/firefox, I was able to verify that the server handles the authentication request properly, and attempts to return my loginSuccess.htm (configured via org.springframework.security.ui.webapp.AuthenticationProcessingFilter in my spring security config file) but I can see it's a 302 forward, it's error'd with a status from firebug saying Aborted.
Also to note, the authentication and application work fine on a standalone instance of weblogic; it's when we introduced the Fusion Middleware piece in between the web application and the client that we started to run into the authentication issues.
Here's a snippet of my AuthenticationProcessingFilter config entry:
<bean id="authenticationProcessingFilter" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/loginFailure.htm"/>
<property name="defaultTargetUrl" value="/loginSuccess.htm"/>
<property name="filterProcessesUrl" value="/login.htm"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="alwaysUseDefaultTargetUrl" value="true" />
<property name="usernameParameter" value="username"/>
<property name="passwordParameter" value="password"/>
</bean>
Any insight would be useful. We introduced Fusion Middleware since it's Oracle's recommended production approach; we were having issues with certificates beforehand.
dvuke - using Oracle Fusion Middleware the redirection can be handled via the app server - so essentially there would be no need to make changes in your spring filter.
This approach using a permanent redirect attribute in your httpd.conf file may fix the issue you describe. So any redirection in your code could be forced to always be served up over https.
NameVirtualHost *:80
Listen 80
<VirtualHost *:80>
ServerName http://server-name
Redirect permanent /contextRoot https://server-name/contextRoot
</VirtualHost>
At least an avenue to look into!

Resources