Why is Web API Authentication not working? - asp.net-web-api

Here I'm using Web API Authentication to check user credentials against my database. I wrote a condition in my Repo.cs file:
public bool EmailValidation(string UserName, string password)
{
var x = (from n in db.LoginCrediential
where n.UserName == UserName && n.Password == password
select n);
if (x != null)
return true;
else
return false;
}
I have a class file with name MyAuthorizationServerProvider. When I enter credentials against my db it accepts my details, but why is it not moving inside my if condition?
public class MyAuthorizationServerProvider: OAuthAuthorizationServerProvider
{
ICrendentials objcredential = new Crendentials();
LoginCrediential objUser = new LoginCrediential();
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated(); //
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (context.UserName == objUser.UserName && context.Password == objUser.Password)
{
var x = objcredential.EmailValidation(context.UserName, context.Password);
if (x==true)
{
}
}
else
{
context.SetError("invalid_grant", "Provided username and password is incorrect");
return;
}
}
}

Related

Validate if a user exists in Active Directory in Asp.net web api core

How can I check the user is exist or not in Active Directory.
we are passing emailId as userName to the method parameter and it is GET method.
We have written this method, but it is not working properly.
[HttpGet("GetADUsers")]
public List<string> GetADUsers(string userName)
{
var domainUsers = new List<string>();
try
{
string domainName = _domainSettings.Value.DomainName;
string domainUserName = _domainSettings.Value.UserName;
string domainPassword = _domainSettings.Value.Password;
PrincipalContext pc = new PrincipalContext(ContextType.Domain, domainName, domainUserName, domainPassword, ContextOptions.SimpleBind.ToString());
UserPrincipal principalUser = new UserPrincipal(pc);
using (var search = new PrincipalSearcher(principalUser))
{
foreach (var user in search.FindAll().Where(x => x.DisplayName == userName))
{
if (user.DisplayName != null)
{
domainUsers.Add(user.DisplayName);
}
}
}
}
catch (Exception ex)
{
ex.Message.ToString();
}
return domainUsers;
}
After you've created the PrincipalContext, you could just call UserPrincipal.FindByIdentity() - if the user is found, you get back the UserPrincipal - otherwise null.
[HttpGet("GetADUsers")]
public bool ADUserExists(string userName)
{
string domainName = _domainSettings.Value.DomainName;
string domainUserName = _domainSettings.Value.UserName;
string domainPassword = _domainSettings.Value.Password;
PrincipalContext pc = new PrincipalContext(ContextType.Domain, domainName, domainUserName, domainPassword, ContextOptions.SimpleBind.ToString());
UserPrincipal principalUser = UserPrincipal.FindByIdentity(pc, userName);
if (principalUser != null)
{
// gefunden ....
return true;
}
else
{
// nicht gefunden
return false;
}
}

Error during serialization using in Custom MediaType Formatter

i implemented custom media-type formatter with per request logic
public class JsonPermissionBasedFormatter : PartialJsonMediaTypeFormatter
{
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
User user = request.GetOwinContext()?.Request.Get<User>("AuthorizationFilter:CurrentUser");
var formatter = (PartialJsonMediaTypeFormatter)base.GetPerRequestFormatterInstance(type, request, mediaType);
formatter.SerializerSettings = SerializerSettings;
formatter.SerializerSettings.ContractResolver = new PermissionBasedContractResolver(user);
return formatter;
}
}
public class PermissionBasedContractResolver : DefaultContractResolver
{
private readonly User _user;
public PermissionBasedContractResolver(User user)
{
_user = user;
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = true,
OverrideSpecifiedNames = true
};
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
if (member == null)
{
throw new ArgumentNullException(nameof(member));
}
JsonProperty property = base.CreateProperty(member, memberSerialization);
var propertyInfo = member as PropertyInfo;
if (propertyInfo != null)
{
if (!PermissionsHelper.IsPropertyVisibleForUser(propertyInfo, _user))
{
property.ShouldSerialize = DoNotSerialize;
}
}
return property;
}
static bool DoNotSerialize(object o)
{
return false;
}
}
public static bool IsPropertyVisibleForUser(PropertyInfo info, User user)
{
if (info.GetCustomAttribute<IgnoreDataMemberAttribute>() != null)
return false;
if (user == null) return true;
var permissionForExportAttribute =
info.GetCustomAttribute<VisibleForAttribute>();
if (permissionForExportAttribute != null)
{
return
user.HasPermission(permissionForExportAttribute.Permission);
}
return true;
}
PermissionBasedContractResolver add custom logic for serialization which depend on user rights. For example user with admin rights receives additional properties in json, which ordinary user do not.
But if run requests in the following manner:
Parallel.For(1, 10000, _ =>
{
Get(ordinaryUser, isAdmin: false);
Get(adminUser, isAdmin: true);
});
occasionally got for ordinaryUser json properties availiable only for admins. i dont understand how it can happens.
Problem can be reproduce only under some load, if run requests manually via postman - all is ok. Can you tell what it can be or give advices how to investigate such problem.

Forbid users from executing WebApi actions

