Custom attributes for flat file authentication in CAS - java

I am an absolute novice in this entire stack so I apologize in advance if this is a very dumb question.
I'm working on setting up a local (mock) CAS service so we're able to test our apps against an auth system which at least remotely resembles something we have on our staging/production environments.
I'm using https://github.com/ubc/vagrant-cas as a starting point. I've managed to set up this by modifying cas.properties and deployerConfigContext.xml to enable me to actually pass custom attributes when a user signs in. i.e.
<bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao">
<property name="backingMap">
<map>
<entry key="uid" value="uid" />
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
<entry key="puid" value="12345678910" />
</map>
</property>
</bean>
This combined with the default org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" means that whenever I sign in with a username and password that is identical (i.e. username 'admin' password 'admin' ) then that user is signed in and the attribute puid is returned with the value of '12345678910' (this same PUID is returned for every username/password combo).
(I had to enable the attributes to be sent back in the 'Services Management' app)
What I actually need is to be able to have multiple users, all with different puid values. i.e.
username:password:1234
username2:password2:5678
etc.
I've noticed there is a org.jasig.cas.adaptors.generic.FileAuthenticationHandler but that only allows for username::password and no custom attributes. (so near yet so far).
I'm way out of my depth, I'm not a java programmer and have hit the limit of my google-fu. Any help pointing me in the right direction would be greatly appreciated.

File-based authn does not support custom attributes. You may be interested in this: https://github.com/Unicon/cas-addons/wiki/Configuring-JSON-ComplexStubPersonAttributeDao

Related

Why does my liberty configuration result in an unknown object name error?

We are trying to make our project which currently runs on WebSphere also work on Liberty.
In trying to get an MDB to work I get the following error: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2085' ('MQRC_UNKNOWN_OBJECT_NAME')
The relevant portion of the server.xml:
<jmsQueue id="jms/incomingRequestQueue" jndiName="jms/incomingRequestQueue">
<properties.mqJms baseQueueName="QUEUEIN" />
</jmsQueue>
<jmsActivationSpec id="application-ear/application-war/InboundMDB"
authDataRef="mqJms.auth">
<properties.mqJms destinationRef="jms/incomingRequestQueue" destinationType="javax.jms.Queue"
transportType="CLIENT"
hostName="${mqconnection.hostName}" port="${mqconnection.port}"
channel="${mqconnection.channel}"
messageCompression="NONE"
rescanInterval="5000"
sslCipherSuite="${mqconnection.sslCipherSuite}"
brokerControlQueue="${mqconnection.brokerControlQueue}" brokerSubQueue="${mqconnection.brokerSubQueue}"
brokerCCSubQueue="${mqconnection.brokerCCSubQueue}" brokerCCDurSubQueue="${mqconnection.brokerCCDurSubQueue}"/>
</jmsActivationSpec>
The values in the Liberty configuration were taken from WebSphere.
My question is if the reason for this error can only be that the queue name is incorrect, or if something could be missing from the configuration.
Update: the solution turned out to be to change destinationRef to destination and add useJNDI="true"
If you look at the logs on MQ and it appears to be trying to open an MQ object called jms/incomingRequestQueue, try replacing destinationRef with destinationLookup. Some methods of specifying the destination for an activation spec just pass the value straight to MQ instead of doing a lookup in the JNDI context for an admin object and fetching the right property.
See the notes in this table about the relationship between destination and destinationLookup. DestinationRef is a property that Liberty adds and I'm not sure how it all relates to the properties the resource adapter actually exposes but may be making this switch unnecessary. It all depends on what string you're trying to look up as a queue on the queue manager.
Additionally, for those who might have this issue and are using the destination property (likely in conjuntion with JMS 1.1/Java EE 6), where destinationLookup doesn't exist, you can specify useJNDI="true" as a property on the activation spec to resolve this, see the table linked above.
I was doing a migration to Open Liberty some time ago and also had some troubles. I managed to make it work, but cannot guarantee this will work for you as your case might be a bit different.
First, check carefully if baseQueueName="QUEUEIN" is correct (perhaps it is case-sensitive and does not match or something e.g. some prefix is missing).
Maybe setting a correct queueManager will help.
Here is my setup that works and it is almost the same as yours.
<resourceAdapter id="mqJMS" location="..../wmq.jmsra-9.1.4.0.rar"/>
<authData id="mqAlias" password="${env.MQ_PWD}" user="${env.MQ_USER}"/>
<jmsActivationSpec authDataRef="mqAlias" id="app-name/MyMessageBean">
<properties.mqJms destinationRef="jms/MyQ"
destinationType="javax.jms.Queue"
sslCipherSuite="${env.MQ_SSL_CIPHER_SUITE}"
channel="${env.MQ_CHANNEL}"
queueManager="${env.MQ_QUEUE_MANAGER}"
hostName="${env.MQ_HOST}" port="${env.MQ_PORT}"
transportType="CLIENT" />
</jmsActivationSpec>
<jmsQueue id="jms/MyQ" jndiName="jms/MyQ">
<properties.mqJms baseQueueName="${env.MY_QUEUE}"
baseQueueManagerName="${env.MQ_QUEUE_MANAGER}" />
</jmsQueue>
</server>
In general, the reason code 2085 means that the referenced queue could not be found on the Queue Manager.
There is this IBM Article that can be useful, especially Resolving The Problem section where you can see a short description of what they recommend to do in this case.

