How use AuthorizationFilterAttribute in WebApi with WebClient Library?
27,485
Solution 1
As described on c# corner:
Add BasicAuthenticationAttribute.cs class in your solution.
With following code
public class BasicAuthenticationAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
try
{
if (actionContext.Request.Headers.Authorization == null)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
}
else
{
// Gets header parameters
string authenticationString = actionContext.Request.Headers.Authorization.Parameter;
string originalString = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationString));
// Gets username and password
string usrename = originalString.Split(':')[0];
string password = originalString.Split(':')[1];
AuthsController auth = new AuthsController();
// Validate username and password
if (!auth.ValidateUser(usrename, password))
{
// returns unauthorized error
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
base.OnAuthorization(actionContext);
}
// Handling Authorize: Basic <base64(username:password)> format.
catch(Exception e)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
}
In AuthsController.cs(Entity Framework)
Add
[NonAction]
public bool ValidateUser(string userName, string password)
{
// Check if it is valid credential
var queryable = db.Auths
.Where(x => x.Name == userName)
.Where(x => x.Password == password);
if (queryable != null)
{
return true;
}
else
{
return false;
}
}
In WebApiConfig.cs
Add
config.Filters.Add(new BasicAuthenticationAttribute());
In Your controller that requires Basic Authorization.
Add
[BasicAuthentication]
public class YourController : ApiController{.......}
Solution 2
Basic authentication requires Authorization header to be set:
using (var client = new WebClient())
{
var credential = String.Format("{0}:{1}", userName, password);
var encodedCredential = Convert.ToBase64String(Encoding.UTF8.GetBytes(credential))
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encodedCredential);
// ...
}
Author by
Hamed F
Updated on October 04, 2020Comments
-
Hamed F over 3 years
I use the following code for Authorization (I found it in internet and change it for my use)
when i call my url seems authorization works
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class ClientAuthorizationAttribute : AuthorizationFilterAttribute { private bool _active = true; public ClientAuthorizationAttribute() { } public ClientAuthorizationAttribute(bool active) { _active = active; } public override void OnAuthorization(HttpActionContext actionContext) { if (_active) { var identity = ParseAuthorizationHeader(actionContext); if (identity == null) { Challenge(actionContext); return; } if (!OnAuthorizeUser(identity.Name, identity.Password, actionContext)) { Challenge(actionContext); return; } var principal = new GenericPrincipal(identity, null); Thread.CurrentPrincipal = principal; base.OnAuthorization(actionContext); } } protected virtual bool OnAuthorizeUser(string clientId, string authId, HttpActionContext actionContext) { return false; } protected virtual ClientAuthenticationIdentity ParseAuthorizationHeader(HttpActionContext actionContext) { string authHeader = null; var auth = actionContext.Request.Headers.Authorization; if (auth != null && auth.Scheme == "Basic") authHeader = auth.Parameter; if (string.IsNullOrEmpty(authHeader)) return null; authHeader = Encoding.UTF8.GetString(Convert.FromBase64String(authHeader)); var tokens = authHeader.Split(':'); if (tokens.Length < 2) return null; return new ClientAuthenticationIdentity(tokens[0], tokens[1]); } void Challenge(HttpActionContext actionContext) { var host = actionContext.Request.RequestUri.DnsSafeHost; actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); actionContext.Response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", host)); } } public class ClientAuthenticationIdentity : GenericIdentity { public ClientAuthenticationIdentity(string name, string password) : base(name, "Basic") { Password = password; } public string Password { get; set; } } public class BasicAuthorizationAttribute : ClientAuthorizationAttribute { public BasicAuthorizationAttribute() { } public BasicAuthorizationAttribute(bool active) : base(active) { } protected override bool OnAuthorizeUser(string clientId, string authId, HttpActionContext actionContext) { var businness = new WebServiceAuthBusiness(); return businness.Count(x => x.ClientID == clientId && x.AuthenticateID == authId) > 0; } } }
in Client I use WebClient for Get application data (Does not work)
[BasicAuthorization] public IList<Application> Get() { using (var client = new WebClient()) { client.BaseAddress = _baseAddress; client.Encoding = Encoding.UTF8; client.UseDefaultCredentials = true; ??? client.Credentials = new NetworkCredential(clientId, authId); ??? var str = client.DownloadString("api/application/get"); return JsonConvert.DeserializeObject<List<Application>>(str); } }
How i can send username and password with webClient for AuthorizationFilter ???
-
Michael Freidgeim about 3 years
-
-
The Dag over 9 yearsWhat is the point of encoding a string as base64? It adds zero security but takes 33% more space (any ASCII char requires one byte in UTF-8, but four characters are needed to represent three bytes as base64).
-
akava over 9 yearsbase64 encoding is a requirement of BASIC authentication protocol: ietf.org/rfc/rfc2617.txt To receive authorization, the client sends the userid and password, separated by a single colon (":") character, within a base64 [7] encoded string in the credentials.
-
Jon49 over 8 years@TheDag, If you haven't figured it out yet. Base64 makes it so characters that normally can't be sent over HTTP can be sent by encoding them in the base characters which are allowed.
-
acostela almost 7 yearsAs an external link can provide a valid answer, please add here the main code of the post. If in the future that link is broken this answer will be useless for the rest of the users. Thank you
-
user8024555 almost 7 yearsEdited answer @acostela
-
Ram Kishore K over 5 yearsIsn't it sufficient to add either config.Filters.Add(new BasicAuthenticationAttribute()); in the global config or decorate your controller with BasicAuthentication Attribute. Why both?
-
fay over 5 yearsI have all of this set but yet a request with no authorization header returns with 200, what can i possibly be missing?