I'm trying to upload Photos to Flickr thru ASP.NET file upload control and flickrnet. But the samples under flickrnet.codeplex.com are, redirecting the page to flickr for authorization and come back.
Is there a way to upload the files with out redirecting to authorization page in asp.net C#?
Yes. I'm able to. First you need FlickrManager Instance for that use below code for that
public class FlickrManager
{
public const string ApiKey = "get it from flickr website";
public const string SharedSecret = "get it from flickr website";
public static Flickr GetInstance()
{
return new Flickr(ApiKey, SharedSecret);
}
public static Flickr GetAuthInstance()
{
var f = new Flickr(ApiKey, SharedSecret);
if (OAuthToken != null)
{
f.OAuthAccessToken = OAuthToken.Token;
f.OAuthAccessTokenSecret = OAuthToken.TokenSecret;
}
return f;
}
public static OAuthAccessToken OAuthToken
{
get
{
if (HttpContext.Current.Request.Cookies["OAuthToken"] == null)
{
return null;
}
var values = HttpContext.Current.Request.Cookies["OAuthToken"].Values;
return new OAuthAccessToken
{
FullName = values["FullName"],
Token = values["Token"],
TokenSecret = values["TokenSecret"],
UserId = values["UserId"],
Username = values["Username"]
};
}
set
{
// Stores the authentication token in a cookie which will expire in 1 hour
var cookie = new HttpCookie("OAuthToken")
{
Expires = DateTime.UtcNow.AddHours(1),
};
cookie.Values["FullName"] = value.FullName;
cookie.Values["Token"] = value.Token;
cookie.Values["TokenSecret"] = value.TokenSecret;
cookie.Values["UserId"] = value.UserId;
cookie.Values["Username"] = value.Username;
HttpContext.Current.Response.AppendCookie(cookie);
}
}
}
Once above Class created, you can start using below method in anywhere in aspx page. Please let me know if you have challenge.
public string FilckerUpload(string url, string title, string description, string tags)
{
OAuthAccessToken accessToken = new OAuthAccessToken();
accessToken.FullName = "your app name";
accessToken.Token = "get it from Flickr Website for your login";
accessToken.TokenSecret = "get it from Flickr Website for your login";
accessToken.UserId = "get it from Flickr Website for your login";
accessToken.Username = "get it from Flickr Website for your login";
FlickrManager.OAuthToken = accessToken;
Flickr flickr = FlickrManager.GetAuthInstance();
string FileuploadedID = flickr.UploadPicture(#url, title, description, tags, true, false, false);
PhotoInfo oPhotoInfo = flickr.PhotosGetInfo(FileuploadedID);
return oPhotoInfo.Small320Url;
}
Related
There are two type of application in my solution
1)Web api application
2)MMC c# application
Here I created web api application which has facility of token authentication.
In this Application username and password validating from SQL server database.
i.e If any user request for web api token that user detail must be present in database table.(In user Table Id,Username,Password column are there with data).
So my web api application connected to database server.
Now I created MVC c# application which consume web api and access the data.
what I do here that when user put credential to mvc app login screen and that credential goes to api and validate them.
Api will give response of data If user credential are correct.
Here I got JSON response from web api and data like "access_token","Expire_time","refresh_token" etc
I stored all these detail in Session object.
So whenever I request for Getdata() from mvc app I passing 'access_token' to api and retuned result data.
I set web api token timeout 2 minutes.(token get deleted after 2 minutes)
So problem goes here that how I can maintain user login session in web api using refresh_token.I do not want to user again get login screen and come back to that screen.
Because every 2 minutes he will get login screen which is not correct solution.
I want some function when api get timeout access_token and mvc application again call refresh_token and continue data transaction.
Whenever your accesstoken is expired you can pass refresh token and can update the access token like this. Hope this will help you.
[AllowAnonymous]
[HttpPost]
public IHttpActionResult GetAccessToken(RefreshTokenModel getRefreshToken)
{
ApiResponse apiResponse = new ApiResponse();
apiResponse.Message = "Your session has expired. Kindly login again.";
try
{
var getHashToken = GenerateHash.GetHash(getRefreshToken.RefreshToken);
var getRefreshTokenDetails = tokenDetailBl.GetRefreshTokenDetail(getHashToken);
if (getRefreshTokenDetails != null && getRefreshTokenDetails.ExpiresUtc > DateTime.UtcNow && !string.IsNullOrEmpty(getRefreshTokenDetails.ProtectedTicket))
{
if (getRefreshTokenDetails.DeviceType == getRefreshToken.DeviceType)
{
var currentTime = DateTime.UtcNow;
var refreshTokenLifeTime = Convert.ToDouble(ConfigurationManager.AppSettings["RefreshTokenExpireTime"]);
var tokenExpiration = Convert.ToDouble(ConfigurationManager.AppSettings["AccessTokenExpireTime"]);
ApiIdentityManager apiIdentityManager = new ApiIdentityManager();
var tokenData = JsonConvert.SerializeObject(new { Ticket = getRefreshTokenDetails.ProtectedTicket, DeviceId = getRefreshTokenDetails.DeviceId });
var getIdentityToken = apiIdentityManager.GetRefreshToken(tokenData);
// Delete Old Tokens
tokenDetailBl.DeleteAccessTokenByDevice(getRefreshTokenDetails.DeviceId);
var refreshToken = new RefreshToken()
{
RefreshTokenId = GenerateHash.GetHash(getIdentityToken.RefreshToken),
DeviceId = getRefreshTokenDetails.DeviceId,
DeviceType = getRefreshToken.DeviceType,
UserId = getRefreshTokenDetails.UserId,
IssuedUtc = currentTime,
ExpiresUtc = currentTime.AddMinutes(Convert.ToDouble(refreshTokenLifeTime)),
ProtectedTicket = getIdentityToken.Ticket
};
//Save new tokens
tokenDetailBl.SaveAccessToken(new TokenDetail
{
AccessToken = getIdentityToken.AccessToken,
CreatedOn = DateTime.UtcNow,
UserId = getRefreshTokenDetails.UserId,
DeviceId = getRefreshTokenDetails.DeviceId,
DeviceType = getRefreshToken.DeviceType
});
tokenDetailBl.SaveRefreshToken(refreshToken);
//Get token cache.
CachedData cachedData = new CachedData(tokenDetailBl);
var getAllToken = cachedData.GetAccessTokens();
cachedData.UpdateTokenCache(getIdentityToken.AccessToken, getRefreshTokenDetails.UserId + ":" + DateTime.UtcNow.AddMinutes(tokenExpiration).ToFormateDateTimeString());
var getUserDetails = userBl.GetUserDetails(getRefreshToken.UserId);
getUserDetails.DeviceId = getRefreshTokenDetails.DeviceId;
getUserDetails.DeviceType = getRefreshTokenDetails.DeviceType;
getUserDetails.AccessToken = getIdentityToken.AccessToken;
getUserDetails.TokenType = "bearer";
getUserDetails.ExpiresIn = getIdentityToken.ExpiresIn;
getUserDetails.Issued = getIdentityToken.Issued;
getUserDetails.Expires = DateTime.UtcNow.Add(TimeSpan.FromMinutes(tokenExpiration)).ToString("R");
getUserDetails.RefreshToken = getIdentityToken.RefreshToken;
//Dictionary<string, string> tokenResponse = new Dictionary<string, string>();
//tokenResponse.Add("access_token", getIdentityToken.AccessToken);
//tokenResponse.Add("token_type", "bearer");
//tokenResponse.Add("expires_in", getIdentityToken.ExpiresIn);
//tokenResponse.Add("issued", getIdentityToken.Issued);
//tokenResponse.Add("expires", DateTime.UtcNow.Add(TimeSpan.FromMinutes(tokenExpiration)).ToString("R"));
//tokenResponse.Add("refresh_token", getIdentityToken.RefreshToken);
return ResponseMessage(Request.CreateResponse(HttpStatusCode.OK, getUserDetails));
}
else
{
apiResponse.Message = "Your session has expired. Kindly login again.";
}
}
}
catch (Exception ex)
{
Logger.Error(ex);
}
return ResponseMessage(Request.CreateResponse(HttpStatusCode.Gone, apiResponse));
}
You can use MVC filters to check that your access token is expired or not something like this.
[CacheAuthorize]
[HttpPost]
public IHttpActionResult GetUserList(SearchRequest searchRequest)
and after that code to check validation of access token
public class CacheAuthorizeAttribute : AuthorizeAttribute
{
public CacheAuthorizeAttribute(params string[] roles)
: base()
{
Roles = string.Join(",", roles);
}
public override void OnAuthorization(HttpActionContext actionContext)
{
Dictionary<HttpStatusCode, string> response;
if (SkipAuthorization(actionContext))
{
return;
}
var userSessionManager = new UserCacheManager();
if (userSessionManager.ReValidateSession(out response))
{
base.OnAuthorization(actionContext);
}
else
{
ApiResponse apiResponse = new ApiResponse(response.Values.FirstOrDefault());
actionContext.Response = actionContext.ControllerContext.Request.CreateResponse(response.Keys.FirstOrDefault(), apiResponse);
}
}
/// <summary>
/// Re-validates the user session. Usually called at each authorization request.
/// If the session is not expired, extends it lifetime and returns true.
/// If the session is expired or does not exist, return false.
/// </summary>
/// <returns>true if the session is valid</returns>
public bool ReValidateSession(out Dictionary<HttpStatusCode, string> errorResponse)
{
errorResponse = new Dictionary<HttpStatusCode, string>();
string authToken = this.GetCurrentBearerAuthrorizationToken();
ITokenDetailRepository tokenDetailRepository = new TokenDetailRepository();
ITokenDetailBL tokenDetailBl = new TokenDetailBL(tokenDetailRepository);
CachedData cachedData = new CachedData(tokenDetailBl);
if (!string.IsNullOrEmpty(authToken))
{
var currentUserId = this.GetCurrentUserId();
var getUserTokens = cachedData.GetAccessTokens();
if (!getUserTokens.ContainsKey(authToken))
{
//Get Data from DB
cachedData.GetAccessToken(authToken);
getUserTokens = cachedData.GetAccessTokens();
}
return CheckAccessToken(getUserTokens, authToken, out errorResponse);
}
else
{
errorResponse.Add(HttpStatusCode.Gone, "Access token not found.");
}
return false;
}
private bool CheckAccessToken(Dictionary<string, string> accessTokenDictionary, string authToken, out Dictionary<HttpStatusCode, string> errorResponse)
{
errorResponse = new Dictionary<HttpStatusCode, string>();
var hasToken = accessTokenDictionary.ContainsKey(authToken);
if (hasToken)
{
var getTokenValue = accessTokenDictionary[authToken];
var enCulture = new CultureInfo("en-US");
DateTime tokenAddedDate;
var isCorrectDate = DateTime.TryParseExact(getTokenValue.Split(new char[] { ':' }, 2)[1], "dd-MMM-yyyy,hh:mm tt", enCulture, DateTimeStyles.None, out tokenAddedDate);
if (isCorrectDate)
{
if (tokenAddedDate >= DateTime.UtcNow)
{
return true;
}
else
{
//Check Refresh token expired or not
errorResponse.Add(HttpStatusCode.Unauthorized, "Access token expired.");
}
}
else
{
errorResponse.Add(HttpStatusCode.Gone, "Invalid access token.");
}
}
else
{
errorResponse.Add(HttpStatusCode.Gone, "Invalid access token.");
}
return false;
}
In my c# application I am trying to get accesstoken/authentication token for user using facebook c# sdk.
If I use response_type = 'code' then I am getting data in my callback function but when I use response_type = 'token' then data is coming as null.
Bellow is my code when i use response_type = 'code'
private Uri RedirectUri
{
get
{
var uriBuilder = new UriBuilder(Request.Url);
uriBuilder.Query = null;
uriBuilder.Fragment = null;
uriBuilder.Path = Url.Action("FacebookCallback");
return uriBuilder.Uri;
}
}
public ActionResult FacebookLogin()
{
var fb = new FacebookClient();
var loginUrl = fb.GetLoginUrl(new
{
client_id = "146137372750966",
client_secret = "",
redirect_uri = RedirectUri.AbsoluteUri,
response_type = "code",
scope = "public_profile,email",
state = "gsdfgjpfosd34956834"
});
return Redirect(loginUrl.AbsoluteUri);
}
public ActionResult FacebookCallback(string code)
{
}
Bellow is code when i use response_type = 'token'
private Uri RedirectUri
{
get
{
var uriBuilder = new UriBuilder(Request.Url);
uriBuilder.Query = null;
uriBuilder.Fragment = null;
uriBuilder.Path = Url.Action("FacebookCallback");
return uriBuilder.Uri;
}
}
public ActionResult FacebookLogin()
{
var fb = new FacebookClient();
var loginUrl = fb.GetLoginUrl(new
{
client_id = "146137372750966",
client_secret = "",
redirect_uri = RedirectUri.AbsoluteUri,
response_type = "token",
scope = "public_profile,email",
state = "gsdfgjpfosd34956834"
});
return Redirect(loginUrl.AbsoluteUri);
}
public ActionResult FacebookCallback(string code)
{
}
I am not able to identify the mistake I am doing when passing response_type = "token",
Url which is returning is something like this.
http://localhost:32432/FacebookCallback?#state=gsdfgjpfosd34956834&access_token=lfahfegldskgjsdgdslkkghlsgfsgmndf;lhjd&expires_in=3927
How do I read this in my callback function ?
I am using Twitterizer dll to post a twit on twitter via oauth method but it give me error.
"Whoa there!
There is no request token for this page. That's the special key we need from applications asking to use your Twitter account. Please go back to the site or application that sent you here and try again; it was probably just a mistake."
And my code is:
using System;
using Twitterizer;
public partial class Home : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var oauth_consumer_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var oauth_consumer_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
if (Request["oauth_token"] == null)
{
OAuthTokenResponse reqToken = OAuthUtility.GetRequestToken(oauth_consumer_key, oauth_consumer_secret,
Request.Url.AbsoluteUri);
Response.Redirect(string.Format("http://Twitter.com/oauth/authorize?oauth_token+{0}", reqToken.Token));
}
else
{
string requestToken = Request["oauth_token"].ToString();
string pin = Request["oauth_verifier"].ToString();
var tokens = OAuthUtility.GetAccessToken(oauth_consumer_key, oauth_consumer_secret, requestToken, pin);
OAuthTokens accessToken = new OAuthTokens()
{
AccessToken = tokens.Token,
AccessTokenSecret = tokens.TokenSecret,
ConsumerKey = oauth_consumer_key,
ConsumerSecret = oauth_consumer_secret
};
TwitterResponse<TwitterStatus> response = TwitterStatus.Update(accessToken, "Hello everyone, today it's too hot (weather)!!!");
if (response.Result == RequestResult.Success)
{
Response.Write("It's done");
}
else
{
Response.Write("Fail");
}
}
}
}
Please help me..
Seeing no one is giving an answer to your problem, I can suggest the library I am working on.
With Tweetinvi you will be able to do what you want with the following code :
// Step 1 : Redirect user to go on Twitter.com to authenticate
public ActionResult TwitterAuth()
{
var appCreds = new ConsumerCredentials("CONSUMER_KEY", "CONSUMER_SECRET");
// Specify the url you want the user to be redirected to
var redirectURL = "http://" + Request.Url.Authority + "/Home/ValidateTwitterAuth";
var authenticationContext = AuthFlow.InitAuthentication(appCreds, redirectURL);
return new RedirectResult(authenticationContext.AuthorizationURL);
}
// Step 2 : On redirected url
public ActionResult ValidateTwitterAuth()
{
// Get some information back from the URL
var verifierCode = Request.Params.Get("oauth_verifier");
var authorizationId = Request.Params.Get("authorization_id");
// Create the user credentials
var userCreds = AuthFlow.CreateCredentialsFromVerifierCode(verifierCode, authorizationId);
// Do whatever you want with the user now!
ViewBag.User = User.GetAuthenticatedUser(userCreds);
return View();
}
Authentication Documentation : https://github.com/linvi/tweetinvi/wiki/Authentication
I know this is not helping for your Twitterizer but you might want to consider it.
Google has new api Google.Apis.
I have desktop application which authorize user by google account. Old API stop working.
How can I authorize user by new API, but WITHOUT webauthorizationBroker in C#? I do not want open webbroswer, I have own win form for enter login and password.
EDITED:
Here is old code:
string fullname = string.Empty;
UserService userService = new UserService("APPKEY");
userService.setUserCredentials(username, Encryptor.Decrypt(password));
try
{
string token = userService.QueryClientLoginToken();
GOAuthRequestFactory reqF = new GOAuthRequestFactory("apps", "APPKEY") { ConsumerKey = "KEY", ConsumerSecret = "SECRET" };
userService = new UserService("APPKEY") { RequestFactory = reqF };
UserQuery query = new UserQuery("DOMAIN", true);
UserFeed usersFeed = userService.Query(query);
UserEntry entry = (UserEntry)usersFeed.Entries.FirstOrDefault(f => (f as UserEntry).Login.UserName == userName);
fullname = string.Format("{0} {1}", entry.Name.GivenName, entry.Name.FamilyName);
}
catch (InvalidCredentialsException ex)
{
service.SendError(ex.Message);
return fullname;
}
return fullname;
I have this below code to get calendar entries using the google Calendar API (https://developers.google.com/google-apps/calendar/) which uses OAuth2.
It works well.
private IList<string> scopes = new List<string>();
private CalendarService calendarService;
private void InitializeCalendarService()
{
// Add the calendar specific scope to the scopes list
scopes.Add(CalendarService.Scopes.Calendar.GetStringValue());
// Display the header and initialize the sample
CommandLine.EnableExceptionHandling();
CommandLine.DisplayGoogleSampleHeader("Google.Api.Calendar.v3 Sample");
// Create the authenticator
//FullClientCredentials credentials = PromptingClientCredentials.EnsureFullClientCredentials();
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);
FullClientCredentials credentials = new FullClientCredentials();
credentials.ClientId = "XYZ.apps.googleusercontent.com";
credentials.ClientSecret = "XYZ";
credentials.ApiKey = "XYZ";
provider.ClientIdentifier = credentials.ClientId;
provider.ClientSecret = credentials.ClientSecret;
OAuth2Authenticator<NativeApplicationClient> auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);
// Create the calendar service using an initializer instance
BaseClientService.Initializer initializer = new BaseClientService.Initializer();
initializer.Authenticator = auth;
calendarService = new CalendarService(initializer);
CalendarList list = calendarService.CalendarList.List().Execute();
// do something with the list .. the list is all good
}
public IAuthorizationState GetAuthorization(NativeApplicationClient client)
{
// You should use a more secure way of storing the key here as
// .NET applications can be disassembled using a reflection tool.
const string STORAGE = "google.samples.dotnet.calendar";
const string KEY = "s0mekey";
// Check if there is a cached refresh token available.
IAuthorizationState state = AuthorizationMgr.GetCachedRefreshToken(STORAGE, KEY);
if ((state != null))
{
try
{
client.RefreshToken(state);
return state;
// we are done
}
catch (DotNetOpenAuth.Messaging.ProtocolException ex)
{
CommandLine.WriteError("Using an existing refresh token failed: " + ex.Message);
CommandLine.WriteLine();
}
}
// Retrieve the authorization from the user
string[] array = new string[scopes.Count];
scopes.CopyTo(array,0);
state = AuthorizationMgr.RequestNativeAuthorization(client, array);
AuthorizationMgr.SetCachedRefreshToken(STORAGE, KEY, state);
return state;
}
How can I use the similar OAuth2Authenticator to fetch Contacts?
I am able to fetch contacts using the below code, but its not password-less, I need to get it working using Oath2. The example below uses Gdata contacts api v2. I can see that i can pass through OAuth2Authenticator but im not exactly sure how to do it correctly (i cant see any valid examples in C# on the google site) and fetch the access code based on what the user is selecting.
I cant see how to use OAuth2Authenticator with the contacts api v3 (https://developers.google.com/google-apps/contacts/v3/)
RequestSettings rsLoginInfo = new RequestSettings("", email,pwd);
rsLoginInfo.AutoPaging = true;
ContactsRequest cRequest = new ContactsRequest(rsLoginInfo);
// fetch contacts list
Feed<Contact> feedContacts = cRequest.GetContacts();
foreach (Contact gmailAddresses in feedContacts.Entries)
{
// Looping to read email addresses
foreach (EMail emailId in gmailAddresses.Emails)
{
lstContacts.Add(emailId.Address);
}
}
I ended up doing this by fetching the access code by having a browser control read the Document title value when the user selects the google account and grants access.
eg:
To Generate URL
RedirectURI = "urn:ietf:wg:oauth:2.0:oob"
OAuth2Parameters parameters = new OAuth2Parameters()
{
ClientId = clientId,
ClientSecret = clientSecret,
RedirectUri = redirectUri,
Scope = requiredScope
};
// Request authorization from the user (by opening a browser window):
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
var loginUri = new Uri(url);
// This form has browser control
GoogleLoginForm form = new GoogleLoginForm(loginUri, redirectUri);
var dr = form.ShowDialog();
if (dr == System.Windows.Forms.DialogResult.OK)
{
parameters.AccessCode = form.OAuthVerifierToken;
}
Then In GoogleLoginForm :
We have a browser control and registered browserControl_Navigated event and the do the below. The DocumentTitle contains the AccessCode which is used to generate the token.
private void GoogleLoginForm_Load(object sender, EventArgs e)
{
wbGoogleLogin.Url = _loginUri;
}
private void wbGoogleLogin_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
string fullPath = e.Url.ToString();
WebBrowser control = sender as WebBrowser;
if (control != null && !string.IsNullOrEmpty(control.DocumentTitle) && control.DocumentTitle.Contains("Success code"))
{
_OAuthVerifierToken = control.DocumentTitle.Replace("Success code=","");
DialogResult = DialogResult.OK;
}
}
This way it can be done in the same piece of code, without having to write a complicated callback service of some sort to read the access token back into our system.
Not exactly sure why the calendar api has this built in, and the contacts API doesn't.
Firstly, the quick answer to your question. I believe that the IAuthorizationState has similar properties to OAuth2Parameters. Thus, you should be able to do this (combining it with the code you have for the calender):
OAuth2Authenticator<NativeApplicationClient> auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);
//This will call your GetAuthorization method
auth.LoadAccessToken()
RequestSettings settings = new RequestSettings("appName", auth.State.AccessToken);
ContactsRequest cRequest = new ContactsRequest(settings);
// fetch contacts list
Feed<Contact> feedContacts = cRequest.GetContacts();
foreach (Contact gmailAddresses in feedContacts.Entries)
{
// Looping to read email addresses
foreach (EMail emailId in gmailAddresses.Emails)
{
lstContacts.Add(emailId.Address);
}
}
This should work as the RequestSettings allows you to specify an access token. That being said, I myself prefer to use :
var parameters = new OAuth2Parameters()
{
//Client
ClientId = CLIENT_ID,
ClientSecret = CLIENT_SECRET,
RedirectUri = redirectUri,
Scope = "https://www.google.com/m8/feeds",
ResponseType = "code"
};
//User clicks this auth url and will then be sent to your redirect url with a code parameter
var authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
.
.
.
//using the code parameter
parameters.AccessCode = code;
OAuthUtil.GetAccessToken(parameters);
var settings = new RequestSettings(applicationName, parameters);
var cr = new ContactsRequest(settings);
//Now you can use contacts as you would have before
Although, Ive only tested this with Web Server Apps, so maybe the authenticator is needed for your situation? I found these source codes handy:
OAuth2Demo
IAuthorizationState
OAuth2Authenticator