I am trying to create a java program that will search for certain files in Box Storage. For this i am trying to use the Box Java SDK and i created an application in Box (https://app.box.com/developers/services).
When i use the developer token i am able to traverse through my box parent/child folders. Since this token is valid for 60 mins i want to programmatically retrieve and set the token. When i looked at the manuals it says to manully call api's to get these tokens.
I tried the below code..
BoxAPIConnection api = new BoxAPIConnection(clientid,clientsecret);
String accesstoken = api.getAccessToken();
String refreshtoken = api.getRefreshToken();
I dont want to throw a box login page to the user and want to run this program as a daemon which will search files and spit out some report text file.
Thanks for all the help.
It is possible to manage Box login through code.
For the first time you access Box.com and get the client id, client secret, access token and refresh token.
Save it in DB or property file.
Use below code, and each and every time update the actual access and refresh token.
String accessToken = // access token from DB/property
String refreshToken = // refresh token from DB/property
String boxClientId = // client id from DB/property
String boxClientSecret = // client secret from DB/property
try {
BoxAPIConnection api = new BoxAPIConnection(boxClientId, boxClientSecret, accessToken, refreshToken);
api.addListener(new BoxAPIConnectionListener() {
#Override
public void onRefresh(BoxAPIConnection api) {
String newAccessToken = api.getAccessToken();
String newrefreshToken = api.getRefreshToken();
// update new access and refresh token in DB/property
}
#Override
public void onError(BoxAPIConnection api, BoxAPIException error) {
LOGGER.error("Error in Box account details. " + error.getMessage());
}
});
LOGGER.debug("Completed Box authentication");
} catch (Exception e) {
LOGGER.error("Error in Box authentication. Error msg : " + e.getMessage());
}
If you use a state.conf file, you'll be able to refresh the token/refres_token pair programmatically without getting an auth code. Here's a code snippet that I use:
private static BoxAPIConnection getBoxAPIConnection(String client_id, String client_secret, String token, String refresh_token, String stateConfPath) {
String state = null;
try {
logger.info("Getting state.conf: " + stateConfPath + "/state.conf");
InputStream fis = new FileInputStream(stateConfPath + "/state.conf");
InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8"));
BufferedReader br = new BufferedReader(isr);
state = br.readLine();
}
catch (FileNotFoundException f) {
try {
// create file if it doesn't exist
PrintWriter writer = new PrintWriter(stateConfPath + "/state.conf", "UTF-8");
writer.println("");
writer.close();
}
catch (Exception w) {
logger.fatal("Exception", w);
}
}
catch (IOException e) {
logger.fatal("IOException", e);
}
BoxAPIConnection api = null;
//if (null == state || "".equals(state)) {
if (!token.equals("") && !refresh_token.equals("")) {
api = new BoxAPIConnection(client_id, client_secret, token, refresh_token);
} else {
logger.info("Restoring state..." + state);
api = BoxAPIConnection.restore(client_id, client_secret, state);
if (api.needsRefresh()) { // this is not a reliable call. It can still throw a 401 below
logger.info("api refreshing...");
api.refresh();
}
else {
logger.info("api good...");
}
}
return api;
}
Related
I am using the admin sdk API to retrieve all G Suite users. We require an access token for this. AWS is used to host our website. I've tried a few different codes to generate access token, but they always return error
"Server returned HTTP response code: 401 for URL: https://accounts.google.com/o/oauth2/token."
I have no idea why this error is occurring. My code is running smoothly, generating access token and retrieving every user domain wise in a local environment. Any help in why actually I am getting this error. have i missed something? any help in it.
This is my code.
private String getAccessToken()
{
String accessToken="";
try
{
Map<String,Object> params = new LinkedHashMap<>();
params.put("grant_type","refresh_token");
params.put("client_id",client_id);
params.put("client_secret",client_secret);
params.put("refresh_token",refresh_token);
StringBuilder postData = new StringBuilder();
for(Map.Entry<String,Object> param : params.entrySet())
{
if(postData.length() != 0)
{
postData.append('&');
}
postData.append(URLEncoder.encode(param.getKey(),"UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()),"UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
URL url = new URL("https://accounts.google.com/o/oauth2/token");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestMethod("POST");
con.getOutputStream().write(postDataBytes);
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuffer buffer = new StringBuffer();
for (String line = reader.readLine(); line != null; line = reader.readLine())
{
buffer.append(line);
}
JSONObject json = new JSONObject(buffer.toString());
accessToken = json.getString("access_token");
return accessToken;
}
catch (Exception ex)
{
ex.printStackTrace();
}
return accessToken;
}
I'm using CAS build SSO, I want to implement login/logout by using CAS RESTful API in my own Web Application.
and the api like this http://sso.cvs.cn:9990/cas-server-webapp/v1/tickets
i test it by test case, and it succesful. here is the code:
public static void main(String... args) throws Exception {
String username = "123";
String password = "123";
validateFromCAS(username, password);
}
public static boolean validateFromCAS(String username, String password) throws Exception {
String url = "http://sso.cvs.cn:9990/cas-server-webapp/v1/tickets";
try {
HttpURLConnection hsu = (HttpURLConnection) openConn(url);
String s = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8");
s += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8");
System.out.println(s);
OutputStreamWriter out = new OutputStreamWriter(hsu.getOutputStream());
BufferedWriter bwr = new BufferedWriter(out);
bwr.write(s);
bwr.flush();
bwr.close();
out.close();
String tgt = hsu.getHeaderField("location");
System.out.println(hsu.getResponseCode());
if (tgt != null && hsu.getResponseCode() == 201) {
System.out.println(tgt);
System.out.println("Tgt is : " + tgt.substring(tgt.lastIndexOf("/") + 1));
tgt = tgt.substring(tgt.lastIndexOf("/") + 1);
bwr.close();
closeConn(hsu);
String serviceURL = "http://sso.cvs.cn:7070/cas-simple-site-alpha/";
String encodedServiceURL = URLEncoder.encode("service", "utf-8") + "=" + URLEncoder.encode(serviceURL, "utf-8");
System.out.println("Service url is : " + encodedServiceURL);
String myURL = url + "/" + tgt;
System.out.println(myURL);
hsu = (HttpURLConnection) openConn(myURL);
out = new OutputStreamWriter(hsu.getOutputStream());
bwr = new BufferedWriter(out);
bwr.write(encodedServiceURL);
bwr.flush();
bwr.close();
out.close();
System.out.println("Response code is: " + hsu.getResponseCode());
BufferedReader isr = new BufferedReader(new InputStreamReader(hsu.getInputStream()));
String line;
System.out.println(hsu.getResponseCode());
while ((line = isr.readLine()) != null) {
System.out.println(line);
}
isr.close();
hsu.disconnect();
return true;
} else {
return false;
}
} catch (MalformedURLException mue) {
mue.printStackTrace();
throw mue;
} catch (IOException ioe) {
ioe.printStackTrace();
throw ioe;
}
}
but how i can use the api in my web application?
If i understand correctly your question is how the api would be usefull for you in general.
So if this is the case, with restful api enabled on cas, when a user gets authenticated by CAS server, he would be allowed to access other applications (cas enabled services) which are configured to have SSO with the same CAS server. Also you can do requests for tickets with POST as the documentation suggests.
Also another reason is that applications need to programmatically access CAS. Say one casified application can invoke other casified application’s REST APIs on behalf of an authenticated user. For this purpose CAS Rest protocol will do the job
I am working with the Google Provisioning API. I have used Web Application type project from Google developer console. I have used Diamto blog and samples and it works perfectly on my local with all options like FileStore, Custom File Store, Service Account etc but when I uploaded on server user consent screen just doesn't pops up with any options like FileStore, Custom File Store. I spent days to figure out problem and solutions but nothing has worked for me so far.
my configuration
My server configuration is windows server 2008 datacenter r2,.net 4.5,IIS 7.5.
Service account works perfectly but I need to do it by Consent screen so Web Application type of project.
I have used google .net client library with version 1.9.2.27817.
I am just highlighting main code where it gets stuck and rest is same as per Diamto post and github examples.
Let me know if you need more info.
Code
public static DirectoryService AuthenticateOauth(string clientId, string clientSecret, string userName, IDataStore datastore)
{
string[] scopes = new string[] {DirectoryService.Scope.AdminDirectoryUser };
try
{
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
, scopes
, userName
, CancellationToken.None
, datastore).Result; // at this point it calls getasynch method for custom datasource
DirectoryService service = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "GoogleProv",
});
return service;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return null;
}
}
{
HttpClientInitializer = credential,
ApplicationName = "GoogleProv",
});
return service;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return null;
}
}
///<summary>
// Returns the stored value for the given key or <c>null</c> if the matching file (<see cref="GenerateStoredKey"/>
// in <see cref="FolderPath"/> doesn't exist.
// </summary>
// <typeparam name="T">The type to retrieve</typeparam>
// <param name="key">The key to retrieve from the data store</param>
// <returns>The stored object</returns>
public Task<T> GetAsync<T>(string key)
{
//Key is the user string sent with AuthorizeAsync
if (string.IsNullOrEmpty(key))
{
throw new ArgumentException("Key MUST have a value");
}
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
// Note: create a method for opening the connection.
SqlConnection myConnection = new SqlConnection(myconn);
myConnection.Open();
// Try and find the Row in the DB.
using (SqlCommand command = new SqlCommand("select RefreshToken from GoogleUser where UserName = #username;", myConnection))
{
command.Parameters.AddWithValue("#username", key);
string RefreshToken = null;
SqlDataReader myReader = command.ExecuteReader();
while (myReader.Read())
{
RefreshToken = myReader["RefreshToken"].ToString();
}
if (RefreshToken == null )
{
// we don't have a record so we request it of the user.
tcs.SetResult(default(T)); // it comes here
}
else
{
try
{
// we have it we use that.
tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(RefreshToken));
}
catch (Exception ex)
{
tcs.SetException(ex);
}
}
}
return tcs.Task; // it comes here and than gets hang forever
}
Any of your help is highly appreciated.
I include a Kerberos ticket header in a request to a service, but as I'm doing works, but says that is SoapContext.Security absoleto.
Can anyone help me fix this?
The code I have is this:
private void button1_Click(object sender, EventArgs e)
{
try
{
//default option selected is Kerberos.
string option = "Kerberos";
if (radioButton1.Checked)
option = "UserName";
if (radioButton2.Checked)
option = "Kerberos";
//declare any Security Token
SecurityToken token = null;
switch (option)
{
case "UserName":
{
try
{
//create a username Token.
UsernameToken unToken = new UsernameToken(textBox1.Text, textBox2.Text, PasswordOption.SendPlainText);
//assign the any SecurityToken an Username Token.
token = unToken;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
break;
}
case "Kerberos":
{
try
{
Console.WriteLine(System.Net.Dns.GetHostName());
//create a kerberos Token.
KerberosToken kToken = new KerberosToken(System.Net.Dns.GetHostName());
//assign the any SecurityToken an Username Token.
token = kToken;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
break;
}
default:
{
break;
}
}
if (token == null)
throw new ApplicationException("Unable to obtain security token.");
// Create an instance of the web service proxy that has been generated.
SecureServiceProxy.WebService1 proxy = new ClientTest.SecureServiceProxy.WebService1();
proxy.SetPolicy("KerberosClient");
//set the time to live to any value.
proxy.RequestSoapContext.Security.Timestamp.TtlInSeconds = 60;
// Add the SecurityToken to the SOAP Request Context.
proxy.RequestSoapContext.Security.Tokens.Add(token);
// Sign the SOAP message with a signatureobject.
proxy.RequestSoapContext.Security.Elements.Add(new MessageSignature(token));
// Create and Send the request
long a = long.Parse(textLong1.Text);
long b = long.Parse(textLong2.Text);
//call the web service.
long result = proxy.perform(a, b);
//Display the result.
MessageBox.Show(a + " + " + b + " = " + result.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
return;
}
}
And my warning appears saying that it is absoleto the following lines of code:
proxy.RequestSoapContext.Security.Timestamp.TtlInSeconds = 60;
// Add the SecurityToken to the SOAP Request Context.
proxy.RequestSoapContext.Security.Tokens.Add(token);
// Sign the SOAP message with a signatureobject.
proxy.RequestSoapContext.Security.Elements.Add(new MessageSignature(token));
But do not know how to solve
I've been trying to post something to my application's timeline/feed/wall on Fb, for the better part of the day but I keep failing. This is getting frustrating.
What I'm doing is : I'm having a simple console C# app, that is trying to post something on the application's wall (a basic hello world!, for instance).
This snippet shows how I'm retrieving an access token :
private string _AccessToken;
public string AccessToken
{
get
{
if (string.IsNullOrEmpty(_AccessToken))
{
//_AccessToken = string.Format("{0}|{1}", Credentials.AppId, Credentials.AppSecret);
Logger.Debug("Attempting to retrieve the access token...");
dynamic result = ExecuteGet("oauth/access_token", new
{
client_id = Credentials.AppId, // my app id
client_secret = Credentials.AppSecret, // my app secret
grant_type = "client_credentials",
scope = "manage_pages,publish_actions,publish_stream"
}, false);
_AccessToken = result.access_token;
}
Logger.Debug("Operation succeeded, access token is : {0}", _AccessToken);
return _AccessToken;
}
}
private object ExecuteGet(string path, object parameters)
{
return ExecuteGet(path, parameters, true);
}
private object ExecuteGet(string path, object parameters, bool useAccessToken)
{
try
{
Logger.Debug("Executing GET : {0}", path);
var client = useAccessToken ? new FacebookClient(AccessToken) : new FacebookClient();
return client.Get(path, parameters);
}
catch (FacebookApiException ex)
{
Logger.Error("GET Operation failed : {0}", ex.Message);
throw;
}
}
And this is how I'm trying to actually post something :
public void PostToApplicationWall(string message)
{
string path = string.Format("/{0}/feed", Credentials.AppId);
IDictionary<string, object> parameters = new Dictionary<string, object>()
{
{ "description", "[DESCRIPTION] Facebook description..." },
{ "link", "http://tinyurl.org" },
{ "name", "[NAME] Facebook name..." },
{ "caption", "[CAPTION] Facebook caption..." },
{ "message", message }
};
dynamic result = ExecutePost(path, parameters);
}
private object ExecutePost(string path, object parameters)
{
try
{
Logger.Debug("Executing POST : {0}", path);
var client = new FacebookClient(AccessToken);
return client.Post(path, parameters);
}
catch (FacebookApiException ex)
{
Logger.Error("POST Operation failed : {0}", ex.Message);
throw;
}
}
Please note that ExecutePost() uses the AccessToken property, I've pasted in the beginning.
The message that I'm getting is : (OAuthException - #210) (#210) Subject must be a page
Please help, I have no idea what am I doing wrong.
Maciek, if you really just want to post to your own page, writing a standalone app may not be the easiest way to do this. Have you tried PowerShell and http://facebookpsmodule.codeplex.com? This module will take care of the permissioning for you, and let you do this operation with a simple script.
App profile pages are discontinued since Feburary 1st 2012. You have to create an app page. Read here.
Now, when you have an app page, you change your code like this:
string path = string.Format("/{0}/feed", Credentials.PageId);
OR
string path = string.Format("/{0}/feed", Credentials.PageUsername);
[EDIT]
For posting to a page, you need the page access token instead of app access token. Read here on how to get a page access token.