Spring Java Mail - How to know send mail be read, bounce or forward by receiver?

I'm new on spring and java mail, may i know how the email send by java mail is read, bounce or forward. I used google search only found the way how to send a mail. Anyone know where can get the reference on it or provide me some example on it?
Thank you.
Below is my code send mail with spring java mail:
Spring-Mail.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="xxxxxxxx#gmail.com" />
<property name="password" value="xxxxxx" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.from">xxxxxxxx#hotmail.com</prop>
</props>
</property>
</bean>
<bean id="mailMail" class="com.penril.my.MailMail">
<property name="mailSender" ref="mailSender" />
</bean>
</beans>
MailMail.java
public class MailMail
{
private JavaMailSender mailSender;
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
public void sendMail(String from, String to, String subject, String msg) {
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(msg);
mailSender.send(message);
} catch (MessagingException e) {
throw new MailParseException(e);
}
}
}
MainClass.java
public class MainClass
{
public static void main( String[] args )
{
ApplicationContext context =
new ClassPathXmlApplicationContext("Spring-Mail.xml");
MailMail mm = (MailMail) context.getBean("mailMail");
mm.sendMail("xxx123xxx#gmail.com",
"xxx234xxx#hotmail.co1m",
"Testing123",
"Testing only \n\n Hello Spring Email Sender");
}
}
There is no standard way of doing this that's accepted and honored across the board. I see that you have some options, though:
Add a header "Return-Receipt-To" with your e-mail address in the value. If the recipient of the e-mail has a client which honors this header, then a return receipt will be sent to you when the e-mail is opened. This is not reliable, mind you, as the user can always decide not to send the receipt, even if he has a client that supports it.
Add an image into your e-mail that loads from your server and put a parameter on the image that includes the user's e-mail address. When the e-mail loads, the image will load from your server. Write a script that collects the e-mail parameter and then delivers a blank image. This is also not reliable, however, as many mail clients prompt users if they wish to download images and they can always choose not to. Also, some (mostly older) e-mail clients do not support images.
Perhaps the most reliable way is not to include the message in your e-mail at all. Include only a link to a website where the message can be read, and include their e-mail address or a unique code in the link. This way, you know exactly who read the message. Of course, this has the downside that people aren't actually getting the message in their inbox, and they also may choose not to go to the website to read it.
Ultimately, I think you're going to have to come up with a creative solution to solve this problem, unless you're happy getting spotty results.
Sign up for a free account for a Cloud Based SMTP service, for example Sendgrid, which will save you the trouble of manually implementing what was suggested in the previous answer.
https://sendgrid.com/
You can send 400 emails a day on the free tier. You can manually check the status of individual messages 'opened', 'bounced' etc using the management console or there are various APIs available to do this programatically (although some are only available on paid tiers).
For example their WebHooks API will call back your server when an event (opened, bounced, click etc.) occurs:
https://sendgrid.com/docs/API_Reference/Webhooks/event.html

