Translate

jueves, 30 de agosto de 2012

SpringSecurity: Truco para securizar URLS de tu aplicación

El parámetro "<sec:http pattern=" de Spring Security sirve para mapear las URL que atacan a nuestra aplicación y poderles aplicar seguridad a cada uno de ellos.

La experiencia aculada en nuestros proyectos nos ha llevado a la conclusión de que para configurar correctamente la seguridad de la aplicación y no tener problemas con las URL lo mejor es agrupar los patrones.

Nuestro sistema de seguridad consistía en que nosotros hacemos login contra un CAS server y una vez obtenida la autenticación este debía de redirigirnos a la aplicación a la que tenemos acceso. El problema era que aleatoriamente nos daba el acceso o no, generalmente nada más hacer log-in no nos daba acceso pero si recargábamos la página si nos daba acceso.

Nuestra configuración, erronea e incial era la siguiente:

 <sec:http pattern="/messagebroker/**" security="none"/>
 <sec:http pattern="*.swf" security="none"/>
 <sec:http pattern="*.html" security="none"/>  
 
 
 
 <sec:http entry-point-ref="entryPoint" auto-config="false" pattern="/*">
  <sec:intercept-url pattern="/**" access="ROLE_AUTHENTICATED"/>
 </sec:http>




La solución a este problema fue juntar los patrones e incluso segregarlos un poco más y diferenciar la distintas URLs

 <sec:http pattern="*.swf" security="none"/>
 <sec:http pattern="*.html" security="none"/>  
 
 <sec:http pattern="/**">
  <sec:anonymous enabled="true"/>
  <sec:intercept-url pattern="/messagebroker/**" access="ROLE_ANONYMOUS"/>
  <sec:intercept-url pattern="/access/login" access="ROLE_ANONYMOUS"/>
  <sec:intercept-url pattern="/access/loginsuccess" access="ROLE_AUTHENTICATED"/>
  <sec:form-login login-page="/access/login"/>  
 </sec:http>




viernes, 24 de agosto de 2012

Flex: Recuperar el índice de un itemrenderer

Title: get de item index in a flex itemrenderer

Recuperar el índice de la posición que ocupa el itemrenderer que se está mostrando en pantalla es un cosa que no te preguntas hasta que realmente no te hace falta utlizarlo, aunque es de lo más básico

En internet hay varias opciones para hacerlo pero si ya estamos utlizando de Flex4 con la implementación Spak del itemrenderer es tan fácil como utilizar la propiedad  itemIndex

--
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer............

<s:Group x="74" y="12">
  <s:Rect x="0.5" y="0.5" width="20" height="20">
   <s:stroke>
    <s:SolidColorStroke caps="none" color="#3085B7" joints="miter" miterLimit="10"/>
   </s:stroke>
  </s:Rect>
 <s:RichText id="numQuestion" x="8" y="6" color="#3085B7" columnCount="1"
 fontFamily="Myriad-Bold" fontSize="12.1205" kerning="on" lineHeight="76.1519"
 tabStops="S36" text="{itemIndex+1}" whiteSpaceCollapse="preserve"/>
</s:Group>


<s:RichText d:id="4" x="110"
y="17" ai:aa="2" color="#414042" columnCount="1" fontFamily="DINPro-Regular"
fontSize="14.1406" kerning="on" lineHeight="76.1519" tabStops="S199.772155761719"
text="{data.question}" 
whiteSpaceCollapse="preserve"/>

..............
</s:ItemRenderer>
--



Acordaros de poner el +1 para que la cuenta no empiece en 0.

Referencias:

http://www.jeffryhouser.com/index.cfm/2008/11/4/How-do-you-find-an-items-dataProvider-index-from-inside-an-itemRenderer

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/components/supportClasses/ItemRenderer.html#itemIndex

jueves, 16 de agosto de 2012

Spring Data: Artículo imprescindible de introducción a Spring Data

Os dejo el enlace a este artículo que está muy bien para saber de que va el tema de Spring Data. Nosotros utilizamos SpringData Mongodb y SpringData redis.

http://www.infoq.com/articles/spring-data-intro

lunes, 13 de agosto de 2012

Eclipse: Incrementar el Console Buffer Size

Este es lo típico que nos va a ocurrir cuando java nos da una error con un montón de trazas y el buffer no da más de si.

Nada más fácil que  ir a Windows>>Preferences>>Run/Debug>>Console

Y ahí encontraremos el buffer size para poner el que queramos.

Cuidado con lo que ponéis que lo guarda todo en memoria y si pones mucho empezará a chupar RAM y todo irá más lento.


viernes, 10 de agosto de 2012

MongoDB: java.lang.NoClassDefFoundError: com/google/common/base/Function

Este error se produce por no tener las versiones correctas de las librerías de Spring-data y query-dsl


