Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Monday, July 11, 2016

Spring framework - Strange characters in Spring writing key to redis

Strange characters in Spring writing key to redis

With the redisTemplate bean declared, Spring is ready to manipulate data on redis

<bean id="redisTemplate" 
     class="org.springframework.data.redis.core.RedisTemplate" 
     p:connection-factory-ref="jedisConnectionFactory"/>

But after the key is set from Spring, you will see the addition strange characters like to “\xac\xed\x00\x05t\x00\t” prepended to the key on redis

redis> keys *
"\xac\xed\x00\x05t\x00\takey"

To get rid of that, create a redis serializer bean

<bean id="stringRedisSerializer" 
     class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

and inject it to keySerializer in redisTemplate.

<bean id="redisTemplate" 
     class="org.springframework.data.redis.core.RedisTemplate" 
     p:connection-factory-ref="jedisConnectionFactory"
     p:keySerializer-ref="stringRedisSerializer"/>

so that the key will not have the unwanted characters.

The values still have them

Without configuring value serializer, the extra characters may not affect the output of reading values. But it will cause “redis.clients.jedis.exceptions.JedisDataException: ERR hash value is not an integer” if you try to do HashOperations.increment(H key, HK hashKey, long delta). That’s because the value is not a number and the operation tries to increment the number before deserialization. In order to for increment() work properly, it’s necessary to inject the redis serializer with Long class to valueSerializer in redis template

<bean id="longRedisSerializer" class="org.springframework.data.redis.serializer.GenericToStringSerializer">
    <constructor-arg type="java.lang.Class" value="java.lang.Long"/>
</bean>

for Sets

<bean id="longRedisTemplate"
     class="org.springframework.data.redis.core.RedisTemplate"
     p:connection-factory-ref="jedisConnectionFactory"
     p:keySerializer-ref="stringRedisSerializer"
     p:valueSerializer-ref="longRedisSerializer"/>

for Hashes

<bean id="longRedisTemplate"
     class="org.springframework.data.redis.core.RedisTemplate"
     p:connection-factory-ref="jedisConnectionFactory"
     p:keySerializer-ref="stringRedisSerializer"
     p:hashKeySerializer-ref="stringRedisSerializer"
     p:hashValueSerializer-ref="longRedisSerializer"/>

References

  1. Weird redis key with spring data Jedis
  2. spring-data-redis redisTemplate Excetion

Thursday, July 11, 2013

Test Spring security protected web app using curl

Form-based authentication
1. Obtain a session and write it to the file. Note that the spring security path j_spring_security_check is used for this step
$ curl --data "j_username=myname&j_password=mypswd" http://localhost:8080/SpringSecurityAuth/j_spring_security_check --cookie-jar cookies.txt

2. Access the protected URL with the session
$ curl http://localhost:8080/SpringSecurityAuth/api/helloworld --cookie cookies.txt

HTTP basic authentication

Option 1

Send username and password for each request
$ curl --user myname:mypwsd http://localhost:8080/SpringSecurityAuth/api/helloworld

Option 2

1. Obrain a session similar to the way in form-based authentication, but using spring security path j_spring_security_check is not needed
$ curl --user byname:mypwsd http://localhost:8080/SpringSecurityAuth/api/helloworld --cookie-jar cookies.txt

2. Access the protected URL with the session
$ curl http://localhost:8080/SpringSecurityAuth/api/helloworld --cookie cookies.txt

Simple REST Stateless configuration
To achieve REST stateless feature, the element in security configuration file can be configured as follow
  <!-- Stateless RESTful service using Basic authentication -->
  <http pattern="/restful/**" create-session="stateless">
      <intercept-url pattern='/**' access='ROLE_REMOTE' />
      <http-basic />
  </http>
Then the saved session will not work and providing username and password is required for each request.

This feature can be achieved only with HTTP basic authentication because the form-based authentication needs to have a session to access the protected resource, but the session is not valid here.

This approach may not be secure enough because the username and password are transmitted in each request. To have a more secure implementation, using option to generate token and customer-filter to authenticate token may be required (authentication could be form-based or HTTP basic since token is being used).


Reference
Interact with a spring-security protected application
https://bowerstudios.com/node/913

Spring Security Basic Authentication
http://www.baeldung.com/spring-security-basic-authentication

Advanced Namespace Configuration
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/security-filter-chain.html#filter-chains-with-ns

Sunday, May 12, 2013

Spring 3 Hello World

Create a Maven project, make the pom.xml as the sample code below and convert it to Eclipse importable by mvn eclipse:eclipse

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.core</groupId>
  <artifactId>Spring3HelloWorld</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Spring3HelloWorld</name>
  <url>http://maven.apache.org</url>

  <properties>
    <org.springframework-version>3.2.2.RELEASE</org.springframework-version>
  </properties>

  <dependencies>
  
        <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
        </dependency>
 
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>${org.springframework-version}</version>
 </dependency>
 
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${org.springframework-version}</version>
 </dependency>
 
  </dependencies>
</project>
 
After the project is imported into Eclipse, create a resources folder first. Select the project on Project Explorer, then go to Project -> Properties, then Add Folder...  

















Add the resource under <Project Name>/src/main

 
 
 
 
 
  
 
 
 
 
 
 
 
 
 
Add the AppBeans.xml with the sample code to <Project Name>/main/src/resources
 
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">
 
 <bean id="helloworldBean" class="com.example.core.HelloWorld">
  <property name="name" value="Spring 3" />
 </bean>
</beans> 
 
 
Add the HelloWorld.java to <Project Name>/main/src/java
 
package com.example.core;

public class HelloWorld {
 private String name;
 
 public void setName(String _name){
  this.name = _name;
 }
 
 public void sayHello(){
  System.out.println("Hello World, " + this.name + "!");
 }
}
 
Add the code to App.java
 
package com.example.core;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Hello world!
 *
 */
public class App {
    public static void main( String[] args ) {
     ApplicationContext context = new ClassPathXmlApplicationContext("AppBeans.xml");
     HelloWorld obj = (HelloWorld)context.getBean("helloworldBean");
     obj.sayHello();
    }
} 
 

The final file structure 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Select App.java and run as Java Application
Hello World, Spring 3!