I've got an Java application running on tomcat6.
I'm using spring 3.0.4 and spring security 3.0.5.
to protect the access of my dao methods i want to use the spring security MethodSecurityInterceptor. but this one doesn't actually "intercept" access at all.
It is configured like this:
<bean id="securityInterceptor" class="org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager">
<ref bean="authenticationManager"/>
</property>
<property name="accessDecisionManager">
<ref bean="accessDecisionManager"/>
</property>
<property name="securityMetadataSource">
<value>
com.xkst.dao.InvoiceDao.*=ROLE_ADMIN
com.xkst.dao.UserDao.*=ROLE_ADMIN
</value>
</property>
</bean>
According to the configuration every access of any of the methods of the UserDao should be intercepted an controlled.
The methods to be protected get accessed by a rich client Java application. To make the service available for the client I use the spring HttpInvokerServiceExporter.
The dao classes are not exported directly. there is a single serviceclass being exported providing a single point of access for the client.
On the client side I've got this clientContext.xml file which references the exported service on the server.
In the client code I just load the context and pick the exported bean out of it
public class SecurityTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("clientContext.xml");
EntityServiceInterface serverService = (EntityServiceInterface) ctx.getBean("entityServiceInterface");
List<UserEntity> users = serverService.performGetAllUsers();
for(UserEntity user : users) {
System.out.println(user.getUserName());
}
}
here i can just invoke any method of the 'serverService' on my client which should be protected by the 'MethodSecurityInterceptor' without authenticating. I can query all data from my 'UserDao'.
I really don't know what the missing link is.
authenticationManager and accessDecisionManager are configured as well. there is no error message at the startup of the server. it even logs the creation of the "secured methods" like:
2011-08-01 10:38:48,675 INFO MethodDefinitionMap:75 - Adding secure method [public java.util.List com.xkst.dao.UserDao.findAll()] with attributes [[ROLE_ADMIN]]
So what am I doing wrong?
Related
I have a spring integration application with a requirement of 2 DefaultMessageListenerContainer (with transactionManager) and 2 jms:outbound-channel-adapter.
I have configured each listener container with "property name="connectionFactory" ref="jmsConnectionFactory" and also "property name="transactionManager" ref="platformTransactionManager" .
But for the transaction manager i have used again a different jmsConnectionFactory . I am not using a CachingConnectionFactory in the listener container but using it in platformTransactionManager . For jms:outbound-channel-adapter again i am using the same jmsConnectionFactory which i have used in listener container.
My problem is that with this configuration i am hitting the no. of connections exceeding the limit (150) to a MQ channel in a high load condition.
I tried many different ways but i don't see the no. of connection getting down once it gets up , using below configuration for cachingFactory
CachingConnectionFactory cachingConnectionFactory = new
CachingConnectionFactory(factory);
cachingConnectionFactory.setCacheConsumers(true);
cachingConnectionFactory.setCacheProducers(true);
cachingConnectionFactory.setSessionCacheSize(16);`
i tried
1)sharing the jmsConnectionFactory between the listenerContainer and the platformTransactionManager but the txn doesn't work correctly as i see the messages getting sent in incorrect order
2)using the cachingConenctionFactory in thelistenerContainer` , but still i see the same no. of connections
Should i use 3 different jmsConnectionFactory for the listener, txnmanager and the sender?
What would be best configuration here, please suggest , many thanks!
I think with IBM MQ you can't use CachingConnectionFactory, but instead this one as:
<bean id="connectionFactory" class="org.springframework.jms.connection.DelegatingConnectionFactory">
<property name="targetConnectionFactory" ref="imbMqFactory"/>
<property name="shouldStopConnections" value="true"/>
</bean>
This single connectionFactory must be used from the TX manager and from the containers.
I have a ws inbound gateway configuration, which accepts soap request. And I have configured a SoapEndpointInterceptor for the same.
<int-ws:inbound-gateway id="inboundWsGateway" request-channel="requestChannel" mapped-request-headers="*" reply-channel="responseChannel" error-channel="errorChannel" />
<bean class="org.springframework.ws.server.endpoint.mapping.UriEndpointMapping">
<property name="defaultEndpoint" ref="inboundWsGateway"/>
<property name="interceptors">
<array>
<ref bean="messageEndpointInterceptor"/>
</array>
</property>
in the MessageEndPointInterceptor.handleRequest() method, I am trying to get the soap header and add new element
public boolean handleRequest(final MessageContext messageContext, final Object endpoint) {
final SoapMessage soapRequestMessage = (SoapMessage) messageContext.getRequest();
final SoapHeaderElement soapHeaderElement = soapRequestMessage.getSoapHeader().addHeaderElement(qname);
}
Since the incoming soap request is not having any soap:header, soapRequestMessage.getSoapHeader() is returning null. Please let me know how to handle this scenario
Your scenario isn't correct.
You receive request, therefore you have to live with it as is. It is immutable, you can't modify it.
Consider some other hooks to provide that additional info, e.g. MessageHeaders after <int-ws:inbound-gateway>.
You can add new SoapHeaderElement only if you are the owner of the message, e.g. if you use SoapMessageFactory directly, or if you send a WebServise message.
Your inbound message modification looks like sacrilege :).
I am facing issue with the int-http:outbound-gateway when I am passing a rest-template which holds the basic credentials at the initial time. But, if any one changes credentials in database, rest-template cannot get those updated credential dynamically.
My code,
<int-http:outbound-gateway id="OutboundGateway"
request-channel="sendDataToContentType"
url="http://localhost:8080"
expected-response-type="java.lang.String"
rest-template="restTemplate"/>
<bean id="httpComponentsMessageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
<property name="credentials">
<bean class="org.apache.http.auth.UsernamePasswordCredentials">
<constructor-arg value="${fromDatabase.userName}"/>
<constructor-arg value="${fromDatabase.password}"/>
</bean>
</property>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<constructor-arg>
<bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="httpClient" value="#{httpComponentsMessageSender.httpClient}"/>
</bean>
</constructor-arg>
Is there any solution for this?
You don't need to do anything with the rest-template. There is need really just update the credentials on the underlying HttpClient.
I'd do that similar to the org.springframework.ws.transport.http.HttpComponentsMessageSender code:
((org.apache.http.impl.client.DefaultHttpClient) getHttpClient())
.getCredentialsProvider().setCredentials(authScope, credentials);
I mean in case of changing credential in the DB you should retrieve that #{httpComponentsMessageSender.httpClient} in your service and call that code.
In fact the credentials are used for each request:
context.setAttribute(
ClientContext.CREDS_PROVIDER,
getCredentialsProvider());
return context;
where it is used from the AbstractHttpClient.doExecute().
So, update the credentials on the HttpClient in one place has effect for the next HTTP Request from the <int-http:outbound-gateway>.
UPDATE
But, in this approach a new httpClient instance is being passed
Right, you can use the HttpClientBuilder but only once, on the initialization phase. I mean you need it for the httpClient injection to the httpComponentsMessageSender.
And the reason for that is because you can pass there (HttpClientBuilder) your own CredentialsProvider. When the same setCredentials(authScope, credentials) can be used from your DB service.
How can I start my scheduler on startup of Alfresco server?
Liferay provide onstartup server event. Is there any similar kind of functionality available in the Alfresco where can I start my Cron job on start of Alfresco server?
It does not make sense to use cron or a similar service if you want to run custom code at startup time. Add your custom Spring managed bean derived from org.springframework.extensions.surf.util.AbstractLifecycleBean to a file tomcat/shared/classes/alfresco/extension/startup-context.xml (or equivalent). Put your code in the onBootstrap method.
Another good way to to this is to extend the AbstractModuleComponent implementing the method executeInternal and in the Spring configuration set the executeOnlyOnce to false.
In this way your custom code will be executed every time Alfresco starts.
Below an example of a Spring configuration:
<bean id="initJobsComponent" class="com.sourcesense.alfresco.component.InitJobsComponent" parent="module.baseComponent" >
<property name="moduleId" value="myModuleId" />
<property name="name" value="initComponent" />
<property name="description" value="You description" />
<property name="sinceVersion" value="1.0" />
<property name="appliesFromVersion" value="1.0" />
<property name="executeOnceOnly" value="false"/>
</bean>
Your Java class must extend AbstractModuleComponent:
public class InitJobsComponent extends AbstractModuleComponent {
...
#Override
protected void executeInternal() throws Throwable {
//put here your custom code
}
...
}
Hope this helps.
To fit your need you could launch execution of your job by appending it to alfresco launch script.
Edit :
/etc/init.d/alfresco
Put into "start" section your job, example:
case $1 in
start)
sh YOUR_CRON_JOB
[....]
;;
I have moderate experience in developing web applications using spring.net 4.0 , nhibernate 3.0 for ASP.net based web applications. Recently I ran into a situation where I needed to use spring.net to inject my service dependencies which belong to the WorkerRole class. I created the app.config file as I normally did with the web.config files on for spring. Here it is for clarity. (I have excluded the root nodes)
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web" requirePermission="false" />
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" requirePermission="false" />
<section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<!-- Application services and data access that has been previously developed and tested-->
<resource uri="assembly://DataAccess/data-access-config.xml" />
<resource uri="assembly://Services/service-config.xml" />
<resource uri="AOP.xml" />
<resource uri="DI.xml"/>
</context>
<parsers>
<parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" />
<parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data" />
<parser type="Spring.Aop.Config.AopNamespaceParser, Spring.Aop" />
</parsers>
</spring>
Similarly Here's the AOP.xml
<object id="FilterServiceProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="proxyInterfaces" value="Domain.IFilterService"/>
<property name="target" ref="FilterService"/>
<property name="interceptorNames">
<list>
<value>UnhandledExceptionThrowsAdvice</value>
<value>PerformanceLoggingAroundAdvice</value>
</list>
</property>
</object>
</objects>
and the DI.xml
<object type="FilterMt.WorkerRole, FilterMt" >
<property name="FilterMtService1" ref="FilterServiceProxy"/>
</object>
However, I was unable to inject any dependencies into the worker role. Can someone please let me know what I am doing wrong here ? Is there a different way to configure Spring.net DI for windows azure applications ?
I don't get any configuration errors but I see that the dependencies have not been injected because the property object to which I've tried injection, remains null.
Based on my experience, you cannot inject anything into your WorkerRole class (the class that implements RoleEntryPoint). What I do, so far with Unity (I also built my own helper for Unity to help me inject Azure settings), is that I have my own infrastructure that runs and is built by Unity, but I create it in the code for the worker role.
For example, I initialize the dependency container in my OnStart() method of RoleEntry point, where I resolve anything I need. Then in my Run() method I call a method on my resolved dependency.
Here is a quick, stripped off version of my RoleEntryPoint's implementation:
public class WorkerRole : RoleEntryPoint
{
private UnityServiceHost _serviceHost;
private UnityContainer _container;
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("FIB.Worker entry point called", "Information");
using (this._container = new UnityContainer())
{
this._container.LoadConfiguration();
IWorker someWorker = this._container.Resolve<IWorker>();
someWorker.Start();
IWorker otherWorker = this._container.Resolve<IWorker>("otherWorker");
otherWorker.Start();
while (true)
{
// sleep 30 minutes. we don't really need to do anything here.
Thread.Sleep(1800000);
Trace.WriteLine("Working", "Information");
}
}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
this.CreateServiceHost();
return base.OnStart();
}
public override void OnStop()
{
this._serviceHost.Close(TimeSpan.FromSeconds(30));
base.OnStop();
}
private void CreateServiceHost()
{
this._serviceHost = new UnityServiceHost(typeof(MyService));
var binding = new NetTcpBinding(SecurityMode.None);
RoleInstanceEndpoint externalEndPoint =
RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["ServiceEndpoint"];
string endpoint = String.Format(
"net.tcp://{0}/MyService", externalEndPoint.IPEndpoint);
this._serviceHost.AddServiceEndpoint(typeof(IMyService), binding, endpoint);
this._serviceHost.Open();
}
As you can see, my own logic is IWorker interface and I can have as many implementations as I want, and I instiate them in my Run() method. What I do more is to have a WCF Service, again entirely configured via DI with Unity. Here is my IWorker interface:
public interface IWorker : IDisposable
{
void Start();
void Stop();
void DoWork();
}
And that's it. I don't have any "hard" dependencies in my WorkerRole, just the Unity Container. And I have very complex DIs in my two workers, everything works pretty well.
The reason why you can't interfere directly with your WorkerRole.cs class, is that it is being instantiated by the Windows Azure infrastructure, and not by your own infrastructure. You have to accept that, and built your infrastructure within the WorkerRole appropriate methods. And do not forget that you must never quit/break/return/exit the Run() method. Doing so will flag Windows Azure infrastructure that there is something wrong with your code and will trigger role recycling.
Hope this helps.
I know this is an old question, but I'm going through the same learning curve and would like to share my findings for someone who struggles to understand the mechanics.
The reason you can't access DI in your worker role class is because this is run in a separate process in the OS, outside of IIS. Think of your WebRole class as being run in a Windows Service.
I've made a little experiment with my MVC web-site and WebRole class:
public class WebRole : RoleEntryPoint
{
public override void Run()
{
while (true)
{
Thread.Sleep(10000);
WriteToLogFile("Web Role Run: run, Forest, RUN!");
}
}
private static void WriteToLogFile(string text)
{
var file = new System.IO.StreamWriter("D:\\tmp\\webRole.txt", true); // might want to change the filename
var message = string.Format("{0} | {1}", DateTime.UtcNow, text);
file.WriteLine(message);
file.Close();
}
}
This would write to a file a new string every 10 seconds (or so). Now start your Azure site in debugging mode, make sure the site deployed to Azure emulator and the debugger in VS has started. Check that the site is running and check that WebRole is writing to the file in question.
Now stop the IIS Express (or IIS if you are running it in full blown installation) without stopping the VS debugger. All operations in your web-site are stopped now. But if you check your temp file, the process is still running and you still get new lines added every 10 seconds. Until you stop the debugger.
So whatever you have loaded in memory of web-application is inside of the IIS and not available inside of Worker Role. And you need to re-configure your DI and other services from the scratch.
Hope this helps someone to better understand the basics.