var appCredentials = new FitbitAppCredentials()
{
ClientId = "227RD5", //ConfigurationManager.AppSettings["FitbitClientId"],
ClientSecret = "468c585ba98fc84e463952ca7a306c07" //ConfigurationManager.AppSettings["FitbitClientSecret"]
};
string UserId = Convert.ToBase64String((Encoding.ASCII.GetBytes("3J9685")));
string code = Request.Params["code"];
StringBuilder dataRequestUrl = new StringBuilder();
dataRequestUrl.Append("https://api.fitbit.com/1/user/-");
dataRequestUrl.Append("/profile.json");
HttpWebRequest dataRequest = (HttpWebRequest)WebRequest.Create(dataRequestUrl.ToString());
dataRequest.Method = "POST";
string _auth = string.Format("{0}:{1}", appCredentials.ClientId, appCredentials.ClientSecret);
var _encbyte = Encoding.ASCII.GetBytes(_auth);
string _enc = Convert.ToBase64String(_encbyte);
string _authorizationHeader = string.Format("{0} {1}", "Bearer", _enc);
dataRequest.Headers["Authorization"] = _authorizationHeader;
dataRequest.ContentType = "application/x-www-form-urlencoded";
dataRequest.Accept = "application/json";
string responseJson;
HttpWebResponse response = null;
try
{
response = dataRequest.GetResponse() as HttpWebResponse;
}
catch (WebException webEx)
{
response = webEx.Response as HttpWebResponse;
}
catch (Exception ex)
{
throw ex;
}
using (var reader = new StreamReader(response.GetResponseStream()))
{
responseJson = reader.ReadToEnd();
}
Above code give me unauthorized access error. Any one can find that what is the issue in code.I can authorize the user and refresh the user token but when I will try to get userprofile.json call it will give me unauthorized access error.
For getting user profile information, we need only access-token sent as part of header.
You don't need clientId and ClientSecret for getting profile information.
Change your code like this:
StringBuilder dataRequestUrl = new StringBuilder();
dataRequestUrl.Append("https://api.fitbit.com/1/user/-/profile.json");
HttpWebRequest dataRequest = (HttpWebRequest)WebRequest.Create(dataRequestUrl.ToString());
String accessToken = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiXXXXXXXXXX";
dataRequest.Method = "GET";
dataRequest.Headers.Add("Authorization","Bearer "+ accessToken);
dataRequest.ContentType = "application/json";
string responseJson;
HttpWebResponse response = null;
try
{
response = dataRequest.GetResponse() as HttpWebResponse;
}
catch (WebException webEx)
{
response = webEx.Response as HttpWebResponse;
}
catch (Exception ex)
{
throw ex;
}
using (var reader = new StreamReader(response.GetResponseStream()))
{
responseJson = reader.ReadToEnd();
}
Related
I have to implement three-legged authentication in ASP.NET MVC. I have followed the steps according to the Blackboard documentation, especially the link https://community.blackboard.com/docs/DOC-3976-three-legged-oauth
I have received authorization code by calling the REST API /learn/api/public/v1/oauth2/authorizationcode.After that according to the documentation (I followed the documentation exactly but I don't know what am I have been missing ), I built a POST request to /learn/api/public/v1/oauth2/token to get access_token but I am unable to get access_token.
Instead, access_token, I have been receiving a BadRequest. This means I am making a mistake to build my second request but I am unable to fix the problem. I haven't found any code sample in .NET to implement three legged authentication for Blackboard Learn. Could you please help me to resolve the issue?
This is my code to call both APIs to receive access_token.
public class HomeController : Controller
{
public ActionResult Index()
{
// GET /learn/api/public/v1/oauth2/authorizationcode
Guid stateId = Guid.NewGuid();
string applicationKey = "Application key goes here";
string redirectUrl = string.Format("https://Blackboard Learn URL goes here/learn/api/public/v1/oauth2/authorizationcode" +
"?redirect_uri=https://localhost:44300/Home/OAuth2Response&response_type=code&client_id={0}&scope=read&state={1}",
applicationKey, stateId);
Response.Redirect(redirectUrl, true);
return View();
}
public async Task<bool> OAuth2Response(string code = null, string state = null, string error = null, string error_description = null)
{
bool success = true;
string json = string.Empty;
string urlCommand = string.Format("/learn/api/public/v1/oauth2/token?code={0}&redirect_url=https://localhost:44300/Home/OAuth2Response", code);
try
{
using (HttpClient client = new HttpClient())
{
var endpoint = new Uri("Blackboard Learn URL goes here" + urlCommand);
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
HttpContent body = new FormUrlEncodedContent(postData);
// POST /learn/api/public/v1/oauth2/token
using (HttpResponseMessage response = await client.PostAsync(endpoint, body)) // Problem is here
{
if (response.IsSuccessStatusCode)
{
json = await response.Content.ReadAsStringAsync();
}
else
{
success = false;
}
}
}
}
catch (Exception err)
{
//hopefully we never end up here, log this exception for forensics
success = false;
}
return success;
}
}
NOTE: I can successfully receive an access_token in Postman tool.
Finally, the below code works perfectly for 3 legged authentications in ASP.NET MVC.
public class HomeController : Controller
{
//https://blackboard.jiveon.com/docs/DOC-3976-three-legged-oauth
public ActionResult Index()
{
// GET /learn/api/public/v1/oauth2/authorizationcode
Guid stateId = Guid.NewGuid();
string applicationKey = "Application key goes here";
string redirectUrl = string.Format("Blackboard Learn URL goes here/learn/api/public/v1/oauth2/authorizationcode" +
"?redirect_uri=https://localhost:44300/Home/OAuth2Response&response_type=code&client_id={0}&scope=read&state={1}",
applicationKey, stateId);
Response.Redirect(redirectUrl, true);
return View();
}
public async Task<bool> OAuth2Response(string code = null, string state = null, string error = null, string error_description = null)
{
bool success = true;
string json = string.Empty;
string urlCommand = string.Format("/learn/api/public/v1/oauth2/token?code={0}&redirect_uri=https://localhost:44300/Home/OAuth2Response", code);
try
{
using (HttpClient client = new HttpClient())
{
var endpoint = new Uri("Blackboard Learn URL goes here" + urlCommand);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("client_id:client_secret")));
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
HttpContent body = new FormUrlEncodedContent(postData);
using (HttpResponseMessage response = await client.PostAsync(endpoint, body))
{
if (response.IsSuccessStatusCode)
{
json = await response.Content.ReadAsStringAsync();
dynamic oauth2Result = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
string access_token = oauth2Result.access_token;
string refresh_token = oauth2Result.refresh_token; }
else
{
success = false;
}
}
}
}
catch (Exception err) {
//hopefully we never end up here, log this exception for forensics
success = false;
}
return success;
}
}
I implemented OAuth2 in my mvc web api project.I got the token but when I call the web api methods with this token the call will return 403 forbidden.I also called the same web api without the token it's working.Here is my token call:
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
AccountLogin LogCredentials = new AccountLogin();
LogCredentials.UserName = context.UserName;
LogCredentials.Password = context.Password;
LogCredentials.IPAddress = "::1";
string webHost = Convert.ToString(WebConfigurationManager.AppSettings["webHost"]);
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { webHost });
ProviderLoginResponse providerLoginResponse = MembershipService.UserLogin(LogCredentials);
if (providerLoginResponse.LoginStatus != "Y")
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return Task.FromResult<object>(null);
}
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Sid, Convert.ToString(providerLoginResponse.UserID)),
new Claim(ClaimTypes.Name, providerLoginResponse.UserName),
new Claim(ClaimTypes.Email, providerLoginResponse.UserEmail)
};
ClaimsIdentity oAuthIdentity = new ClaimsIdentity(claims,
Startup.OAuthOptions.AuthenticationType);
AuthenticationProperties properties = CreateProperties(providerLoginResponse);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
return Task.FromResult<object>(null);
}
Here is my api method:
[HttpGet]
[Route("GetColumn")]
public HttpResponseMessage GetColumn(HttpRequestMessage request)
{
string tableName = "";
HttpResponseMessage response = null;
try
{
var clientList = _settingsService.GetColumns(tableName);
response = request.CreateResponse(HttpStatusCode.OK, new APIResponse { Status = true, Data = clientList, Message = Messages.Saved_Success });
}
catch (Exception ex)
{
response = request.CreateResponse(HttpStatusCode.OK, new APIResponse { Status = false, Data = null, Message = ex.Message });
}
return response;
}
My api call is :
function GetColumn(data, cb) {
var token = sessionStorage.getItem('accessToken');
var headers = {};
if (token) {
headers.Authorization = 'Bearer ' + token;
}
$.ajax({
type: 'GET',
url: "api/Settings/GetColumn",
headers: headers
}).done(function (data) {
cb(data);
}).fail(function (Res) {
cb(Res);
});
};
I also tried the postman by passing the Authorization token but still got the 403.I searched the web for this problem but nothing will solve my problem .Why it is behaving like this?
I am trying to receive one simple sentence from a webservice, but I have something wrong.
This is my async task to request from the webservice:
private async Task<string> GetData (string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create (new Uri(url));
request.ContentType = "text/plain";
request.Method = "GET";
using (WebResponse response = await request.GetResponseAsync())
{
using (Stream stream = response.GetResponseStream())
{
string doc = await Task.Run(() => stream.ToString());
return doc;
}
}
}
And this is my button:
cmd02.Click += async (sender, e) => {
string sentence = await GetData(url);
txt01.Text = sentence;
};
I get only "System.Net.WebConnectionStream" into my TextView and donĀ“t know which function I should use. Or maybe everthing is wrong?
Maybe somebody has an idea?
public static async Task<string> SendGetRequestAsync (string url) {
string responseString = "";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
request.Method = WebRequestMethods.Http.Get;
HttpWebResponse response;
await Task.Run (() => {
try {
response = request.GetResponse () as HttpWebResponse;
using (var reader = new StreamReader (response.GetResponseStream ())) {
responseString = reader.ReadToEnd ();
}
} catch (WebException ex) {
Console.WriteLine (ex);
}
});
return responseString;
}
I'm develop a web api2 where I post json data.
The code of this api is:
public HttpResponseMessage Post(an_lavanderie an_lavanderie)
{
var response = new HttpResponseMessage();
if (!ModelState.IsValid)
{
response = Request.CreateErrorResponse(HttpStatusCode.NotFound, new Exception("modello non valido"));
}
bool creato = _repoLavanderie.CreaLavanderia(an_lavanderie);
if (creato == true)
{
response = Request.CreateResponse(HttpStatusCode.OK);
}
else
{
response = Request.CreateErrorResponse(HttpStatusCode.NotFound, new Exception("Errore nella creazione"));
}
return response;
}
This code write into db correctly.
My code to POST DATA is this:
var risultato = PostDataAsync();
and the function is
var lav1 = new Lavanderia()
{
rag_soc = "Ragione Sociale",
rag_soc2 = "Ragione sociale2",
indirizzo = "Via Crispi 27",
citta = "Ovada",
provincia = "AL",
isAttiva = "N",
portalkey = "sample string 1",
isPortalVisibile = "S",
cap = "15057"
};
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56040/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.PostAsJsonAsync("api/CreaLavanderia", lav1);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
MessageBox.Show("Crezione effettuata correttamente");
}
else
{
MessageBox.Show("Creazione non effettuata");
}
}
return "";
Post operation is ok, but when await don't fire.
Is possible that the return Message from webapi is not correct?
Where is the problem?
Thanks.
Since you are using await and you're saying that it's not firing make sure that your method is marked with the keyword async.
My windows phone client sends a piece of JSON that represents the Name and Score... Should I be using the Class from the Web API instead ? What is the code to send the object to the server rather than the raw json?
private void btnCreateSampleScore_Click(object sender, RoutedEventArgs e)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://punkoutersoftware.azurewebsites.net");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("Bob", "2.65")
});
var result = client.PostAsync("/api/DrunkMeterScore", content).Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
Console.WriteLine(resultContent);
//DrunkMeterScore dms = new DrunkMeterScore();
//dms.Name = "Bob";
//dms.Score = 2.42;
}
}
The server is using the plain Web API template
// POST api/DrunkMeterScore
public HttpResponseMessage PostDrunkMeterScore(DrunkMeterScore drunkmeterscore)
{
if (ModelState.IsValid)
{
db.DrunkMeterScores.Add(drunkmeterscore);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, drunkmeterscore);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = drunkmeterscore.DrunkMeterScoreId }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
edit1:
I tried both of these.. They both hang and never come back during the PostAsync calls :(
var client = new HttpClient();
client.BaseAddress = new Uri("http://punkoutersoftware.azurewebsites.net");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var score = new DrunkMeterScore() { Name = "Joe", Score = 2.67 };
//MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
//HttpContent content = new ObjectContent<DrunkMeterScore>(score, jsonFormatter);
//var resp = client.PostAsync("api/DrunkMeterScore", content).Result;
//Uri scoreUri = null;
//HttpResponseMessage response = client.PostAsJsonAsync("api/DrunkMeterScore", score).Result;
//if (response.IsSuccessStatusCode)
//{
// scoreUri = response.Headers.Location;
//}
//else
//{
// Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
//}
To serialize objects you need the ObjectContent class which for the wp8 is only available as an alpha release.
Use the package console to do,
Install-Package Microsoft.AspNet.WebApi.Client -Pre
Should be something like this. I did this from memory so YMMV.
DrunkMeterScore dms = new DrunkMeterScore();
dms.Name = "Bob";
dms.Score = 2.42;
var content = new ObjectContent(dms, new JsonMediaTypeFormatter());
var result = client.PostAsync("/api/DrunkMeterScore", content).Result;