OAuth(二)Sample Provider Implementation in JAVA
OAuth(2)Sample Provider Implementation in JAVA
OAuth(2)Sample Provider Implementation in JAVA
5. Modify the provider base on the example
Configure the spring listener and Servlets in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:main-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>RequestTokenServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>AuthorizationServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>AccessTokenServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestTokenServlet</servlet-name>
<url-pattern>/request_token</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AuthorizationServlet</servlet-name>
<url-pattern>/authorize</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AccessTokenServlet</servlet-name>
<url-pattern>/access_token</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>
Spring configuration file about oauth in oauth-context.xml:
<bean id="oauthValidator" class="net.oauth.SimpleOAuthValidator" >
</bean>
<bean id="oauthProvider" class="com.sillycat.easyoauthprovider.plugins.oauth.impl.OAuthHashMemoryProvider" init-method="init">
<property name="userManager" ref="userManager" />
</bean>
Spring configuration file about servlets in servlet-context.xml:
<bean id="RequestTokenServlet" class="com.sillycat.easyoauthprovider.servlets.RequestTokenHttpRequestHandler" >
<property name="oauthProvider" ref="oauthProvider" />
<property name="oauthValidator" ref="oauthValidator" />
</bean>
<bean id="AuthorizationServlet" class="com.sillycat.easyoauthprovider.servlets.AuthorizationHttpRequestHandler" >
<property name="oauthProvider" ref="oauthProvider" />
</bean>
<bean id="AccessTokenServlet" class="com.sillycat.easyoauthprovider.servlets.AccessTokenHttpRequestHandler" >
<property name="oauthProvider" ref="oauthProvider" />
<property name="oauthValidator" ref="oauthValidator" />
</bean>
<bean id="UserServlet" class="com.sillycat.easyoauthprovider.servlets.UserHttpRequestHandler">
<property name="oauthProvider" ref="oauthProvider" />
<property name="oauthValidator" ref="oauthValidator" />
</bean>
I have the interface of OAuthProvider.java:
package com.sillycat.easyoauthprovider.plugins.oauth;
import java.io.IOException;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage;
import net.oauth.OAuthProblemException;
import com.sillycat.easyoauthprovider.model.User;
/**
* provide the OAUTH
* @author SILLYCAT
*/
public interface OAuthProvider {
public void init();
/**
* find the consumer in our database
*
* @param requestMessage
* @return
* @throws IOException
* @throws OAuthProblemException
*/
public OAuthConsumer getConsumer(OAuthMessage requestMessage)throws IOException, OAuthProblemException;
/**
* get the ACCESSOR from our database
*
* @param requestMessage
* @return
* @throws IOException
* @throws OAuthProblemException
*/
public OAuthAccessor getAccessor(OAuthMessage requestMessage) throws IOException, OAuthProblemException;
/**
* authorize
*
* @param accessor
* @param user
*/
public void markAsAuthorized(OAuthAccessor accessor, User user);
/**
* generate request token
*
* @param accessor
*/
public void generateRequestToken(OAuthAccessor accessor);
/**
* generate ACCESS token
*
* @param accessor
*/
public void generateAccessToken(OAuthAccessor accessor);
}
One of the Memory implementation OAuthHashMemoryProvider.java, but there is more work in load the properties files:
package com.sillycat.easyoauthprovider.plugins.oauth.impl;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage;
import net.oauth.OAuthProblemException;
import net.oauth.example.provider.core.SampleOAuthProvider;
import org.apache.commons.codec.digest.DigestUtils;
import com.sillycat.easyoauthprovider.manager.UserManager;
import com.sillycat.easyoauthprovider.model.User;
import com.sillycat.easyoauthprovider.plugins.oauth.OAuthProvider;
public class OAuthHashMemoryProvider implements OAuthProvider {
private final Map<String, OAuthConsumer> ALL_CONSUMERS = Collections
.synchronizedMap(new HashMap<String, OAuthConsumer>(10));
private final Collection<OAuthAccessor> ALL_TOKENS = new HashSet<OAuthAccessor>();
private UserManager userManager;
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
public void init() {
try {
loadAllConsumerFromProperties();
} catch (IOException e) {
e.printStackTrace();
}
}
private void loadAllConsumerFromProperties() throws IOException {
Properties p = new Properties();
String resourceName = "/"
+ SampleOAuthProvider.class.getPackage().getName()
.replace(".", "/") + "/provider.properties";
URL resource = SampleOAuthProvider.class.getClassLoader().getResource(
resourceName);
if (resource == null) {
throw new IOException("resource not found: " + resourceName);
}
InputStream stream = resource.openStream();
try {
p.load(stream);
} finally {
stream.close();
}
// for each entry in the properties file create a OAuthConsumer
for (@SuppressWarnings("rawtypes")
Map.Entry prop : p.entrySet()) {
String consumer_key = (String) prop.getKey();
// make sure it's key not additional properties
if (!consumer_key.contains(".")) {
String consumer_secret = (String) prop.getValue();
if (consumer_secret != null) {
String consumer_description = (String) p
.getProperty(consumer_key + ".description");
String consumer_callback_url = (String) p
.getProperty(consumer_key + ".callbackURL");
// Create OAuthConsumer w/ key and secret
OAuthConsumer consumer = new OAuthConsumer(
consumer_callback_url, consumer_key,
consumer_secret, null);
consumer.setProperty("name", consumer_key);
consumer.setProperty("description", consumer_description);
ALL_CONSUMERS.put(consumer_key, consumer);
}
}
}
}
@Override
public OAuthConsumer getConsumer(OAuthMessage requestMessage)
throws IOException, OAuthProblemException {
OAuthConsumer consumer = null;
// try to load from local cache if not throw exception
String consumer_key = requestMessage.getConsumerKey();
consumer = ALL_CONSUMERS.get(consumer_key);
if (consumer == null) {
OAuthProblemException problem = new OAuthProblemException(
"token_rejected");
throw problem;
}
return consumer;
}
@Override
public OAuthAccessor getAccessor(OAuthMessage requestMessage)
throws IOException, OAuthProblemException {
// try to load from local cache if not throw exception
String consumer_token = requestMessage.getToken();
OAuthAccessor accessor = null;
for (OAuthAccessor a : ALL_TOKENS) {
if (a.requestToken != null) {
if (a.requestToken.equals(consumer_token)) {
accessor = a;
break;
}
} else if (a.accessToken != null) {
if (a.accessToken.equals(consumer_token)) {
accessor = a;
break;
}
}
}
if (accessor == null) {
OAuthProblemException problem = new OAuthProblemException(
"token_expired");
throw problem;
}
return accessor;
}
@Override
public void markAsAuthorized(OAuthAccessor accessor, User user) {
// first remove the accessor from cache
ALL_TOKENS.remove(accessor);
if (userManager.login(user)) {
accessor.setProperty("user", user);
//accessor.setProperty("userName", user.getUserName());
//accessor.setProperty("emailAddress", user.getEmailAddress());
accessor.setProperty("authorized", Boolean.TRUE);
// update token in local cache
ALL_TOKENS.add(accessor);
}
}
@Override
public void generateRequestToken(OAuthAccessor accessor) {
// generate oauth_token and oauth_secret
String consumer_key = (String) accessor.consumer.getProperty("name");
// generate token and secret based on consumer_key
// for now use md5 of name + current time as token
String token_data = consumer_key + System.nanoTime();
String token = DigestUtils.md5Hex(token_data);
// for now use md5 of name + current time + token as secret
String secret_data = consumer_key + System.nanoTime() + token;
String secret = DigestUtils.md5Hex(secret_data);
accessor.requestToken = token;
accessor.tokenSecret = secret;
accessor.accessToken = null;
// add to the local cache
ALL_TOKENS.add(accessor);
}
@Override
public void generateAccessToken(OAuthAccessor accessor) {
// generate oauth_token and oauth_secret
String consumer_key = (String) accessor.consumer.getProperty("name");
// generate token and secret based on consumer_key
// for now use md5 of name + current time as token
String token_data = consumer_key + System.nanoTime();
String token = DigestUtils.md5Hex(token_data);
// first remove the accessor from cache
ALL_TOKENS.remove(accessor);
accessor.requestToken = null;
accessor.accessToken = token;
// update token in local cache
ALL_TOKENS.add(accessor);
}
}
The provider.properties is as follow:
myKey=mySecret
myKey.description=OAUTHCONSUMER
myKey.callbackURL=http://localhost:8080/easyoauthconsumer
#noCallbackConsumer=noCallbackSecret
#noCallbackConsumer.description=sample consumer
references:
OAuth(2)Sample Provider Implementation in JAVA
5. Modify the provider base on the example
Configure the spring listener and Servlets in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:main-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>RequestTokenServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>AuthorizationServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>AccessTokenServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestTokenServlet</servlet-name>
<url-pattern>/request_token</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AuthorizationServlet</servlet-name>
<url-pattern>/authorize</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AccessTokenServlet</servlet-name>
<url-pattern>/access_token</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>
Spring configuration file about oauth in oauth-context.xml:
<bean id="oauthValidator" class="net.oauth.SimpleOAuthValidator" >
</bean>
<bean id="oauthProvider" class="com.sillycat.easyoauthprovider.plugins.oauth.impl.OAuthHashMemoryProvider" init-method="init">
<property name="userManager" ref="userManager" />
</bean>
Spring configuration file about servlets in servlet-context.xml:
<bean id="RequestTokenServlet" class="com.sillycat.easyoauthprovider.servlets.RequestTokenHttpRequestHandler" >
<property name="oauthProvider" ref="oauthProvider" />
<property name="oauthValidator" ref="oauthValidator" />
</bean>
<bean id="AuthorizationServlet" class="com.sillycat.easyoauthprovider.servlets.AuthorizationHttpRequestHandler" >
<property name="oauthProvider" ref="oauthProvider" />
</bean>
<bean id="AccessTokenServlet" class="com.sillycat.easyoauthprovider.servlets.AccessTokenHttpRequestHandler" >
<property name="oauthProvider" ref="oauthProvider" />
<property name="oauthValidator" ref="oauthValidator" />
</bean>
<bean id="UserServlet" class="com.sillycat.easyoauthprovider.servlets.UserHttpRequestHandler">
<property name="oauthProvider" ref="oauthProvider" />
<property name="oauthValidator" ref="oauthValidator" />
</bean>
I have the interface of OAuthProvider.java:
package com.sillycat.easyoauthprovider.plugins.oauth;
import java.io.IOException;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage;
import net.oauth.OAuthProblemException;
import com.sillycat.easyoauthprovider.model.User;
/**
* provide the OAUTH
* @author SILLYCAT
*/
public interface OAuthProvider {
public void init();
/**
* find the consumer in our database
*
* @param requestMessage
* @return
* @throws IOException
* @throws OAuthProblemException
*/
public OAuthConsumer getConsumer(OAuthMessage requestMessage)throws IOException, OAuthProblemException;
/**
* get the ACCESSOR from our database
*
* @param requestMessage
* @return
* @throws IOException
* @throws OAuthProblemException
*/
public OAuthAccessor getAccessor(OAuthMessage requestMessage) throws IOException, OAuthProblemException;
/**
* authorize
*
* @param accessor
* @param user
*/
public void markAsAuthorized(OAuthAccessor accessor, User user);
/**
* generate request token
*
* @param accessor
*/
public void generateRequestToken(OAuthAccessor accessor);
/**
* generate ACCESS token
*
* @param accessor
*/
public void generateAccessToken(OAuthAccessor accessor);
}
One of the Memory implementation OAuthHashMemoryProvider.java, but there is more work in load the properties files:
package com.sillycat.easyoauthprovider.plugins.oauth.impl;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage;
import net.oauth.OAuthProblemException;
import net.oauth.example.provider.core.SampleOAuthProvider;
import org.apache.commons.codec.digest.DigestUtils;
import com.sillycat.easyoauthprovider.manager.UserManager;
import com.sillycat.easyoauthprovider.model.User;
import com.sillycat.easyoauthprovider.plugins.oauth.OAuthProvider;
public class OAuthHashMemoryProvider implements OAuthProvider {
private final Map<String, OAuthConsumer> ALL_CONSUMERS = Collections
.synchronizedMap(new HashMap<String, OAuthConsumer>(10));
private final Collection<OAuthAccessor> ALL_TOKENS = new HashSet<OAuthAccessor>();
private UserManager userManager;
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
public void init() {
try {
loadAllConsumerFromProperties();
} catch (IOException e) {
e.printStackTrace();
}
}
private void loadAllConsumerFromProperties() throws IOException {
Properties p = new Properties();
String resourceName = "/"
+ SampleOAuthProvider.class.getPackage().getName()
.replace(".", "/") + "/provider.properties";
URL resource = SampleOAuthProvider.class.getClassLoader().getResource(
resourceName);
if (resource == null) {
throw new IOException("resource not found: " + resourceName);
}
InputStream stream = resource.openStream();
try {
p.load(stream);
} finally {
stream.close();
}
// for each entry in the properties file create a OAuthConsumer
for (@SuppressWarnings("rawtypes")
Map.Entry prop : p.entrySet()) {
String consumer_key = (String) prop.getKey();
// make sure it's key not additional properties
if (!consumer_key.contains(".")) {
String consumer_secret = (String) prop.getValue();
if (consumer_secret != null) {
String consumer_description = (String) p
.getProperty(consumer_key + ".description");
String consumer_callback_url = (String) p
.getProperty(consumer_key + ".callbackURL");
// Create OAuthConsumer w/ key and secret
OAuthConsumer consumer = new OAuthConsumer(
consumer_callback_url, consumer_key,
consumer_secret, null);
consumer.setProperty("name", consumer_key);
consumer.setProperty("description", consumer_description);
ALL_CONSUMERS.put(consumer_key, consumer);
}
}
}
}
@Override
public OAuthConsumer getConsumer(OAuthMessage requestMessage)
throws IOException, OAuthProblemException {
OAuthConsumer consumer = null;
// try to load from local cache if not throw exception
String consumer_key = requestMessage.getConsumerKey();
consumer = ALL_CONSUMERS.get(consumer_key);
if (consumer == null) {
OAuthProblemException problem = new OAuthProblemException(
"token_rejected");
throw problem;
}
return consumer;
}
@Override
public OAuthAccessor getAccessor(OAuthMessage requestMessage)
throws IOException, OAuthProblemException {
// try to load from local cache if not throw exception
String consumer_token = requestMessage.getToken();
OAuthAccessor accessor = null;
for (OAuthAccessor a : ALL_TOKENS) {
if (a.requestToken != null) {
if (a.requestToken.equals(consumer_token)) {
accessor = a;
break;
}
} else if (a.accessToken != null) {
if (a.accessToken.equals(consumer_token)) {
accessor = a;
break;
}
}
}
if (accessor == null) {
OAuthProblemException problem = new OAuthProblemException(
"token_expired");
throw problem;
}
return accessor;
}
@Override
public void markAsAuthorized(OAuthAccessor accessor, User user) {
// first remove the accessor from cache
ALL_TOKENS.remove(accessor);
if (userManager.login(user)) {
accessor.setProperty("user", user);
//accessor.setProperty("userName", user.getUserName());
//accessor.setProperty("emailAddress", user.getEmailAddress());
accessor.setProperty("authorized", Boolean.TRUE);
// update token in local cache
ALL_TOKENS.add(accessor);
}
}
@Override
public void generateRequestToken(OAuthAccessor accessor) {
// generate oauth_token and oauth_secret
String consumer_key = (String) accessor.consumer.getProperty("name");
// generate token and secret based on consumer_key
// for now use md5 of name + current time as token
String token_data = consumer_key + System.nanoTime();
String token = DigestUtils.md5Hex(token_data);
// for now use md5 of name + current time + token as secret
String secret_data = consumer_key + System.nanoTime() + token;
String secret = DigestUtils.md5Hex(secret_data);
accessor.requestToken = token;
accessor.tokenSecret = secret;
accessor.accessToken = null;
// add to the local cache
ALL_TOKENS.add(accessor);
}
@Override
public void generateAccessToken(OAuthAccessor accessor) {
// generate oauth_token and oauth_secret
String consumer_key = (String) accessor.consumer.getProperty("name");
// generate token and secret based on consumer_key
// for now use md5 of name + current time as token
String token_data = consumer_key + System.nanoTime();
String token = DigestUtils.md5Hex(token_data);
// first remove the accessor from cache
ALL_TOKENS.remove(accessor);
accessor.requestToken = null;
accessor.accessToken = token;
// update token in local cache
ALL_TOKENS.add(accessor);
}
}
The provider.properties is as follow:
myKey=mySecret
myKey.description=OAUTHCONSUMER
myKey.callbackURL=http://localhost:8080/easyoauthconsumer
#noCallbackConsumer=noCallbackSecret
#noCallbackConsumer.description=sample consumer
references: