access LTPA token outside of WebSphere context - java

I've a web app which is deployed in tomcat and from this web app, i have to consume a SOAP service which is deployed in Websphere. To access this service, i need to pass LTPA token. I'm very new to websphere, don't know how can i get LTPA token in my web app ? I can't modify the implementation of the app which is deployed in web sphere.

I could acheive this by using HttpBasicAuthentication. Here is the code snippet -
public class TokenHelper {
private static Logger logger = LoggerFactory.getLogger(TokenHelper.class);
private static final int HTTP_TIMEOUT_MILISEC = 100000;
private static String lineSeparator = System.getProperty("line.separator");
#Value("#{'${hostname}'}")
private String hostName;
#Value("#{'${port}'}")
private int port;
#Value("#{'${contextpath}'}")
private String contextPath;
#Value("#{'${isbasicauthentication}'}")
private boolean isBasicAuthentication;
#Value("#{'${username}'}")
private String basicAuthenticationUserName;
#Value("#{'${userpassword}'}")
private String basicAuthenticationPassword;
public Map<String, String> getLtpaToken() throws Exception {
Cookie[] cookies = null;
Protocol protocol = null;
Map<String, String> cookiesMap = new HashMap<String, String>();
GetMethod method = new GetMethod();
HttpClient client = new HttpClient();
method.getParams().setSoTimeout(HTTP_TIMEOUT_MILISEC);
protocol = new Protocol("http", new DefaultProtocolSocketFactory(), getPort());
if (isBasicAuthentication) {
client.getParams().setAuthenticationPreemptive(true);
Credentials defaultcreds = new UsernamePasswordCredentials(getBasicAuthenticationUserName(), getBasicAuthenticationPassword());
client.getState().setCredentials(new AuthScope(getHostName(), getPort(), AuthScope.ANY_REALM), defaultcreds);
}
// Execute request
try {
client.getHostConfiguration().setHost(getHostName(), getPort(), protocol);
method = new GetMethod(getContextPath());
method.setFollowRedirects(true);
logger.info(methodName, "URL to get:" + getContextPath());
// Execute the GET method
int statusCode = client.executeMethod(method);
if (statusCode != -1) {
cookies = client.getState().getCookies();
StringBuffer sb = new StringBuffer();
for (int j = 0; j < cookies.length; j++) {
cookiesMap.put(cookies[j].getName(), cookies[j].getValue());
sb.append("CookieName=" + cookies[j].getName() + lineSeparator);
sb.append("Value=" + cookies[j].getValue() + lineSeparator);
sb.append("Domain=" + cookies[j].getDomain() + lineSeparator);
}
sb.append("Status Text>>>" + HttpStatus.getStatusText(statusCode));
logger.debug("Cookies are: {}" + sb.toString());
method.releaseConnection();
}
} catch (Exception e) {
logger.error("Error while getting LTPA token using HttpBasicAuthentication for URL {}" +e);
throw new RuntimeException("Error while getting LTPA token using HttpBasicAuthentication for URL:" + contextPath, e);
} finally {
// Release current connection to the connection pool once you
// are done
method.releaseConnection();
}
return cookiesMap;
}

Related

How to get access token from AuthenticationFlowContext on keycloak custom authenticator

I need to call one external API from the Keycloak custom authenticator authenticate(AuthenticationFlowContext context) method, for that, I need keycloak access token.
How to get the access token from the AuthenticationFlowContext.
Authenticator class:
public class CMAuthenticator implements Authenticator
{
#Override
public void authenticate(AuthenticationFlowContext context)
{
try
{
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
final String userName = formData.getFirst("username");
final String pwd = formData.getFirst("password");
String cmLoginURL = getCMAuthenticatorConfig(context);
String loginObj = "{\"username\": \"" + userName + "\", \"password\":\"" + pwd + "\"}";
Entity<String> entity = Entity.text(loginObj);
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target(cmLoginURL);
Response response = target.request(MediaType.TEXT_PLAIN).post(entity);
if (response.getStatus() != 200)
{
context.getEvent().user(context.getUser());
context.getEvent().error(Errors.ACCESS_DENIED);
context.failure(AuthenticationFlowError.INVALID_USER);
return;
}
}
catch (Exception e)
{
context.getEvent().user(context.getUser());
context.getEvent().error(Errors.ACCESS_DENIED);
context.failure(AuthenticationFlowError.INVALID_USER);
return;
}
context.success();
}
}

WebServiceException: Method beaInvoke is exposed as WebMethod

Below is the code Snippet.. that must call WSDL in other server dynamically
but in the moment of calling
(int i = webServiceModuleService.notificationRecieved("xyz");)
returned exception :(
note: i haven't any beaInvoke method in my service :|
public static void main(String[] args) {
java.sql.Connection conn = null;
InitialContext context;
try {
context = new InitialContext();
DataSource ds = (DataSource) context.lookup("jdbc/dataSourceDS");
conn = ds.getConnection();
} catch (SQLException e) {
} catch (NamingException e) {
}
QueryRunner run = new QueryRunner();
SampleResultSetHandler h = new SampleResultSetHandler();
Object[] res = null;
try {
res = run.query(conn, "select SERVER_IP,SERVER_PORT from SERVER where UPPER(SERVER_NAME)=? ", h, "test");
} catch (SQLException e) {
}
String ip = res[0].toString();
String port = res[1].toString();
String endpointURL = "http://" + ip + ":" + port + "/context-root/WebServiceModuleService";
try {
URL tmpURL = new URL(endpointURL + "?wsdl");
System.err.println(tmpURL);
WebServiceModuleService_Service webServiceModuleService_Service = new WebServiceModuleService_Service(tmpURL,
new QName("/org/parsisys/test/mina/model/services/common/",
"WebServiceModuleService"));
WebServiceModuleService webServiceModuleService = null;
webServiceModuleService = webServiceModuleService_Service.getWebServiceModuleServiceSoapHttpPort();
BindingProvider bp = (BindingProvider) webServiceModuleService;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
// Configure credential providers
Map<String, Object> requestContext = ((BindingProvider) webServiceModuleService).getRequestContext();
try {
setPortCredentialProviderList(requestContext);
} catch (Exception ex) {
ex.printStackTrace();
}
//Call WebService ... ==> Exception :(
int i = webServiceModuleService.notificationRecieved("xyz");
//logp("successfully call the webservice for [ip&port:" + ip + ":" + port + "] [transid : " +transid + "]");
} catch (Exception e) {
//log
//TODO: Clean This
System.err.println(e.getMessage());
e.printStackTrace();
return;
}
}
#Generated("Oracle JDeveloper")
public static void setPortCredentialProviderList(Map<String, Object> requestContext) throws Exception {
// TODO - Provide the required credential values
String username = "";
String password = "";
String clientKeyStore = "";
String clientKeyStorePassword = "";
String clientKeyAlias = "";
String clientKeyPassword = "";
String serverKeyStore = "";
String serverKeyStorePassword = "";
String serverKeyAlias = "";
List<CredentialProvider> credList = new ArrayList<CredentialProvider>();
// Add the necessary credential providers to the list
// Code commented out due to empty username/password value found in the credential.
// credList.add(getUNTCredentialProvider(username, password));
// Code commented out due to empty server keystore value found in the credential.
// credList.add(getBSTCredentialProvider(clientKeyStore, clientKeyStorePassword, clientKeyAlias, clientKeyPassword, serverKeyStore, serverKeyStorePassword, serverKeyAlias, requestContext));
credList.add(getSAMLTrustCredentialProvider());
requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credList);
}
#Generated("Oracle JDeveloper")
public static CredentialProvider getSAMLTrustCredentialProvider() {
return new SAMLTrustCredentialProvider();
}
daynamic webservice call is generated with jdeveloper and it's works in clien't tester but in my module when i call webservice return exception :/
StackTrace is: ↓
Method beaInvoke is exposed as WebMethod, but there is no corresponding wsdl operation with name {/org/parsisys/test/mina/model/services/common/}beaInvoke in the wsdl:portType{/org/parsisys/test/mina/model/services/common/}WebServiceModuleService
javax.xml.ws.WebServiceException: Method beaInvoke is exposed as WebMethod, but there is no corresponding wsdl operation with name {/org/parsisys/test/mina/model/services/common/}beaInvoke in the wsdl:portType{/org/parsisys/test/mina/model/services/common/}WebServiceModuleService
at com.sun.xml.ws.model.JavaMethodImpl.freeze(JavaMethodImpl.java:382)
at com.sun.xml.ws.model.AbstractSEIModelImpl.freeze(AbstractSEIModelImpl.java:124)
at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:336)
at com.sun.xml.ws.db.DatabindingImpl.(DatabindingImpl.java:99)
at com.sun.xml.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:74)
at com.sun.xml.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:58)
at com.sun.xml.ws.db.DatabindingFactoryImpl.createRuntime(DatabindingFactoryImpl.java:120)
at com.sun.xml.ws.client.WSServiceDelegate.buildRuntimeModel(WSServiceDelegate.java:882)
at com.sun.xml.ws.client.WSServiceDelegate.createSEIPortInfo(WSServiceDelegate.java:899)
at com.sun.xml.ws.client.WSServiceDelegate.addSEI(WSServiceDelegate.java:862)
at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:451)
at weblogic.wsee.jaxws.spi.WLSProvider$ServiceDelegateImpl.internalGetPort(WLSProvider.java:1698)
at weblogic.wsee.jaxws.spi.WLSProvider$ServiceDelegateImpl$PortClientInstanceFactory.createClientInstance(WLSProvider.java:1769)
at weblogic.wsee.jaxws.spi.ClientInstancePool.takeSimpleClientInstance(ClientInstancePool.java:389)
at weblogic.wsee.jaxws.spi.ClientInstancePool.take(ClientInstancePool.java:243)
at weblogic.wsee.jaxws.spi.WLSProvider$ServiceDelegateImpl$3.apply(WLSProvider.java:1555)
at weblogic.wsee.jaxws.spi.WLSProvider$ServiceDelegateImpl$3.apply(WLSProvider.java:1517)
at weblogic.wsee.jaxws.spi.ClientIdentityRegistry.initClientIdentityFeatureAndCall(ClientIdentityRegistry.java:1456)
at weblogic.wsee.jaxws.spi.WLSProvider$ServiceDelegateImpl.getPort(WLSProvider.java:1513)
at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:420)
at weblogic.wsee.jaxws.spi.WLSProvider$ServiceDelegateImpl.getPort(WLSProvider.java:1477)
at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:402)
at javax.xml.ws.Service.getPort(Service.java:119)
at org.parsisys.test.mina.model.service.WebServiceModuleService_Service.beaInvokeSuper(WebServiceModuleService_Service.java)
at org.parsisys.test.mina.model.service.WebServiceModuleService_Service$beaVersion0_31.getWebServiceModuleServiceSoapHttpPort(WebServiceModuleService_Service.java:51)
at org.parsisys.test.mina.model.service.WebServiceModuleService_Service.getWebServiceModuleServiceSoapHttpPort(WebServiceModuleService_Service.java)
at org.parsisys.test.mina.files.notification.queue.NotificationQueueRecieved$beaVersion0_11.onMessage(NotificationQueueRecieved.java:330)
at org.parsisys.test.mina.files.notification.queue.NotificationQueueRecieved.onMessage(NotificationQueueRecieved.java)
at weblogic.jms.client.JMSSession.onMessage(JMSSession.java:5107)
at weblogic.jms.client.JMSSession.execute(JMSSession.java:4775)
at weblogic.jms.client.JMSSession.executeMessage(JMSSession.java:4170)
at weblogic.jms.client.JMSSession.access$000(JMSSession.java:127)
at weblogic.jms.client.JMSSession$UseForRunnable.run(JMSSession.java:5627)
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:666)
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:348)
at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:333)
at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:54)
at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:640)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:406)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:346)
please help me. tnx
For me this occurs when the WSDL does not agree with the generated classes.