I have the following WebApi action that deletes an order from the back-end database, only for users that are in the Admin and Order roles. However, if the user is also in the Readonly role the action returns a HTTP 403 Forbidden response.
[Authorize(Roles = "Admin,Order")]
public async Task<IHttpActionResult> Delete(int orderid) {
if(User.IsInRole("Readonly")) { return Forbidden(); }
var order = await _repository.Get(orderid);
if(order != null) {
await _repository.Delete(orderid);
return NoContent();
}
else {
return NotFound();
}
}
What I'd like to know is it possible to prevent actions from being executed if users are in specific roles so that I do not have to put if(User.IsInRole("Readonly")) { return Forbidden(); } at the start of all database update-able action methods, e.g.
[Authorize(Roles = "Admin,Order")]
[NotAuthorized(Roles = "Readonly")]
public async Task<IHttpActionResult> Delete(int orderid) {
var order = await _repository.Get(orderid);
if(order != null) {
await _repository.Delete(orderid);
return NoContent();
}
else {
return NotFound();
}
}
The NotAuthorized action filter will return a HTTP 403 Forbidden response if the user is in the Readonly role.
Is this possible?
This is the code to implement a reverse of the [Authorize()] attribute and forbid users from executing MVC WebApi actions if they are a member of one or more roles.
using System;
using System.Net;
using System.Net.Http;
using System.Security.Principal;
using System.Web.Http;
using System.Web.Http.Controllers;
namespace MyAPI {
[AttributeUsage(AttributeTargets.Method,AllowMultiple = false)]
public class NotAuthorizedAttribute : AuthorizeAttribute {
public override void OnAuthorization(HttpActionContext actionContext) {
IPrincipal user = actionContext.RequestContext.Principal;
if(!user.Identity.IsAuthenticated) {
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
else {
bool userInRole = false;
foreach(var role in Roles.Split(',')) {
if(user.IsInRole(role)) {
userInRole = true;
break;
}
}
if(userInRole) {
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}
}
}
}
To use this filter attribute simply decorate any actions that you don't want users to execute if they're a member of a restricted role, e.g. if the user is part of a read-only role they not permitted to update the database:
[Authorize(Roles = "Admin,Order")]
[NotAuthorized(Roles = "Readonly")]
public async Task<IHttpActionResult> Delete(int orderid) {
var order = await _repository.Get(orderid);
if(order != null) {
await _repository.Delete(orderid);
return NoContent();
}
else {
return NotFound();
}
}

MVC3 AuthorizeAttribute

This allows "frankl" to access but blocks the admins. What have I done wrong?
[Authorize(Order=1,Roles = "Admin",Users="frankl")]
public class AuthorizeBaseController_Admins_frank : Controller
{
}
It is probably simple but I don't see any examples that combine the two and the "Allowmultiple" property generates an error when I try to add it.
Thanks,
Chris
Roles and Users should be used exclusively. If you want to combine them you could write a custom authorize attribute:
public class MyAuthoirizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
var user = httpContext.User;
if (!user.Identity.IsAuthenticated)
{
return false;
}
var usersSplit = SplitString(Users);
var rolesSplit = SplitString(Roles);
return
(usersSplit.Length > 0 && usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) ||
(rolesSplit.Length > 0 && rolesSplit.Any(user.IsInRole));
}
private string[] SplitString(string original)
{
if (string.IsNullOrEmpty(original))
{
return new string[0];
}
return (from piece in original.Split(',')
let trimmed = piece.Trim()
where !string.IsNullOrEmpty(trimmed)
select trimmed).ToArray();
}
}
and then:
[MyAuthorize(Order = 1, Roles = "Admin", Users="frankl")]
public class AuthorizeBaseController_Admins_frank : Controller
{
...
}
Unfortunately the AuthorizeAttribrute will let you either specify valid users, or valid roles - not both. Here is the relevant bit of code from the MVC 3 source.
protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
if (httpContext == null) {
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated) {
return false;
}
if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) {
return false;
}
if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) {
return false;
}
return true;
}
You will either need to make 'frankl' an Admin, or create a custom authorization attribrute

asp.net mvc3, cookie

I have a website where a user can authenticate with their facebook account or twitter:
to know the user I used the cookie:
Global.asax:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
var id = new MyIdentity(authTicket);
var userData = authTicket.UserData.Split(',');
id.SocialProviderName = userData[0].Replace("providerslist=", "").Split('|')[0];
var newUser = new MyPrincipal(id);
Context.User = newUser;
}
}
the user can link two accounts (facebook and twitter). connect with
twitter and then click on "account linking" and will be redirect to authenticate with her facebook account
the problem is that when redirecting to the second account the cookie becomes null and
if (this.HttpContext.Request.IsAuthenticated)
{...}
return false
(if I connect with a single account the cookie is valid no problem)
My Controller:
....
FormsAuthentication.SetAuthCookie(socialProfile.UserId, true);
ResetFormsCookie(providerName, socialProfile.UserId);
....
UserId generate by GUID
public void ResetFormsCookie(string providerName, string userId)
{
var authCookie = HttpContext.Current.ApplicationInstance.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null)
{
authCookie = FormsAuthentication.GetAuthCookie(userId, true);
}
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
var userData = authTicket.UserData;
var providerslist = (from c in userData.Split(',') where c.Contains("providerslist=") select c).FirstOrDefault();
if (string.IsNullOrEmpty(providerslist))
{
userData += string.IsNullOrEmpty(userData) ? "providerslist=" + providerName : ",providerslist=" + providerName;
}
else
{
if (!providerslist.Contains(providerName))
{
userData = userData.Replace(providerslist, providerslist + "|" + providerName);
}
}
var newTicket = new FormsAuthenticationTicket(authTicket.Version, authTicket.Name, authTicket.IssueDate
, DateTime.Now.AddDays(90) // authTicket.Expiration ToDo: This need to set in the config
, authTicket.IsPersistent, userData);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
HttpContext.Current.Response.Cookies.Add(authCookie);
}
I apologize for my English
Thanks,

Resources