--
java.lang.NoClassDefFoundError: com/google/common/base/Function
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.createQueryFor(QueryDslMongoRepository.java:167)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.count(QueryDslMongoRepository.java:154)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
 at $Proxy26.count(Unknown Source)
 at com.antuansoft.contentapi.application.CourseContentTemplateImpl.countByAllowedUsers(CourseContentTemplateImpl.java:61)
 at com.antuansoft.contentapi.integration.CourseContentTemplateIntegrationTest.countByAllowedUsers(CourseContentTemplateIntegrationTest.java:157)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
 at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
 at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
 at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
 at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
 at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
 at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
 at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: com.google.common.base.Function
 at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
 at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
 ... 43 more

--

Si investigamos un poco en google la clase que nos fata la podemos encontrar en un jar llamado guava-12.0.jar este error se soluciona pero nos da otro


--
java.lang.NoSuchMethodError: com.mysema.query.mongodb.MongodbQuery.<init>(Lcom/mongodb/DBCollection;Lcom/google/common/base/Function;Lcom/mysema/query/mongodb/MongodbSerializer;)V
 at org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery.<init>(SpringDataMongodbQuery.java:58)
 at org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery.<init>(SpringDataMongodbQuery.java:44)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.createQueryFor(QueryDslMongoRepository.java:167)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.count(QueryDslMongoRepository.java:154)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)

--
Para este error ya tengo un post publicado que este:

Spring JPA MongoDB: java.lang.NoSuchMethodError: com.mysema.query.mongodb.MongodbQuery

jueves, 9 de agosto de 2012

MongoDB Spring Data: Push de objetos en Arrays

Push an Object into an array (addToSet)

Si trabajáis con MongoDB ya sabréis que podemos utilizar el comando push para introducir valores en un arrary.

Por ejemplo si tenemos el siguiente objecto mapeado en MongoDB


import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import com.google.code.morphia.annotations.Entity;

@Entity
@Document
public class Course implements Serializable {
 
 
 private static final long serialVersionUID = -7251789829032925885L;
 
 
 @Id
 private String id = UUID.randomUUID().toString();
 private String name; 
 private String description;
 private long creationDate = new Date().getTime();
 private int duration;
 private int credits;
 private List<String> tags = new ArrayList<String>();
 private List<String> users = new ArrayList<User>();


Si queremos introducir un valor String en el array de tags es tan fácil como hace esto

 public void addTag(String courseId, String tag){
  
  

    
  WriteResult wr = mongoOperations.updateFirst(
   new Query(where("id").is(courseId)),   
   new Update().push("tags", tag),Course.class);
   
    

  
  
 }


El resultado en MongoDb debería ser algo parecido a esto


  {"_class": "com.antuansoft.Course",
  
  "_id": "953a878e-5aa6-4811-82e3-660b00ebafe2",
    
  "creationDate": 1344439353237,
  
  "credits": 10,
  
  "description": "Course DESCRIPTION",
  
  "duration": 100,
    
  "name": "Course 1",
    
  "tags": {
    
    "0": "tag1"
    "1": "tag2"
  
  }}

Al insertar en el array de tags objetos de la clase String no hay ningún problema ya que los entiende perfectamente.

El problema que he encontrado ocurre cuando tienes que insertar en el array Objectos de alguna clase que no sean tipos básicos. Por ejemplo un objecto de la clase User.

El problema que ocurre es que al insertarlo de la misma manera que un String normal no transforma el objeto y no pone las propiedades ni "_id" ni "_class", o sea que no lo transforma e introduce sólo las propiedades que tenga ese objeto en el array.

Para solucionar esto utilizamos una par de instrucciones que fuerzan a MongoDb a realizar esta transformación.

DBObject dbo = new BasicDBObject();
mongoOperations.getConverter().write(user, dbo);


public void addUser(String idCourse, User user){  
  
   
   DBObject dbo = new BasicDBObject();
   mongoOperations.getConverter().write(user, dbo);
   
   WriteResult wr = mongoOperations.updateFirst(
     new Query(where("id").is(idCourse)),   
     new Update().push("users", dbo),Course.class);


{"_class": "com.antuansoft.Course",
  
  "_id": "953a878e-5aa6-4811-82e3-660b00ebafe2",
    
  "creationDate": 1344439353237,
  
  "credits": 10,
  
  "description": "Course DESCRIPTION",
  
  "duration": 100,
    
  "name": "Course 1",
    
  "tags": {
    
    "0": "tag1"
    "1": "tag2"
  
  }

"users": {
    "0": {
        
        "_class": "com.antuansoft.User",
        
        "_id": "047cd911-356a-4851-948a-3087ea735353",
        "name": "AntuanSoft"
      }
  }
  
  }

Nota: Si no queremos que aparezcan valores repetidos en nuestra lista de objetos/strings lo mejor es utilizar el método  addToSet en vez de push. De este modo si introducimos un valor que ya existe, este no se insetará