Verify OAuth1a signed request using Twitter joauth with RSA-SHA1?

I have a use case to authenticate OAuth1 request which is signed using RSA Private Key and verified at server end with RSA public key.
I found this library from Twitter which helps us authenticate/verify the Oauth signed requests. https://github.com/twitter/joauth
I want to leverage this library for verifying the request from Jersey or Spring MVC action method. The request from client would have been signed using private key. At my end I would use the public key of the client to verify the request. which means RSA-SHA1 algo.
Twitter joauth seem to be useful but I am missing the code that would transform HttpServletRequest to OAuthRequest
The library read-me file suggests this as facility but I could not find a code that does javax.servlet.http.HttpServletRequest --> com.twitter.joauth.OAuthRequest transformation.
The request verification happens in verify method which has following signature.
public VerifierResult verify(UnpackedRequest.OAuth1Request request, String tokenSecret, String consumerSecret);
Secondly I also want to know which is the most appropriate way to use/read RSA public key with twitter joauth when verify method takes String parameter ?
I have never used any library to authenticate users via Twitter. But I have just looked in the UnpackedRequest.OAuth1Request. You can create an instance of this class by filling all parameters. I have written Twitter OAuth Header creator, so you can just use it to fill those parameters or send POST requests directly without a library.
Here all classes what you need:
Signature - to generate an OAuth Signature.
public class Signature {
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
public static String calculateRFC2104HMAC(String data, String key)
throws java.security.SignatureException
{
String result;
try {
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data.getBytes());
result = new String(Base64.encodeBase64(rawHmac));
} catch (Exception e) {
throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
}
return result;
}
}
NvpComparator - to sort parameters you need in the header.
public class NvpComparator implements Comparator<NameValuePair> {
#Override
public int compare(NameValuePair arg0, NameValuePair arg1) {
String name0 = arg0.getName();
String name1 = arg1.getName();
return name0.compareTo(name1);
}
}
OAuth - for URL encode.
class OAuth{
...
public static String percentEncode(String s) {
return URLEncoder.encode(s, "UTF-8")
.replace("+", "%20").replace("*", "%2A")
.replace("%7E", "~");
}
...
}
HeaderCreator - to create all needed parameters and generate an OAuth header param.
public class HeaderCreator {
private String authorization = "OAuth ";
private String oAuthSignature;
private String oAuthNonce;
private String oAuthTimestamp;
private String oAuthConsumerSecret;
private String oAuthTokenSecret;
public String getAuthorization() {
return authorization;
}
public String getoAuthSignature() {
return oAuthSignature;
}
public String getoAuthNonce() {
return oAuthNonce;
}
public String getoAuthTimestamp() {
return oAuthTimestamp;
}
public HeaderCreator(){}
public HeaderCreator(String oAuthConsumerSecret){
this.oAuthConsumerSecret = oAuthConsumerSecret;
}
public HeaderCreator(String oAuthConsumerSecret, String oAuthTokenSecret){
this(oAuthConsumerSecret);
this.oAuthTokenSecret = oAuthTokenSecret;
}
public String getTwitterServerTime() throws IOException, ParseException {
HttpsURLConnection con = (HttpsURLConnection)
new URL("https://api.twitter.com/oauth/request_token").openConnection();
con.setRequestMethod("HEAD");
con.getResponseCode();
String twitterDate= con.getHeaderField("Date");
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
Date date = formatter.parse(twitterDate);
return String.valueOf(date.getTime() / 1000L);
}
public String generatedSignature(String url, String method, List<NameValuePair> allParams,
boolean withToken) throws SignatureException {
oAuthNonce = String.valueOf(System.currentTimeMillis());
allParams.add(new BasicNameValuePair("oauth_nonce", oAuthNonce));
try {
oAuthTimestamp = getTwitterServerTime();
allParams.add(new BasicNameValuePair("oauth_timestamp", oAuthTimestamp));
}catch (Exception ex){
//TODO: Log!!
}
Collections.sort(allParams, new NvpComparator());
StringBuffer params = new StringBuffer();
for(int i=0;i<allParams.size();i++)
{
NameValuePair nvp = allParams.get(i);
if (i>0) {
params.append("&");
}
params.append(nvp.getName() + "=" + OAuth.percentEncode(nvp.getValue()));
}
String signatureBaseStringTemplate = "%s&%s&%s";
String signatureBaseString = String.format(signatureBaseStringTemplate,
OAuth.percentEncode(method),
OAuth.percentEncode(url),
OAuth.percentEncode(params.toString()));
String compositeKey = OAuth.percentEncode(oAuthConsumerSecret)+"&";
if(withToken) compositeKey+=OAuth.percentEncode(oAuthTokenSecret);
oAuthSignature = Signature.calculateRFC2104HMAC(signatureBaseString, compositeKey);
return oAuthSignature;
}
public String generatedAuthorization(List<NameValuePair> allParams){
authorization = "OAuth ";
Collections.sort(allParams, new NvpComparator());
for(NameValuePair nvm : allParams){
authorization+=nvm.getName()+"="+OAuth.percentEncode(nvm.getValue())+", ";
}
authorization=authorization.substring(0,authorization.length()-2);
return authorization;
}
}
Explain:
1. getTwitterServerTime
In oAuthTimestamp you need not your time of server but the time of a Twitter server. You can optimize it saving this param if you always send requests in the certain Twitter server.
2. HeaderCreator.generatedSignature(...)
url - logically url to twitter API
method - GET or POST. You must use always "POST"
allParams - Parameters which you know to generate signature ("param_name", "param_value");
withToken - if you know oAuthTokenSecret put true. Otherwise false.
3. HeaderCreator.generatedAuthorization(...)
Use this method after generatedSignature(...) to generate an OAuth header string.
allParams - it is parameters which you have used in generatedSignature(...) plus: nonce, signature, timestamp. Always use:
allParams.add(new BasicNameValuePair("oauth_nonce", headerCreator.getoAuthNonce()));
allParams.add(new BasicNameValuePair("oauth_signature", headerCreator.getoAuthSignature()));
allParams.add(new BasicNameValuePair("oauth_timestamp", headerCreator.getoAuthTimestamp()));
Now you can use it to fill UnpackedRequest.OAuth1Request in your library. Also here an example to authenticate user in SpringMVC without the library:
Requests - to send post requests.
public class Requests {
public static String sendPost(String url, String urlParameters, Map<String, String> prop) throws Exception {
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setRequestMethod("POST");
if(prop!=null) {
for (Map.Entry<String, String> entry : prop.entrySet()) {
con.setRequestProperty(entry.getKey(), entry.getValue());
}
}
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
BufferedReader in;
if(responseCode==200) {
in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
}else{
in = new BufferedReader(
new InputStreamReader(con.getErrorStream()));
}
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
}
twAuth(...) - put it in your controller. Execute it when an user want to authenticate in your site via Twitter.
#RequestMapping(value = "/twauth", method = RequestMethod.GET)
#ResponseBody
public String twAuth(HttpServletResponse response) throws Exception{
try {
String url = "https://api.twitter.com/oauth/request_token";
List<NameValuePair> allParams = new ArrayList<NameValuePair>();
allParams.add(new BasicNameValuePair("oauth_callback", "http://127.0.0.1:8080/twlogin"));
allParams.add(new BasicNameValuePair("oauth_consumer_key", "2YhNLyum1VY10UrWBMqBnatiT"));
allParams.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
allParams.add(new BasicNameValuePair("oauth_version", "1.0"));
HeaderCreator headerCreator = new HeaderCreator("RUesRE56vVWzN9VFcfA0jCBz9VkvkAmidXj8d1h2tS5EZDipSL");
headerCreator.generatedSignature(url,"POST",allParams,false);
allParams.add(new BasicNameValuePair("oauth_nonce", headerCreator.getoAuthNonce()));
allParams.add(new BasicNameValuePair("oauth_signature", headerCreator.getoAuthSignature()));
allParams.add(new BasicNameValuePair("oauth_timestamp", headerCreator.getoAuthTimestamp()));
Map<String, String> props = new HashMap<String, String>();
props.put("Authorization", headerCreator.generatedAuthorization(allParams));
String twitterResponse = Requests.sendPost(url,"",props);
Integer indOAuthToken = twitterResponse.indexOf("oauth_token");
String oAuthToken = twitterResponse.substring(indOAuthToken, twitterResponse.indexOf("&",indOAuthToken));
response.sendRedirect("https://api.twitter.com/oauth/authenticate?" + oAuthToken);
}catch (Exception ex){
//TODO: Log
throw new Exception();
}
return "main";
}
twLogin(...) - put it in your controller. It is callback from Twitter.
#RequestMapping(value = "/twlogin", method = RequestMethod.GET)
public String twLogin(#RequestParam("oauth_token") String oauthToken,
#RequestParam("oauth_verifier") String oauthVerifier,
Model model, HttpServletRequest request){
try {
if(oauthToken==null || oauthToken.equals("") ||
oauthVerifier==null || oauthVerifier.equals(""))
return "main";
String url = "https://api.twitter.com/oauth/access_token";
List<NameValuePair> allParams = new ArrayList<NameValuePair>();
allParams.add(new BasicNameValuePair("oauth_consumer_key", "2YhNLyum1VY10UrWBMqBnatiT"));
allParams.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
allParams.add(new BasicNameValuePair("oauth_token", oauthToken));
allParams.add(new BasicNameValuePair("oauth_version", "1.0"));
NameValuePair oAuthVerifier = new BasicNameValuePair("oauth_verifier", oauthVerifier);
allParams.add(oAuthVerifier);
HeaderCreator headerCreator = new HeaderCreator("RUesRE56vVWzN9VFcfA0jCBz9VkvkAmidXj8d1h2tS5EZDipSL");
headerCreator.generatedSignature(url,"POST",allParams,false);
allParams.add(new BasicNameValuePair("oauth_nonce", headerCreator.getoAuthNonce()));
allParams.add(new BasicNameValuePair("oauth_signature", headerCreator.getoAuthSignature()));
allParams.add(new BasicNameValuePair("oauth_timestamp", headerCreator.getoAuthTimestamp()));
allParams.remove(oAuthVerifier);
Map<String, String> props = new HashMap<String, String>();
props.put("Authorization", headerCreator.generatedAuthorization(allParams));
String twitterResponse = Requests.sendPost(url,"oauth_verifier="+oauthVerifier,props);
//Get user id
Integer startIndexTmp = twitterResponse.indexOf("user_id")+8;
Integer endIndexTmp = twitterResponse.indexOf("&",startIndexTmp);
if(endIndexTmp<=0) endIndexTmp = twitterResponse.length()-1;
Long userId = Long.parseLong(twitterResponse.substring(startIndexTmp, endIndexTmp));
//Do what do you want...
}catch (Exception ex){
//TODO: Log
throw new Exception();
}
}

How to access ehcache mbeans on weblogic server

In my weblogic server ehcache is deployed , I need to get ehcahe mbeans from this program through java programming, Through JMX i am not able to connect.how can i get those custom mbeans??
i tried to get mbeans through weblogic t3 protocol
public class Test
{
private String hostName = "";
private String port = "";
private String userName = "";
private String password = "";
private String connectorURL = "service:jmx:rmi:///jndi/rmi://{0}:{1}/jmxrmi";
private JMXConnector jmxc = null;
public static void main(String []args) throws Exception
{
Test t = new Test();
t.hostName = args[0];
System.out.println(args[1]);
t.port = args[1];
t.userName = args[2];
t.password = args[3];
t.jmxc = t.initConnection();
MBeanServerConnection mbsc = t.jmxc.getMBeanServerConnection();
System.out.println(mbsc);
Set<ObjectInstance> st =mbsc.queryMBeans(new ObjectName("net.*:*"), null);
System.out.println(st.toString());
Iterator<ObjectInstance> it = st.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
t.closeConnection();
}
private JMXConnector initConnection()
{
System.out.println("initiate connection");
JMXServiceURL serviceURL = null;
try
{
String jndiroot = "/jndi/";
String mserver = "weblogic.management.mbeanservers.domainruntime";
int port1 = Integer.parseInt(port);
serviceURL = new JMXServiceURL("t3", hostName, port1, jndiroot + mserver);
Hashtable h = new Hashtable();
h.put(Context.SECURITY_PRINCIPAL, userName);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
long lngJmxClientWTO = 10000;
h.put("jmx.remote.x.request.waiting.timeout", lngJmxClientWTO );
return JMXConnectorFactory.connect(serviceURL, h);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
/**
* This method closes client connection with server
* #throws IOException
*/
public void closeConnection()
{
if(jmxc != null)
{
try
{
jmxc.close();
}
catch (IOException e) {
jmxc = null;
}
}
}
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
CacheManager manager = CacheManager.newInstance();
Ehcache cache = manager.getEhcache("Some cache name here..."); //<-- PLEASE EDIT THE CACHE NAME...
I don't know if this is what you're asking for....
Once you've obtained your cache, you can use it, pretty much like a java Map.
You can follow the Ehcache documentation to see how to programmatically get the remote cache. Essentially, you will need to create a configuration (or configuration file) which the CacheManager can access.

XMPP with Java Asmack library supporting X-FACEBOOK-PLATFORM

I'm trying to make a Facebook Chat on Android with the Smack library. I've read the Chat API from Facebook, but I cannot understand how I have to authenticate with Facebook using this library.
Can anyone point me how to accomplish this?
Update: According to the no.good.at.coding answer, I have this code adapted to the Asmack library. All works fine except I receive as response to the login: not-authorized. Here is the code I use:
public class SASLXFacebookPlatformMechanism extends SASLMechanism
{
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String applicationSecret = "";
private String sessionKey = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
{
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException
{
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
}
#Override
public void authenticate(String apiKeyAndSessionKey, String host,
String applicationSecret) throws IOException, XMPPException
{
if (apiKeyAndSessionKey == null || applicationSecret == null)
{
throw new IllegalArgumentException("Invalid parameters");
}
String[] keyArray = apiKeyAndSessionKey.split("\\|", 2);
if (keyArray.length < 2)
{
throw new IllegalArgumentException(
"API key or session key is not present");
}
this.apiKey = keyArray[0];
Log.d("API_KEY", apiKey);
this.applicationSecret = applicationSecret;
Log.d("SECRET_KEY", applicationSecret);
this.sessionKey = keyArray[1];
Log.d("SESSION_KEY", sessionKey);
this.authenticationId = sessionKey;
this.password = applicationSecret;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc =
Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
this);
authenticate();
}
#Override
protected String getName()
{
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException
{
byte[] response = null;
if (challenge != null)
{
String decodedChallenge = new String(Base64.decode(challenge));
Log.d("DECODED", decodedChallenge);
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis() / 1000L;
String sig =
"api_key=" + apiKey + "call_id=" + callId + "method="
+ method + "nonce=" + nonce + "session_key="
+ sessionKey + "v=" + version + applicationSecret;
try
{
sig = md5(sig);
sig = sig.toUpperCase();
} catch (NoSuchAlgorithmException e)
{
throw new IllegalStateException(e);
}
String composedResponse =
"api_key=" + URLEncoder.encode(apiKey, "utf-8")
+ "&call_id=" + callId + "&method="
+ URLEncoder.encode(method, "utf-8") + "&nonce="
+ URLEncoder.encode(nonce, "utf-8")
+ "&session_key="
+ URLEncoder.encode(sessionKey, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8") + "&sig="
+ URLEncoder.encode(sig, "utf-8");
Log.d("COMPOSED", composedResponse);
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null)
{
authenticationText =
Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query)
{
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params)
{
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
private String md5(String text) throws NoSuchAlgorithmException,
UnsupportedEncodingException
{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(text.getBytes("utf-8"), 0, text.length());
return convertToHex(md.digest());
}
private String convertToHex(byte[] data)
{
StringBuilder buf = new StringBuilder();
int len = data.length;
for (int i = 0; i < len; i++)
{
int halfByte = (data[i] >>> 4) & 0xF;
int twoHalfs = 0;
do
{
if (0 <= halfByte && halfByte <= 9)
{
buf.append((char) ('0' + halfByte));
}
else
{
buf.append((char) ('a' + halfByte - 10));
}
halfByte = data[i] & 0xF;
} while (twoHalfs++ < 1);
}
return buf.toString();
}
}
And this, is the communication with the server with the sent and received messages:
PM SENT (1132418216): <stream:stream to="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">
PM RCV (1132418216): <?xml version="1.0"?><stream:stream id="C62D0F43" from="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xml:lang="en"><stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>
PM SENT (1132418216): <auth mechanism="X-FACEBOOK-PLATFORM" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth>
PM RCV (1132418216): <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9NzFGNkQ3Rjc5QkIyREJCQ0YxQTkwMzA0QTg3OTlBMzM=</challenge>
PM SENT (1132418216): <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">YXBpX2tleT0zMWYzYjg1ZjBjODYwNjQ3NThiZTZhOTQyNjVjZmNjMCZjYWxsX2lkPTEzMDA0NTYxMzUmbWV0aG9kPWF1dGgueG1wcF9sb2dpbiZub25jZT03MUY2RDdGNzlCQjJEQkJDRjFBOTAzMDRBODc5OUEzMyZzZXNzaW9uX2tleT0yNjUzMTg4ODNkYWJhOGRlOTRiYTk4ZDYtMTAwMDAwNTAyNjc2Nzc4JnY9MS4wJnNpZz04RkRDRjRGRTgzMENGOEQ3QjgwNjdERUQyOEE2RERFQw==</response>
PM RCV (1132418216): <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>
As read in the developers Facebook forum, it is needed to disable the "Disable Deprecated Auth Methods" setting from the Facebook settings page of your app. But, even doing that, I can't login. And the session key is the second part of the OAuth token in the form AAA|BBB|CCC, I mean, BBB.
Finally, thanks to the no.good.at.coding code and the suggestion of harism, I've been able to connect to the Facebook chat. This code is the Mechanism for the Asmack library (the Smack port for Android). For the Smack library is necessary to use the no.good.at.coding mechanism.
SASLXFacebookPlatformMechanism.java:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
import org.apache.harmony.javax.security.sasl.Sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.util.Base64;
public class SASLXFacebookPlatformMechanism extends SASLMechanism
{
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String applicationSecret = "";
private String sessionKey = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
{
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException
{
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
}
#Override
public void authenticate(String apiKeyAndSessionKey, String host,
String applicationSecret) throws IOException, XMPPException
{
if (apiKeyAndSessionKey == null || applicationSecret == null)
{
throw new IllegalArgumentException("Invalid parameters");
}
String[] keyArray = apiKeyAndSessionKey.split("\\|", 2);
if (keyArray.length < 2)
{
throw new IllegalArgumentException(
"API key or session key is not present");
}
this.apiKey = keyArray[0];
this.applicationSecret = applicationSecret;
this.sessionKey = keyArray[1];
this.authenticationId = sessionKey;
this.password = applicationSecret;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc =
Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
this);
authenticate();
}
#Override
public void authenticate(String username, String host, CallbackHandler cbh)
throws IOException, XMPPException
{
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc =
Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
cbh);
authenticate();
}
#Override
protected String getName()
{
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException
{
byte[] response = null;
if (challenge != null)
{
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis();
String sig =
"api_key=" + apiKey + "call_id=" + callId + "method="
+ method + "nonce=" + nonce + "session_key="
+ sessionKey + "v=" + version + applicationSecret;
try
{
sig = md5(sig);
} catch (NoSuchAlgorithmException e)
{
throw new IllegalStateException(e);
}
String composedResponse =
"api_key=" + URLEncoder.encode(apiKey, "utf-8")
+ "&call_id=" + callId + "&method="
+ URLEncoder.encode(method, "utf-8") + "&nonce="
+ URLEncoder.encode(nonce, "utf-8")
+ "&session_key="
+ URLEncoder.encode(sessionKey, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8") + "&sig="
+ URLEncoder.encode(sig, "utf-8");
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null)
{
authenticationText =
Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query)
{
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params)
{
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
private String md5(String text) throws NoSuchAlgorithmException,
UnsupportedEncodingException
{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(text.getBytes("utf-8"), 0, text.length());
return convertToHex(md.digest());
}
private String convertToHex(byte[] data)
{
StringBuilder buf = new StringBuilder();
int len = data.length;
for (int i = 0; i < len; i++)
{
int halfByte = (data[i] >>> 4) & 0xF;
int twoHalfs = 0;
do
{
if (0 <= halfByte && halfByte <= 9)
{
buf.append((char) ('0' + halfByte));
}
else
{
buf.append((char) ('a' + halfByte - 10));
}
halfByte = data[i] & 0xF;
} while (twoHalfs++ < 1);
}
return buf.toString();
}
}
To use it:
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
XMPPConnection xmpp = new XMPPConnection(config);
try
{
SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
xmpp.connect();
xmpp.login(apiKey + "|" + sessionKey, sessionSecret, "Application");
} catch (XMPPException e)
{
xmpp.disconnect();
e.printStackTrace();
}
apiKey is the API key given in the application settings page in Facebook. sessionKey is the second part of the access token. If the token is in this form, AAA|BBB|CCC, the BBB is the session key. sessionSecret is obtained using the old REST API with the method auth.promoteSession. To use it, it's needed to make a Http get to this url:
https://api.facebook.com/method/auth.promoteSession?access_token=yourAccessToken
Despite of the Facebook Chat documentation says that it's needed to use your application secret key, only when I used the key that returned that REST method I was able to make it works. To make that method works, you have to disable the Disable Deprecated Auth Methods option in the Advance tab in your application settings.
I'd used this about 6 months ago with Smack (not asmack) so I'm not sure how it'll hold up now but here goes, hope it helps!
I found an implementation of Facebook's X-FACEBOOK-PLATFORM authentication mechanism on the Ignite Realtime Smack forum where someone got it from the fbgc project. You'll find the a ZIP with the SASLXFacebookPlatformMechanism.java source in the answer I linked to. You can use it as follows:
public void login() throws XMPPException
{
SASLAuthentication.registerSASLMechanism(SASLXFacebookPlatformMechanism.NAME,
SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism(SASLXFacebookPlatformMechanism.NAME, 0);
ConnectionConfiguration connConfig = new ConnectionConfiguration(host, port);
XMPPConnection connection = new XMPPConnection(connConfig);
connection.connect();
log.info("XMPP client connected");
connection.login(Utils.FB_APP_ID + "|" + this.user.sessionId, Utils.FB_APP_SECRET, "app_name");
log.info("XMPP client logged in");
}
I was doing this on the server without an SDK. I don't remember the details (and the Facebook documentation isn't very good) but from what I can tell from my code, after getting the user to authorize the app, I get a callback request from Facebook with a code parameter. I open a URLConnection to https://graph.facebook.com/oauth/access_token?client_id=<app_id>&redirect_uri=http://myserver/context/path/&client_secret=<app_secret>&code=<code>. The response should be the access token where the session id is the part after the | - something of the form XXX|<sessionId>.
Here's code I've been using successfully for authentication. Maybe this helps even though this is not related to Smack in any way. You can get sessionKey from access token received from FB, and for getting sessionSecret I've been using oldish REST API;
http://developers.facebook.com/docs/reference/rest/auth.promoteSession/
private final void processChallenge(XmlPullParser parser, Writer writer,
String sessionKey, String sessionSecret) throws IOException,
NoSuchAlgorithmException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, null, "challenge");
String challenge = new String(Base64.decode(parser.nextText(),
Base64.DEFAULT));
String params[] = challenge.split("&");
HashMap<String, String> paramMap = new HashMap<String, String>();
for (int i = 0; i < params.length; ++i) {
String p[] = params[i].split("=");
p[0] = URLDecoder.decode(p[0]);
p[1] = URLDecoder.decode(p[1]);
paramMap.put(p[0], p[1]);
}
String api_key = "YOUR_API_KEY";
String call_id = "" + System.currentTimeMillis();
String method = paramMap.get("method");
String nonce = paramMap.get("nonce");
String v = "1.0";
StringBuffer sigBuffer = new StringBuffer();
sigBuffer.append("api_key=" + api_key);
sigBuffer.append("call_id=" + call_id);
sigBuffer.append("method=" + method);
sigBuffer.append("nonce=" + nonce);
sigBuffer.append("session_key=" + sessionKey);
sigBuffer.append("v=" + v);
sigBuffer.append(sessionSecret);
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(sigBuffer.toString().getBytes());
byte[] digest = md.digest();
StringBuffer sig = new StringBuffer();
for (int i = 0; i < digest.length; ++i) {
sig.append(Integer.toHexString(0xFF & digest[i]));
}
StringBuffer response = new StringBuffer();
response.append("api_key=" + URLEncoder.encode(api_key));
response.append("&call_id=" + URLEncoder.encode(call_id));
response.append("&method=" + URLEncoder.encode(method));
response.append("&nonce=" + URLEncoder.encode(nonce));
response.append("&session_key=" + URLEncoder.encode(sessionKey));
response.append("&v=" + URLEncoder.encode(v));
response.append("&sig=" + URLEncoder.encode(sig.toString()));
StringBuilder out = new StringBuilder();
out.append("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>");
out.append(Base64.encodeToString(response.toString().getBytes(),
Base64.NO_WRAP));
out.append("</response>");
writer.write(out.toString());
writer.flush();
}
I'm sorry to make new answer but I had to include the new code #YShinkarev sorry for being late
By modifying #Adrian answer to make challengeReceived we can use APIKey and accessToken all I modified was the composedResponse
#Override
public void challengeReceived(String challenge) throws IOException {
byte[] response = null;
if (challenge != null) {
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis();
String composedResponse = "api_key="
+ URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId
+ "&method=" + URLEncoder.encode(method, "utf-8")
+ "&nonce=" + URLEncoder.encode(nonce, "utf-8")
+ "&access_token="
+ URLEncoder.encode(access_token, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8");
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null) {
authenticationText = Base64.encodeBytes(response,
Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
What do you want to do?
If you just want to login on FB chat, you connect to FB just like any other XMPP server.
I would look at and use "Authenticating with Username/Password" from Chat API, wich is supported by Smack. Unless I would like to write an FaceBook-application. Then I would try to login in with "Authenticating with Facebook Platform".
So, just use Smack to connect to FB chat as you would do with your ordinary Jabber client.
For the username, use your Facebook username. (see http://www.facebook.com/username/ )
For the domain, use: chat.facebook.com
For the password, use your Facebook password
Turn off SSL and TSL
Set connect port to: 5222 (which is the default for XMPP)
Set connect server to chat.facebook.com

Categories