Struts 2 Conversation Scope Plugin with no #EndConversation

Consider below example, which I think is a very common sample of step forms.
I have a three step form which want to transfer money from an account to other :
First page gets user source account
Second page shows source account and gets destination account and the amount
Last page shows a confirmation which mention source account + destination account + amount
As you can see I need the model information in the last page too. So I use #BeginConversation for first action and #ConversationAction for second and last page.
The question is none of my actions are annotated with #EndConversation. Is it OK?!
Will the model resides in memory or it will be auto cleaned? I could not find when it is auto cleaned.
I had the similar problem. If my end action was called through a form submit I was always getting an error saying that the conversation was already closed or expired.
Of course if you don't finish the conversation, memory resources won't be released. You can get some information about this in the strut2 conversation plugin site: https://code.google.com/p/struts2-conversation/wiki/UsageGuide#Memory_Management
There you can see that it is possible to set some parameters related with the expiration of the conversation thread and the number of them that can be used at the same time:
<!-- monitoring frequency in milliseconds -->
<constant name="conversation.monitoring.frequency" value="300000"/>
<!-- idle conversation timeout in milliseconds -->
<constant name="conversation.idle.timeout" value="28800000"/>
<!-- max instances of a conversation -->
<constant name="conversation.max.instances" value="20"/>
<!-- number of timeout monitoring threads -->
<constant name="conversation.monitoring.thread.pool.size" value="20"/>
Anyway, I resolved this issue adding a redirect result in the last action which calls to an action which contains the #EndConversation tag. In it I just set the result I wanted to be the last one. The conversation fields variables are still correct set and available.
#ConversationAction(conversations = "form")
#Action(value="formSecondLast", results={#Result(name=SUCCESS, type = "redirect", location="formLast")})
public String formSecondLast() throws Exception {
//Here goes the code you want it to manipulate the conversation field data.
//Maybe save to the database or send it to the business tier.
return SUCCESS;
}
#EndConversation(conversations = "form")
#Action(value="formLast", results={#Result(name=SUCCESS, location="/jsp/form-end.jsp")})
public String formEnd() throws Exception {
// This is a dummy action that does not do anything.
// It is called just after formSecondLast ends and sends the user the jsp page.
return SUCCESS;
}

Default value not being set in database column from application

I have an application running in websphere. I have configured the data source on the server and getting the datasource from jndi.
I am using Spring Jdbc and a couple of select statements are runnign just fine.
Now I have an insert statement that is running successfully from inside 'toad' but same insert statement is failing from the application.
java.sql.SQLException: ORA-01400: cannot insert NULL into ("SCHEMA1"."XYZ"."CREATED_BY")
CREATED_BY is a VARCHAR2 (30 Byte) with DEFAULT set to 'SYS_CONTEXT ('USERENV', 'OS_USER')'
Note: I am not specifying the column in the insert statement. My statement is like the following:
Insert into SCHEMA1.XYZ(some_column, another_column, is_active) values ('sadsf','sdfsdfsdf','Y')
I am using jdbcTemplate so essentially doing:
jdbcTemplate.update(theQuery);
I am configuring my datasource like the following:
<beans:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<beans:property name="jndiName" value="jdbc/MyDatasource" />
</beans:bean>
Now I was expecting this to be coming from the username used while setting up JAAS - J2C authentication data for the data source.
I don't want to specify all the audit columns which can be easily autofilled with every query. Any help would be appreciated.
From SYS_CONTEXT
Predefined Parameters of Namespace USERENV
OS_USER Operating system user name of the client process that initiated the database session.
There is also
CLIENT_IDENTIFIER Returns an identifier that is set by the application through the DBMS_SESSION.SET_IDENTIFIER procedure, the OCI attribute OCI_ATTR_CLIENT_IDENTIFIER, or the Java class Oracle.jdbc.OracleConnection.setClientIdentifier. This attribute is used by various database components to identify lightweight application users who authenticate as the same database user.
SESSION_USER Database user name by which the current user is authenticated. This value remains the same throughout the duration of the session.
I'm not familiar with Oracle authentication, but maybe one of the latter is more suitable for your task.

