HttpResponseMessage asp.net : How to integrate basic authentication - asp.net

How do I implement a basic authentication filter into a working web api client written in asp.net HttpResponseMessage.
How do I check the authentication (user:pass or 64Base Key) and if failed pass unauthorised message.
This is my current code and it work:
public HttpResponseMessage WebAPiPost([FromBody]byte[] incomingData)
{
string rawData = getRawPostData().Result;
var responseMessage= (HttpResponseMessage)null;
responseMessage = new HttpResponseMessage()
{Content = new StringContent(SQLFunctions.SQLStoredProcedureJson("StoredProcedureName", rawData, true), System.Text.Encoding.UTF8, "application/json")};
return responseMessage;
}

Related

Sending and getting http headers

I am working on an asp.net Web API and I have an web application that consumes this api.
Right now it is working perfectly since I don't have the [Authorize] part on my api controller.
So, if I want to secure this api, my web application will not be able anymore to fetch data from the API because it is not authorized.
So how can I send the token generated from my API to my web app and to allow it to fetch the needed data?
-I am using postman for testing my app;
-my api return jwt token;
-I am not really familiar with http headers.
My consuming web application controller :
public ActionResult Index()
{
IEnumerable<OperatorClass> OperatorObject = null;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://localhost:44304/api/");
var ApiOpController = client.GetAsync("data");
client.DefaultRequestHeaders.Add("Authorization", "Bearer"+"");
ApiOpController.Wait();
var resultDisplay = ApiOpController.Result;
if (resultDisplay.IsSuccessStatusCode)
{
var readTable = resultDisplay.Content.ReadAsAsync<IList<OperatorClass>>();
readTable.Wait();
OperatorObject = readTable.Result;
}
else
{
OperatorObject = Enumerable.Empty<OperatorClass>();
ModelState.AddModelError(String.Empty, "No records found");
}
return View(OperatorObject);
}
My web API controller
[Authorize]
[HttpGet]
public IHttpActionResult GetOperators()
{
SchoolEntity myEntity = new SchoolEntity ();
IList<OperatorClass> OperatorObject = myEntity.Operator.Include("Operator").Select(x => new OperatorClass()
{
name = x.name,
lastname = x.lastname,
mobile = x.mobile,
username = x.username,
password = x.password
}).ToList<OperatorClass>();
return Ok(OperatorObject);
}
string token = <Your token>
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
this should work for you.
To be able to use your MVC controller, you need to store the token when it returns.
One way to do it is to store it using Session.
Assuming you are using sign in to get the token, anytime you sign in successfully you can store the token using the session. See below.
//For brevity after successful login
string myToken = <token returned from api>
HttpContext.Session.SetString("token", myToken);
//other codes
then you can use this in all of your controllers.
public async Task<ActionResult> Index()
{
IEnumerable<OperatorClass> OperatorObject = null;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://localhost:44304/api/");
//note here
var token = HttpContext.Session.GetString("token");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
//ApiOpController.Wait();
var resultDisplay = await client.GetAsync("data");
if (resultDisplay.IsSuccessStatusCode)
{
var readTable = await resultDisplay.Content.ReadAsAsync<IList<OperatorClass>>();
//readTable.Wait();
OperatorObject = readTable;
}
else
{
OperatorObject = Enumerable.Empty<OperatorClass>();
ModelState.AddModelError(String.Empty, "No records found");
}
return View(OperatorObject);
}

Implementing ROPC based authentication in asp .net core

