Azure active directory 在WebApi中验证Azure广告令牌
我们正在构建一个webAPI服务,客户将使用AAD令牌访问该服务。因此,该服务需要对令牌进行身份验证,以确保其有效。 这是一个多租户场景 我查阅了AAD文档,没有什么问题。如果有人能帮助回答,我们将不胜感激 1) 根据我的理解,该服务将从AAD下载公共签名令牌并缓存它们。这些用于验证令牌,对吗 2) 刷新缓存签名令牌的建议间隔是多久?此外,如果AAD在刷新周期内旋转键,建议按需刷新 3) 根据我在中找到的AAD示例代码 由于计算机不信任AAD根证书,因此启用证书验证不起作用,这里的建议是什么?我们是否需要在受信任的存储中手动安装证书Azure active directory 在WebApi中验证Azure广告令牌,azure-active-directory,Azure Active Directory,我们正在构建一个webAPI服务,客户将使用AAD令牌访问该服务。因此,该服务需要对令牌进行身份验证,以确保其有效。 这是一个多租户场景 我查阅了AAD文档,没有什么问题。如果有人能帮助回答,我们将不胜感激 1) 根据我的理解,该服务将从AAD下载公共签名令牌并缓存它们。这些用于验证令牌,对吗 2) 刷新缓存签名令牌的建议间隔是多久?此外,如果AAD在刷新周期内旋转键,建议按需刷新 3) 根据我在中找到的AAD示例代码 由于计算机不信任AAD根证书,因此启用证书验证不起作用,这里的建议是什么?我
4) 在AAD示例代码@中,它以同步方式下载这些签名令牌,是否有代码的异步版本?AFAIK,请求将获得Azure AD发行的令牌,这些令牌通过私钥进行签名。web API将使用Azure AD的公钥自动验证令牌(OWIN组件) 要使用Visual Studio 2013之后的版本开发web API,无需手动验证令牌。下面是一段保护web API的代码:
public void ConfigureAuth(IAppBuilder app)
{
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() { ValidateIssuer = false }
});
}
是保护多租户web API的完整代码示例的链接
更新(支持不同控制器的密码和令牌身份验证)
谢谢你,菲。不幸的是,我认为我必须使用手动验证。例如,我想支持多个发卡机构租户。另外,我只验证某些控制器操作的令牌,对于其他操作,我有不同的身份验证模型。根据我的理解,如果你想用多个认证中间件来保护WebAPI,它应该是正确的。但是,无论用户使用哪种方式通过身份验证,web API都会返回结果。如果您希望使用相应的身份验证分离不同的API(更像“角色”管理,来自不同IDP的用户具有不同的角色),我们可以开发定制属性来验证特定的声明,以区分请求和请求。我还更新了帖子,添加了一个代码示例来演示这个场景。或者更简单的方法是为不同的身份验证开发两个web API控制器。感谢Fei提供的代码示例。初始化WindowsAzureActiveDirectoryBeareAuthenticationOptions时,传递颁发令牌的租户id。在我的情况下,客户可以属于不同的租户,因此发行人将是不同的否?我如何支持这一点?
public void ConfigureAuth(IAppBuilder app)
{
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() { ValidateIssuer = false }
});
}
public void ConfigureAuth(IAppBuilder app)
{
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() { ValidateIssuer = false }
});
app.UsePasswordAuthentication();
}
public class PasswordAuthorization : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
var principal = actionContext.RequestContext.Principal as ClaimsPrincipal;
if (principal.FindFirst("authenticationType") == null)
{
actionContext.Response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.Unauthorized,
Content = new StringContent("You are unauthorized to access this resource!")
};
}
}
}
public class TokenAuthorization : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
var principal = actionContext.RequestContext.Principal as ClaimsPrincipal;
if (principal.FindFirst("authenticationType") != null)
{
actionContext.Response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.Unauthorized,
Content = new StringContent("You are unauthorized to access this resource!")
};
}
}
}
public class PasswordAuthenticationOptions : AuthenticationOptions
{
public PasswordAuthenticationOptions() : base("password")
{ }
}
public class PasswordAuthenticationHandler : AuthenticationHandler<PasswordAuthenticationOptions>
{
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()
{
bool authorized = await Task<bool>.Run(() => IsAuthorised(Request.Headers));
if (authorized)
{
AuthenticationProperties authProperties = new AuthenticationProperties();
authProperties.IssuedUtc = DateTime.UtcNow;
authProperties.ExpiresUtc = DateTime.UtcNow.AddDays(1);
authProperties.AllowRefresh = true;
authProperties.IsPersistent = true;
IList<Claim> claimCollection = new List<Claim>
{
new Claim(ClaimTypes.Name, "Andras")
, new Claim(ClaimTypes.Country, "Sweden")
, new Claim(ClaimTypes.Gender, "M")
, new Claim(ClaimTypes.Surname, "Nemes")
, new Claim(ClaimTypes.Email, "hello@me.com")
, new Claim(ClaimTypes.Role, "IT")
, new Claim("authenticationType", "password")
};
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claimCollection, "Custom");
AuthenticationTicket ticket = new AuthenticationTicket(claimsIdentity, authProperties);
return ticket;
}
return null;
}
private bool IsAuthorised(IHeaderDictionary requestHeaders)
{
string[] username,password;
bool usernamePresent = requestHeaders.TryGetValue("username", out username);
bool passwordPresent = requestHeaders.TryGetValue("password", out password);
if (usernamePresent& passwordPresent)
{
if("user1".Equals(username[0])&&"pass".Equals(password[0]))
return true;
}
return false;
}
}
public class PasswordAuthMiddleware : AuthenticationMiddleware<PasswordAuthenticationOptions>
{
public PasswordAuthMiddleware(OwinMiddleware nextMiddleware, PasswordAuthenticationOptions authOptions)
: base(nextMiddleware, authOptions)
{ }
protected override AuthenticationHandler<PasswordAuthenticationOptions> CreateHandler()
{
return new PasswordAuthenticationHandler();
}
}
public static class PassworAuthenticationExtension
{
public static void UsePasswordAuthentication(this IAppBuilder appBuilder)
{
appBuilder.Use<PasswordAuthMiddleware>(new PasswordAuthenticationOptions());
}
}
[PasswordAuthorization]
public class Values2Controller : ApiController
{
// GET: api/Values2
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
[TokenAuthorization]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() {
ValidateIssuer = true,
ValidIssuers =new string[] { "https://sts.windows.net/{tenantId}/" }
}
});