[英]Enabling Windows and Basic Authentication for ASP.NET Web API 2 Application
I have an ASP.NET Web API 2 application that uses Windows Authentication for all the controllers. 我有一个ASP.NET Web API 2应用程序,它为所有控制器使用Windows身份验证。 I have a need now for some controllers to use Basic Authentication.
我现在需要某些控制器使用基本身份验证。
I know it is not possible to enable both Anonymous and Windows Authentications, but is it possible to enable Windows Authentication for some controllers and Basic Authentication for some others? 我知道无法同时启用匿名和Windows身份验证,但是是否可以为某些控制器启用Windows身份验证,为其他控制器启用基本身份验证?
UPDATE: Implemented a filter as shown on the article EdSF shared 更新:实现了一个过滤器,如EdSF 共享文章所示
Here is what I have so far: 这是我到目前为止:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class BasicAuthenticationFilter : AuthorizationFilterAttribute
{
private bool _active = true;
private const string ValidUsername = @"Test";
private const string ValidPassword = @"T3st";
public BasicAuthenticationFilter()
{
}
public BasicAuthenticationFilter(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;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
base.OnAuthorization(actionContext);
}
}
protected virtual bool OnAuthorizeUser(string username, string password, HttpActionContext actionContext)
{
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) ||
!username.Equals(ValidUsername) || !password.Equals(ValidPassword))
{
return false;
}
return true;
}
protected virtual BasicAuthenticationIdentity 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.Default.GetString(Convert.FromBase64String(authHeader));
var tokens = authHeader.Split(':');
if (tokens.Length < 2) return null;
return new BasicAuthenticationIdentity(tokens[0], tokens[1]);
}
private 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));
}
}
BasicAuthenticationIdentity Class: BasicAuthenticationIdentity类:
public class BasicAuthenticationIdentity : GenericIdentity
{
public BasicAuthenticationIdentity(string name, string password)
: base(name, "Basic")
{
Password = password;
}
public string Password { get; set; }
}
Also, decorated my controller with the Basic Authentication Filter: 另外,使用基本身份验证过滤器装饰我的控制器:
[BasicAuthenticationFilter]
[RoutePrefix("api/BasicAuth")]
public class BasicAuthController : ApiController
{
//[BasicAuthenticationFilter]
[HttpGet]
public IHttpActionResult TestBasicAuth()
{
return Ok("success");
}
}
When I make a call to api/BasicAuth from Fiddler I got back 401, but it only returns the following challenges: 当我从Fiddler打电话给api / BasicAuth时,我回到了401,但它只返回了以下挑战:
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
At this point Fiddler tries it again but this time instead of passing Basic Authorization Scheme, it passes Negotiate. 此时,Fiddler再次尝试,但这次不是通过基本授权方案,而是通过Negotiate。 This one fails also.
这个也失败了。
Then, when Fiddler finally tries the third time, my filter actually gets the request, but since authorization scheme is Negotiate instead of Basic, my filter returns Unauthorized also. 然后,当Fiddler最后第三次尝试时,我的过滤器实际上得到了请求,但由于授权方案是Negotiate而不是Basic,我的过滤器也返回Unauthorized。
Is there a way to force the controller to just use the BasicAuthenticationFilter? 有没有办法强制控制器只使用BasicAuthenticationFilter?
Thanks in advance 提前致谢
You can - because BASIC AUTH
credentials are sent in HTTP Headers
(base64 encoded only). 您可以 - 因为
BASIC AUTH
凭据是在HTTP Headers
中发送的(仅限base64编码)。 You don't have to "enable" anything at the application level and handle HTTP requests to your API endpoints "manually" (by inspecting headers). 你不必为“Enable”在应用层面任何事情,处理HTTP请求到您的API端点“手动”(通过检查头)。
eg Basic Auth Header: Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
例如Basic Auth Header:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
See this example that creates an AuthorizationFilter
that can be applied to Controller
or Action
, or even globally if needed... 请参阅此示例 , 该示例创建可应用于
Controller
或Action
的AuthorizationFilter
,如果需要,甚至可以全局应用...
Hth. 心连心。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.