ASP.NET WEB API Forms Authentication Error - c#

I am trying to create a web api with forms based authentication. I want to login from a client and retrieve data from there. When I log in, user gets authenticated and can retrieve data by giving http request direct into adressbar like localhost:1393/api/Game. But when i try to get it from client I am getting a 401 (Unauthorized error). I have enabled CORS in server side. This is the controller to handle data
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Security;
using Cheeky_backend.Models;
using System.Web.Http.WebHost;
namespace Cheeky_backend.Controllers
{
public class Demo
{
public List<Teams> team { get; set; }
public List<Hole> hole { get; set; }
}
[Authorize]
public class GameController : ApiController
{
private Cheeky_backendContext db = new Cheeky_backendContext();
// GET api/Game
public IEnumerable<Hole> GetHoles()
{
return db.Holes.AsEnumerable();
}
}
}
This is the authenticating controler
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Security;
using System.Web.Http;
using Cheeky_backend.Models;
namespace Cheeky_backend.Controllers
{
public class UserController : ApiController
{
private Cheeky_backendContext db = new Cheeky_backendContext();
// GET api/Default1
// GET api/Default1/5
// PUT api/Default1/5
// POST api/Default1
public HttpResponseMessage CreateUser(User user)
{
if (ModelState.IsValid)
{
db.Users.Add(user);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, user);
// response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = user.ID }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
// DELETE api/Default1/5
public HttpResponseMessage Login(User user)
{
var userfound = from user2 in db.Users
where user.username == user2.username && user.password == user2.password
select user2;
if( userfound.Any())
{
FormsAuthentication.SetAuthCookie(user.username, true);
return Request.CreateResponse(HttpStatusCode.OK,user);
}
return Request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
}

Source
In your Authentication Handler
Don't set the Principal on the Thread.CurrentPrinicipal any more.
Use the Principal on the HttpRequestContext.
Take a look at here

Related

SignalR only works the first time it is called

I have a ASP.NET Core MVC 5 website. I am using SignalR to send "Notifications" from the model layer to the client / view.
If I open my index page, It uses SignalR to send a list of available cameras as they are discovered. I then again use SignalR to send images that the camera is taking on a different model. However, only the first one works.
If I navigate to https://localhost:44303/camera/live/?IP=192.168.50.212 It starts sending images, but will not discover other cameras. If I navigate to the discovery first, the discovery works just fine.
In both the models, the line Hub.Clients.All.SendAsync("method", data); is executing. In both models, the Hub is defined as
public Microsoft.AspNetCore.SignalR.IHubContext<MasterHub> Hub { get; internal set; }`
and each model has a separate controller, that sets the hub context like so:
private readonly IHubContext<MasterHub> _hubContext;
public CameraController(IHubContext<MasterHub> hubContext)
{
_hubContext = hubContext;
}
However, only the first one I navegate to works.
Do I have to close the SignalR connection after sending a message to use it again? If so, How would I do this?
both controllers look like:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Thermal_Screening.Hubs;
using Thermal_Screening.Models;
namespace Thermal_Screening.Controllers
{
public class CameraController : Controller
{
public string CameraName;
private readonly IHubContext<MasterHub> _hubContext;
public CameraController(IHubContext<MasterHub> hubContext)
{
_hubContext = hubContext;
}
public IActionResult Live(string IP)
{
CameraName = getCameraNameFromIP(IP); // doin it this way causes a 2s delay, should get ip in model
return View(new CameraViewModel(IP) { Hub = _hubContext, IP = IP, CameraName = CameraName });
}
public IActionResult Settings(string IP)
{
CameraName = getCameraNameFromIP(IP);
return View(new CameraViewModel(IP) { Hub = _hubContext, IP = IP, CameraName = CameraName });
}
public IActionResult Log(string IP)
{
CameraName = getCameraNameFromIP(IP);
return View(new CameraViewModel(IP) { Hub = _hubContext, IP = IP, CameraName = CameraName });
}
private string getCameraNameFromIP(string IP)
{
WebClient x = new WebClient();
string source = x.DownloadString("http://" + IP);
return Regex.Match(source, #"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>", RegexOptions.IgnoreCase).Groups["Title"].Value;
}
}
}
both viewmodels look like:
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Extensions;
using Flir.Atlas.Live.Discovery;
using Flir.Atlas.Live.Device;
using Flir.Atlas.Live;
using System.IO;
using Flir.Atlas.Image;
using System.Drawing;
using Microsoft.AspNetCore.SignalR;
using Thermal_Screening.Hubs;
namespace Thermal_Screening.Models
{
public class CameraViewModel
{
public Microsoft.AspNetCore.SignalR.IHubContext<MasterHub> Hub { get; internal set; }
//removed for berevity
Hub.Clients.All.SendAsync("method", "data");

Xamarin forms with firebase user registration error

i am developing an app using xamarin forms and firebase authentication
with xamarin.firebase.auth and xamarin.firebase.core
when i want to create a new user the code works fine but it gives me the exception
Java.Lang.IllegalStateException: 'Task is not yet complete'
when i trace the code line by line every thing works just fine and i get no errors but when running the app after creating user it gives me the exception.
this is my code:
inerface in pcl:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace XamarinFirebaseAuth
{
public interface IAuth
{
Task<string> LoginWithEmailPassword(string email, string password);
bool SignUpWithEmailPassword(string email, string password);
}
}
android implementation:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Foundation;
using UIKit;
using XamarinFirebaseAuth;
using XamarinFirebaseAuth.iOS;
using Firebase.Auth;
using System.Threading.Tasks;
using Xamarin.Forms;
[assembly: Dependency(typeof(AuthIOS))]
namespace XamarinFirebaseAuth.iOS
{
public class AuthIOS : IAuth
{
public async Task<string> LoginWithEmailPassword(string email, string password)
{
try
{
var user = await Auth.DefaultInstance.SignInWithPasswordAsync(email, password);
var token = user.User.GetIdTokenAsync();
return token.ToString();
}
catch(Exception e)
{
return "";
}
}
public bool SignUpWithEmailPassword(string email, string password)
{
try
{
var signUpTask = Auth.DefaultInstance.CreateUserAsync(email, password);
return true;
}
catch (Exception e)
{
throw;
//return false;
}
}
}
}
and this is my sign up page :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace XamarinFirebaseAuth
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SignUpPage : ContentPage
{
IAuth auth;
public SignUpPage()
{
InitializeComponent();
auth = DependencyService.Get<IAuth>();
}
private async void btnRegister_Clicked(object sender, EventArgs e)
{
try
{
bool created = auth.SignUpWithEmailPassword(EmailInput.Text, PasswordInput.Text);
if (created)
{
await DisplayAlert("Success", "Your account created successfully", "OK");
await Navigation.PopAsync();
}
else
{
await DisplayAlert("Error", "Something went wrong. Try again later!", "OK");
}
}
catch
{
throw;
}
}
}
}
I think you should await the CreateUserAsync method to know whether the account is created successfully or not:
AuthDataResult signUpTask = await Auth.DefaultInstance.CreateUserAsync(email, password);
Then you can get the user info:
await signUpTask.User.GetIdTokenAsync();

c# mvc viewmodel database first unable to create view

I am an experienced programmer but relatively new to c# mvc. I am attempting to create my first viewmodel to combine two models into one so a view can access members from both. I have followed instructions on combining distinct models into one view model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ViApplication.Models;
using System.ComponentModel.DataAnnotations;
namespace ViApplication.ViewModel
{
public class TemplateMTMQuestionViewModel
{
public TemplateVISpdat ThisTemplate { get; set; }
public MtmTemplateViSpdatQuestion ThisMTMQuestion { get; set; }
}
}
I have created a controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ViApplication.ViewModel;
using ViApplication.Models;
using System.Net;
namespace ViApplication.Controllers
{
public class TemplatesMTMQuestions : Controller
{
private VulnerabilityIndexDatabaseEntities db = new VulnerabilityIndexDatabaseEntities();
public ActionResult AddQuestionToTemplate(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
TemplateVISpdat templateVISpdat = GetTemplateByID(id);
if (templateVISpdat == null)
{
return HttpNotFound();
}
TemplateMTMQuestionViewModel TMTMQVM = new TemplateMTMQuestionViewModel();
TMTMQVM.ThisTemplate = GetTemplateByID(id);
TMTMQVM.ThisMTMQuestion = GetBlankMtmTemplateViSpdatQuestion();
return View(TMTMQVM);
}
public TemplateVISpdat GetTemplateByID(long? id)
{
TemplateVISpdat templateVISpdat = db.TemplateVISpdats.Find(id);
return templateVISpdat;
}
public MtmTemplateViSpdatQuestion GetBlankMtmTemplateViSpdatQuestion()
{
MtmTemplateViSpdatQuestion TMTMQVM = new MtmTemplateViSpdatQuestion();
return TMTMQVM;
}
}
}
This compiles fine. But when I try to create a view from AddQuestionToTemplate and select Empty and my ViewModel I get:
Unable to retrieve metadata for
ViApplication.ViewMdoel.TemplateMTMQuestionViewModel. One or more
validation errors were detected during model generation.
TemplateMTMQuestionViewModel::EntityType TemplateMTMQuestionViewModel
has no key defined
The only difference between this project and other projects is that I am using database first.
Any help would be greatly appreciated.

How To Get a User's Role with a DiscordSocketClient

I have been locking for a long time on how to get a user's role so I can set permissions for commands. This is my code. I am using Discord.NET in the newer version.
using Discord.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AmberScript2.Modules
{
public class Kick : ModuleBase<SocketCommandContext>
{
[Command("kick")]
public async Task KickUser(string userName)
{
if (Context.Guild.GetRole(Context.Message.Author.Id).Name == "Administrator")
{
await Context.Channel.SendMessageAsync("Success!");
}
else
{
await Context.Channel.SendMessageAsync("Inadequate permisions.");
}
}
}
}
The error i am getting is object reference not set to an instance of an object. I have been trying to find the source of it and i can't. Thanks.
(And yes i have yet to get rid of excess usings. This code isn't done yet.)
If you want to try to get a role of the user, try using SocketGuildUser instead of a string. (Use var role = (user as IGuildUser).Guild.Roles.FirstOrDefault(x => x.Name == "Role");)
using Discord.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AmberScript2.Modules
{
public class Kick : ModuleBase<SocketCommandContext>
{
[Command("kick")]
public async Task KickUser(SocketGuildUser userName)
{
var user = Context.User as SocketGuildUser;
var role = (user as IGuildUser).Guild.Roles.FirstOrDefault(x => x.Name == "Role");
if (!userName.Roles.Contains(role))
{
// Do Stuff
if (user.GuildPermissions.KickMembers)
{
await userName.KickAsync();
}
}
}
}
}
That is most of my code for kicking.
With the line RequireUserPermission(GuildPermission.KickMembers) you check whether or not the user has the permission to kick members.
Within GuildPermission there are many different permissions.
Like GuildPermission.ManageRoles etc.
using Discord.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AmberScript2.Modules
{
public class Kick : ModuleBase<SocketCommandContext>
{
[Command("kick"), RequireUserPermission(GuildPermission.KickMembers)]
public async Task KickUser(SocketGuildUser userName)
{
var user = Context.User as SocketGuildUser;
var role = (user as IGuildUser).Guild.Roles.FirstOrDefault(x => x.Name == "Role");
if (!userName.Roles.Contains(role))
{
// Do Stuff
if (user.GuildPermissions.KickMembers)
{
await userName.KickAsync();
}
}
}
}
I have the same problem...
To my knowledge Linq needs to be used with IGuildUser or SocketGuildUser.
I have not yet been able to create functioning code to check if the person performing the command does have a role named "Admin"or some other name
Edit: This might be helpful
https://discord.foxbot.me/docs/api/Discord.WebSocket.SocketGuildUser.html

Stripe Webhook Controller Not Found

I have the following:
public class StripeController : Controller
{
private readonly UserService _userService;
public StripeController(UserService userService)
{
_userService = userService;
}
[HttpPost]
public ActionResult StripeWebook()
{
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
[HttpPost]
[Route("api/stripewebhook")]
public async Task<ActionResult> Index(CancellationToken ct)
{
var json = new StreamReader(Request.InputStream).ReadToEnd();
var stripeEvent = StripeEventUtility.ParseEvent(json);
switch (stripeEvent.Type)
{
case StripeEvents.ChargeRefunded: // all of the types available are listed in StripeEvents
var stripeCharge = Stripe.Mapper<StripeCharge>.MapFromJson(stripeEvent.Data.Object.ToString());
break;
}
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
}
And requests from stripe generate an error:
The controller for path '/api/stripewebhook' was not found or does not implement IController
Any idea why this is happening when I test from the stripe portal?
Using WebApi 2 it works with no problem.
Here is the smallest WebApi controller to begin with:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
namespace WebApplication1.Controllers
{
public class StripeController : ApiController
{
[HttpPost]
[Route("api/stripewebhook")]
public IHttpActionResult Index()
{
var json = new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd();
return Ok();
}
}
}
if you execute this from VS you can access it from http://localhost:(port)/api/stripewebhook
Now you only need to extend this to include the stripe code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
namespace WebApplication1.Controllers
{
public class StripeController : ApiController
{
[HttpPost]
[Route("api/stripewebhook")]
public IHttpActionResult Index()
{
var json = new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd();
var stripeEvent = StripeEventUtility.ParseEvent(json);
switch (stripeEvent.Type)
{
case StripeEvents.ChargeRefunded: // all of the types available are listed in StripeEvents
var stripeCharge = Stripe.Mapper<StripeCharge>.MapFromJson(stripeEvent.Data.Object.ToString());
break;
}
return Ok();
}
}
}

Categories