应用系统Azure AD认证(二)

应用系统Azure AD认证

应用系统与员工账户认证绑定(AD),实现基于Azure AD的Multi-Factor Authentication(MFA)。

1.3 前端登录认证

1.3.1 使用Azure AD登录

当用户登录时,JavaScript 前端使用 JavaScript (ADAL.JS) 的 Active Directory 身份验证库和隐式授权授予从 Azure AD 获取一个 ID 令牌 (id_token)。 该令牌随后被缓存,当客户端调用使用 OWIN 中间件进行保护的 Web API 后端时,客户端将该令牌作为持有者令牌附加到请求。
在这里插入图片描述

  1. 用户导航到 Web 应用程序。
  2. 应用程序将 JavaScript 前端(表示层)返回到浏览器。
  3. 如用户未登录启动登录。浏览器将 GET 发送到 Azure AD 授权终结点来请求一个 ID 令牌。此请求将应用程序 ID 和答复 URL 包含在查询参数中。
  4. Azure AD 根据在 Azure 门户中配置的已注册答复 URL 来验证答复 URL。
  5. 用户在登录页面上进行登录。
  6. 如果身份验证成功,Azure AD 将创建一个 ID 令牌,并将其作为 URL 片段 (#) 返回到应用程序的答复 URL。对于生产应用程序,此回复 URL 应当采用 HTTPS 格式。返回的令牌包括应用程序对该令牌进行验证所需的关于用户和 Azure AD 的声明。
  7. 在浏览器中运行的 JavaScript 客户端代码从用于安全调用应用程序的 Web API 后端的响应中提取令牌。
  8. 浏览器使用 Authorization 标头中的访问令牌来调用应用程序的 Web API 后端获取。
1.3.2 使用ADFS登录及Token解析
1.3.2.1 用户登录验证

系统的用户登录是通过ADFS+OAuth来实现的,登录用户为AD中的用户,可以通过用户的邮件地址或者domain\alias的方式登录。ADFS相关配置请参考《ADFS 配置管理手册.docx》,要实现一个应用的用户登录,需要连接到ADFS登录页面,以下是ADFS OAuth登录URL:https://ADFSSserver/adfs/oauth2/authorize?response_type=code&client_id={1}&redirect_uri={2}&resource={3}
参数说明:

  1. response_type: 这里必须为code,表示登录成功后返回一个authorization_code,我们要利用这个code去获取access token
  2. client_id: 在ADFS中通过powershell的Add-ADFSClient命令参数中的ClientId
  3. redirect_uri: 在ADFS中通过powershell的Add-ADFSClient命令参数中的RedirectUri
  4. resource: 在ADFS中配置中的“信赖方信任标识符”,即应用程序中的ida:Audience参数
1.3.2.2 客户端访问OAuth应用

当用户登录成功后,用户访问需要OAuth验证的应用时,需要在每次请求的header里面增加acccess token, OAuth应用会根据这个access token自动验证请求者的身份。

1.3.2.3 获取access token

利用返回的authorization_code来获取access token:
POST https://ADFSSserver/adfs/oauth2/token

request.Content=new  StringContent(string.Format("client_id={0}&redirect_uri={1}&grant_type=authorization_code&code={2}", ClientId, RedirctUri, code));

请求的内容包括ClientId, RedirectUri和authorization_code,返回一个JSON的字符串,包括以下内容:

{"access_token":"youraccesstoken","token_type":"bearer","expires_in":3600}

把这个access token返回到客户端并且保存到sessionStorage中。

1.3.2.4 使用access token

例如在使用AngularJS客户端框架的应用,可以使用窃听器(Interceptor),使用$http与服务器端通讯时,如果希望对request、response做全局的处理,那么Interceptor是一个很好的选择。可以在app.js中增加一个Interceptor来对所有的request,在其请求的header里面增加access token:

app.factory('authInterceptorService',['$q','$location',function($q,$location){
 
 
varauthInterceptorServiceFactory={};
 
varrequest=function (config){
 
config.headers=config.headers||{};
 
vartoken=sessionStorage.getItem("access_token");
if(token){
config.headers.Authorization='Bearer ' + token;
}
 
Return config;
}
 
varresponseError=function(rejection){}

在上面代码中,request函数中headers.Authorization = 'Bearer ’ + token,这个就是表示使用OAuth的token去访问相关资源。在responseError函数中可以对返回的错误状态码进行统一的处理。这样在使用http方式发送请求时,会自动在请求中增加这个access token.如果直接使用$.ajax方式访问应用,可以通过以下方式使用access token:

$.ajax({
		type: 'Get',
		headers:getHearders(),
		url: encodeURI(url)
})

Function getHearders(){
Var token=sessionStorage.getItem("access_token");
Var headers={};
if(token)
headers.Authorization='Bearer '+token;
return headers;
}
1.3.2.5 在服务端获取用户身份

当用户成功登录后,可以在服务器获取用户的相关身份信息:
//获取当前登录用户的用户名,目前设置的是用户的UPN名字,即带域名的邮件地址
HttpContext.Current.User.Identity.Name

//下面代码可以获取当前登录用户所有的角色Roles,如果要获取用户的显示名,可以通过userCommonNameClaim.Value得到

varclaims=((System.Security.Claims.ClaimsIdentity)HttpContext.Current.User.Identity).Claims;
if (claims != null)
{
Var enumerable = claims as Claim[] ?? claims.ToArray();
varroles=enumerable.Where(c=>c.Type==ClaimTypes.Role&&c.Value!= "Domain Users").Select(c=>c.Value).ToArray();
varuserCommonNameClaim=enumerable.FirstOrDefault(c=>c.Type==ClaimTypes.Prip.CommonName);
return new UserInfo()
{
UserName=HttpContext.Current.User.Identity.Name,
UserEmail=HttpContext.Current.User.Identity.Name,
Roles=roles
};
}

1.4 后端调用API获取用户信息(GraphaAPI)

1.4.1 概述

Azure Active Directory (AD) Graph API 是与 OData 3.0 兼容的服务,可用于读取和修改租户中的对象(如用户、组和联系人)。Azure AD Graph API 公开要向其发送 HTTP 请求的 REST 终结点,以使用服务执行操作。下面各节提供了关于以下内容的常规信息:如何对请求进行格式化;使用 Graph API 读取和写入目录资源、调用目录函数或操作,或针对目录执行查询时希望得到什么响应。
在这里插入图片描述

对 Graph API 的成功请求必须发送到有效的终结点且格式正确,也就是说,它必须包含任何必需的标头,如有必要,在请求正文中包含 JSON 有效负载。发出请求的应用必须包括从 Azure AD 收到的令牌,以便证明其有权访问请求的资源。应用必须能够处理从 Graph API 收到的任何响应。

1.4.2 身份验证和授权

每个 Graph API 请求都必须具有通过附加的 Azure Active Directory 颁发的持有者令牌。此令牌具有关于你的应用、已登录用户(有委派权限的情况下)、身份验证和你的应用有权执行的目录上的操作的信息。请求的Authorization标头中携带有此令牌。例如(为简洁起见已缩短令牌):

Authorization: Bearer eyJ0eX ... FWSXfwtQ

Graph API 基于令牌中存在的 OAuth 2.0 权限范围执行授权。
为了使应用通过 Azure AD 进行身份验证并调用 Graph API,必须将其添加到租户中,并配置为需要 Windows Azure Active Directory 的权限(OAuth 2.0 权限范围)。
Azure AD 使用的是 OAuth 2.0 身份验证协议

1.4.3 终结点寻址

若要使用 Graph API 执行操作,请采用支持的方法(通常为GET、POST、PATCH、PUT 或 DELETE)将 HTTP 请求发送至面向服务、资源集合、单个资源、资源的导航属性或由服务公开的函数或操作的终结点。终结点表示为 URL。
下面介绍了 Graph API 终结点的基本格式:

https://graph.windows.net/{tenant_id}/{resource_path}?{api_version}

以下组件构成 URL:
• 服务根:所有 Graph API 请求的服务根服务https://graph.windows.net。
• 租户标识符 {tenant_id}:接收请求的租户的标识符。
• 资源路径 {resource_path}:接收请求的资源(例如,用户或组)的路径。
• Graph API 版本 {api_version}:请求面向的 Graph API 的版本。它表示为一个查询参数,并且是必需的。
在某些情况下,当读取资源集合时,可以将 OData 查询参数添加到请求以对结果集进行筛选、排序和分页。

1.4.4 租户标识符 {tenant_id}

可以使用以下四种方法之一指定请求的目标租户:
• 通过租户对象 ID。这是创建租户时分配的 GUID。它可以在TenantDetail对象的objectId属性中找到。以下 URL 介绍了如何通过使用租户对象 ID 对用户资源集合进行寻址:https://graph.windows.net/12345678-9abc-def0-1234-56789abcde/users?api-version=1.6。
• 通过已验证(注册)的域名。这是为租户注册的域名之一。它们可在 TenantDetail 对象的 verifiedDomains 属性中找到。以下 URL 介绍了如何对域为 contoso.com 的租户的用户资源集合进行寻址:https://graph.windows.net/contoso.com/users?api-version=1.6。
• 通过使用 myOrganization 别名。仅当使用 OAuth 授权码授权类型(3 重)身份验证时,此别名才可用;即当使用委托的权限范围时可用。此别名不区分大小写。它将替换 URL 中的对象 ID 或租户域。使用此别名时,Graph API 将从附加到请求的令牌中提供的声明获取租户。以下 URL 介绍了如何通过使用此别名对租户的用户资源集合进行寻址:https://graph.windows.net/myorganization/users?api-version=1.6。
• 通过使用 me 别名。仅当使用 OAuth 授权码授权类型(3 重)身份验证时,此别名才可用;即当使用委托的权限范围时可用。此别名不区分大小写。它将替换 URL 中的对象 ID 或租户域。使用此别名时,Graph API 将从附加到请求的令牌中提供的声明获取用户。以下 URL 通过使用此别名对已登录用户进行寻址:https://graph.windows.net/me?api-version=1.6。
使用me别名仅适用于针对已登录用户的操作。

1.4.5 资源路径 {resource_path}

可以以不同的方式指定{resource_path},具体取决于你是面向资源集合、单独的资源、资源的导航属性、租户上公开的函数或操作,还是面向资源上公开的函数或操作。
在这里插入图片描述

1.4.6 API 版本 {api-version}

可以使用api-version查询参数将 Graph API 的特定版本作为某操作的目标。此参数是必需的。
api-version参数的值可以是下列内容之一:
• “beta”
• “1.6”
• “1.5”
• “2013/11/08”
• “2013/04/05”
例如,以下 URL 面向使用 Graph API 1.6 版本的用户集合:

https://graph.windows.net/myorganization/users?api-version=1.6
1.4.7 OData 查询参数

在许多情况下,当读取资源集时,可以通过将 OData 查询参数附加到请求中来对结果集进行筛选、排序和分页。
Graph API 支持以下 OData 查询参数:
• $filter
• $batch
• $expand
• $orderby
• $top
• $skiptoken 和 previous-page

1.4.8 请求和响应标头

下表显示了 Graph API 请求中使用的常见 HTTP 标头。
在这里插入图片描述

下表显示了 Graph API 作为响应返回的常见 HTTP 标头。并不意味着它是全面的。
在这里插入图片描述

1.4.9 请求和响应正文

可以在 JSON 或 XML 有效负载中发送 POST、PATCH 和 PUT 请求的请求主体。可以在 JSON 或 XML 有效负载中返回服务器响应。可以通过使用Content-Type请求标头在请求主体中指定有效负载,以及通过使用Accept请求标头作出响应。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值