I'm trying to implement ROPC flow in asp.net api . Can you please guide me on how to achieve this properly in ASP.net core using built in authentication library. If it is not possible what are the alternatives
I'm able to get the access token using http call to azure AD token endpoint. But i'm not able to validate the token using built in authentication library
can we implement this without the HTTP call , but using built in library.
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
Im using the below code snippet to get the access token
private async Task<string> GetTokenAsync(string username, string password)
{
string grantType = "password";
string tenantId = Configuration["AzureAdNative:TenantId"];
string clientId = Configuration["AzureAdNative:ClientId"];
string resource = Configuration["AzureAdNative:Resource"];
string endpoint = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var dict = new Dictionary<string, string>();
dict.Add("grant_type", grantType);
dict.Add("client_id", clientId);
dict.Add("username", username);
dict.Add("password", password);
dict.Add("resource", resource);
var req = new HttpRequestMessage(HttpMethod.Post, endpoint) { Content = new FormUrlEncodedContent(dict) };
var res = await client.SendAsync(req);
string result = res.Content.ReadAsStringAsync().Result;
var jwt = JObject.Parse(result);
return result;
// return jwt.GetValue("access_token").ToString();
}
getting unauthorised 401 error while validating with above code. access token is being sent in the authorization header (eg: Authorization : Bearer e4dgkddskdsdk).

twitter search Api RestSharp not working and giving error unauthorize

I am trying to develop twitter client. i am using RestSharp for api. its work fine with authentication and gettimeline but its give error when i try to search twitter with # hashtag . its gives error like bad request and unauthorized.
Working code
public string GetTimeLine(string key,string secret,string userToken,string userSecret)
{
var request = new RestRequest("/1.1/statuses/user_timeline.json", Method.GET);
Client.Authenticator = OAuth1Authenticator.ForProtectedResource(key, secret, userToken, userSecret);
var response = Client.Execute(request);
return response.Content;
}
Respond with unauthorized error:
public string GetHashtag(string key, string secret, string userToken, string userSecret)
{
var request = new RestRequest("/1.1/search/tweets.json?q=%23freebandnames", Method.GET);
Client.Authenticator = OAuth1Authenticator.ForProtectedResource(key, secret, userToken, userSecret);
var response = Client.Execute(request);
return response.Content;
}
Try this:
var request = new RestRequest("/1.1/search/tweets.json?q={query}", Method.GET);
request.AddUrlSegment("query", "#freebandnames");

AADSTS70001: Application '574c1791-d632-4180-91e4-38094a8a3a77' is not supported for this API version

I am trying to use office365 api in my single page .net application not an mvc. I got the source code for mvc .net project C# in the website itself.
public async Task<ActionResult> SignIn()
{
string authority = "https://login.microsoftonline.com/common";
string clientId = System.Configuration.ConfigurationManager.AppSettings["ida:ClientID"];
AuthenticationContext authContext = new AuthenticationContext(authority);
// The url in our app that Azure should redirect to after successful signin
Uri redirectUri = new Uri(Url.Action("Authorize", "Home", null, Request.Url.Scheme));
// Generate the parameterized URL for Azure signin
Uri authUri = await authContext.GetAuthorizationRequestUrlAsync(scopes, null, clientId, redirectUri, UserIdentifier.AnyUser, null);
// Redirect the browser to the Azure signin page
return Redirect(authUri.ToString());
}
// Note the function signature is changed!
public async Task<ActionResult> Authorize()
{
// Get the 'code' parameter from the Azure redirect
string authCode = Request.Params["code"];
string authority = "https://login.microsoftonline.com/common";
string clientId = System.Configuration.ConfigurationManager.AppSettings["ida:ClientID"]; ;
string clientSecret = System.Configuration.ConfigurationManager.AppSettings["ida:ClientSecret"]; ;
AuthenticationContext authContext = new AuthenticationContext(authority);
// The same url we specified in the auth code request
Uri redirectUri = new Uri(Url.Action("Authorize", "Home", null, Request.Url.Scheme));
// Use client ID and secret to establish app identity
ClientCredential credential = new ClientCredential(clientId, clientSecret);
try
{
// Get the token
var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
authCode, redirectUri, credential, scopes);
// Save the token in the session
Session["access_token"] = authResult.Token;
// Try to get user info
Session["user_email"] = GetUserEmail(authContext, clientId);
return Redirect(Url.Action("Inbox", "Home", null, Request.Url.Scheme));
}
catch (AdalException ex)
{
return Content(string.Format("ERROR retrieving token: {0}", ex.Message));
}
}
I converted the code to vb.net and i am receiving bad request error stating that my application is not supported for this api version when executed. The code is in WebForm1.aspx and the redirect uri link is to webform2.aspx
Private Sub SignIn()
Dim authority As String = "https://login.microsoftonline.com/common"
Dim clientId As String = System.Configuration.ConfigurationManager.AppSettings("ida:ClientID")
Dim authContext As New AuthenticationContext(authority)
Dim redirectUri As New Uri("http://localhost:26683/WebForm2.aspx")
Dim authUri As Uri = authContext.GetAuthorizationRequestURL("https://outlook.office.com/mail.read", clientId, redirectUri, UserIdentifier.AnyUser, Nothing)
Response.Redirect(authUri.ToString())
End Sub
How ever i have registered the application.In fact when i used the same client id and client secret for the mvc application it is executed without any error but when i use it in my single web application it throws this error.
Please help.What am i doing wrong