Spring JmsTemplate + Security

I've just refactored some code that published to a JMS topic to use Spring's JmsTemplate class and now I'm receiving an exception stating I'm not authenticated.
Previously I created the factory, made a connection, then session etc as follows:
MQTopicConnectionFactory factory = new MQTopicConnectionFactory();
factory.setQueueManager(qMgr);
factory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
factory.setHostName(hostname);
factory.setPort(listenerPort);
factory.setChannel(channel);
// setting username and password to be empty string ==> no authentication
connection = factory.createConnection("", "");
...
connection.start();
I don't see anywhere in the JmsTemplate to set the username and password to empty strings. My config looks like this:
<bean id="jmsFactory" class="com.ibm.mq.jms.MQTopicConnectionFactory">
<property name="queueManager">
<value>ACT01</value>
</property>
<property name="hostName">
<value>xx.xx.xx.xx</value>
</property>
<property name="port">
<value>15004</value>
</property>
<property name="transportType">
<value>1</value>
</property>
<property name="channel">
<value>CONDUCTOR.ACT01</value>
</property>
</bean>
<bean id="impactJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<bean class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory">
<ref local="jmsFactory" />
</property>
</bean>
</property>
</bean>
I have also tried wrapping the jmsFactory in a UserCredentialsConnectionFactoryAdapter object to no avail:
<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="jmsFactory"/>
<property name="username" value=""/>
<property name="password" value=""/>
</bean>
Stack trace:
Caused by: com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'LOROL' with connection mode 'Client' and host name 'xx.xx.xx.xx'. Please check if the supplied username and password are correct on the QueueManager you are connecting to
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:531)
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:219)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:410)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:7855)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:7331)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:276)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6055)
at com.ibm.mq.jms.MQTopicConnectionFactory.createTopicConnection(MQTopicConnectionFactory.java:114)
at com.ibm.mq.jms.MQTopicConnectionFactory.createConnection(MQTopicConnectionFactory.java:197)
at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:343)
at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:290)
at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:227)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:461)
... 25 more
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:206)
... 37 more
A few options here...
The properties you were setting before resulted in the channel running as an administrator. To get the same functionality you can set the channel's MCAUSER to whatever ID the QMgr is running as (commonly mqm for UNIX and MUSR_MQADMIN on Windows). Boom. Done. Bob's yer uncle.
Yes, this does mean that anyone connecting to that channel is an administrator. On the other hand, this is no worse than it was before as demonstrated by your previous code working the way it did.
You can still use Spring and pass in the ID and password as described in this forum post. Just keep in mind the password is not actually checked. Whatever ID you pass in is accepted at face value unless you use a channel exit to validate it.
For more on WMQ security over client connections, see the Hardening WebSphere MQ presentation. If you wanted to actually secure access to the QMgr you'd want to set MCAUSER to a low-privileged user ID, perform setmqaut commands to authorize that ID's group and then lock down all the other channels like SYSTEM.AUTO.* and SYSTEM.DEF.* so they could not run.
I am running Websphere in my local windows machine and connecting to MQ server in Unix machine . For me only the third option worked. Setting the userID from console didn't work.I tried both mqm and MUSR_MQADMIN.
//connection created using username and password
QueueConnection connection = factory.createQueueConnection("mqm","mqm");

Categories

Resources