Securing ASP.NET MVC controller action which returns JSON

I have an MVC3 application, and my controller actions are secured using the [Authorize] attribute. So far, so good, forms auth works great. Now I want to add a JSON API to my application so some actions are accessible to non-browser clients.
I'm having trouble figuring out the 'right' design.
1) Each user has secret API key.
2) User ID 5 calls http://myapp.com/foocontroller/baraction/5?param1=value1&param2=value2&secure_hash=someValue. Here, secure_hash is simply the SHA1 hash of param1 and param2's values appended with the secret API key for the user
2) /foocontroller/baraction will be decorated with [CustomAuthorize]. This will be an implementation of AuthorizeAttribute which will check if the request is coming in as JSON. If it is, it will check the hash and see if it matches. Otherwise, if the request is HTML, then I call into existing authorization.
I am not at all sure if this will work. Is it normal to pass a secure hash in the query string or should I be passing it in as an HTTP header? Is it better to use HTTP basic auth instead of a hash made using the secret API key?
Tips from anyone who has made a web API using ASP.NET MVC would be welcome!
I pass the secret API key along with username and password in the request body. Once authorized, a token is generated and the client has to pass that in the Authorization header. This gets checked in the base controller on each request.
Client calls myapp.com/authorize which return auth token.
Client stores auth token locally.
Client calls myapp.com/anycontroller, with authtoken in Authorization header.
AuthorizeController inherits from controller.
Anycontroller inherits from a custom base controller which performs the authorization code.
My example requires the following route which directs POST requests to an ActionResult named post in any controller. I am typing this in by hand to simplify it as much as possible to give you the general idea. Don't expect to cut and paste and have it work :)
routes.MapRoute(
"post-object",
"{controller}",
new { controller = "Home", action = "post" {,
new { httpMethod = new HttpMethodConstraint("POST")}
);
Your auth controller can use this
public class AuthorizationController : Controller
{
public ActionResult Post()
{
string authBody;
var request = ControllerContext.HttpContext.Request;
var response = ControllerContext.HttpContext.Response;
using(var reader = new StreamReader(request.InputStream))
authBody = reader.ReadToEnd();
// authorize based on credentials passed in request body
var authToken = {result of your auth method}
response.Write(authToken);
}
}
Your other controllers inherit from a base controller
public class BaseController : Controller
{
protected override void Execute(RequestContext requestContext)
{
var request = requestContext.HttpContext.Request;
var response = requestContext.HttpContext.Response;
var authToken = Request.Headers["Authorization"];
// use token to authorize in your own method
var authorized = AmIAuthorized();
if(authorized = false) {
response.StatusCode = 401;
response.Write("Invalid token");
return;
}
response.StatusCode = 200; // OK
base.Execute(requestContext); // allow inheriting controller to continue
}
}
Sample code to call the api
public static void ExecutePostRequest(string contentType)
{
request = (HttpWebRequest)WebRequest.Create(Uri + Querystring);
request.Method = "POST";
request.ContentType = contentType; // application/json usually
request.Headers["Authorization"] = token;
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
writer.Write(postRequestData);
// GetResponse reaises an exception on http status code 400
// We can pull response out of the exception and continue on our way
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
response = (HttpWebResponse)ex.Response;
}
finally
{
using (StreamReader reader =
new StreamReader(response.GetResponseStream()))
responseText = reader.ReadToEnd();
httpcontext = HttpContext.Current;
}
}

Resources