使用Windows Azure Mobile Service 进行Azure Active Directory 身份验证

Windows Azure Mobile Service (WAMS) 对移动应用提供了多项功能,如数据交互/存储、用户身份认证、推送消息及调度作业(scheduled jobs)等,本文结合WAMS的身份认证功能介绍如何获取更多的用户信息如用户名用于应用显示。

微软官方文档Get started with authentication in Mobile Services详细介绍了如何使用所支持的identity provider 如Microsoft AccountFacebook loginTwitter loginGoogle loginAzure Active Directory(AAD)对移动应用提供身份验证功能,并且可以通过采用日志Expanded login scopes in Azure Mobile Services介绍的API获取用户ID信息,该文档介绍了如何通过Graph API获得Microsoft AccountFacebook loginGoogle login账号的用户信息,那么针对Azure Active Directory账号,该如何获取呢?AAD也提供了丰富的Graph API,可以用于获得用户信息。接下来我们以一个简单的Windows Store APP为例详细讲解如何使用Azure Active Directory进行用户身份认证并获取ID信息。 

首先在Azure Management Portal上创建一个Azure Mobile Service,如名为wamsaad,

                        

点击新建的Mobile Service 的IDENTITY 标签,滚动到windows azure active directory,拷贝APP URL的值-如https://wamsaad.azure-mobile.net/login/aad,将用于后续Active Directory 配置。

                     

切换到Active Directory,创建一个新的AAD domain 如名为icesmart,<添加了两名用户test1@icesmart.onmicrosoft.com><和test2@icesmart.onmicrosoft.com>,当作测试账号。

                  

点击icesmart 的APPLICATIONS标签,然后点击ADD按钮添加一个应用,在弹出的对话框选择“Add and application my organization is developing”

                   

在Add Application向导窗口添加一个新的应用,如名为 wamsaad,选择类型为Web Application And/OR Web API,在SIGN-ON URL里,使用前文提及的mobile service 提供的active directory 身份认证的APP URL值(https://wamsaad.azure-mobile.net/login/aad),在APP ID URI同样使用一个唯一的URI,如https://wamsaad.azure-mobile.net/login/sso

               

应用添加完毕后,点击CONFIGURE标签,拷贝CLIENT ID值,粘贴到前文新建的Mobile Service wamsadd的IDENTITY标签下的windows azure active directory CLIEND ID区域

                   

                             

 

点击新建的AAD application-wamsaad,在CONFIGURE标签下,点击页面底部的“MANAGE MANIFEST”按钮下载manifest 文件,打开该文件将 "appPermissions" : [], 内容替换为如下内容后保存该文件,再点击“MANAGE MANIFEST”按钮上传该文件

"appPermissions": [

    {

        "claimValue": "user_impersonation",

        "description": "Allow the application access to the mobile service",

        "directAccessGrantTypes": [],

        "displayName": "Have full access to the mobile service",

        "impersonationAccessGrantTypes": [

            {

                "impersonated": "User",

                "impersonator": "Application"

            }

        ],

        "isDisabled": false,

        "origin": "Application",

        "permissionId": "b69ee3c9-c40d-4f2a-ac80-961cd1534e40",

        "resourceScopeType": "Personal",

        "userConsentDescription": "Allow the application full access to the mobile service on your behalf",

        "userConsentDisplayName": "Have full access to the mobile service"

    }

],

                        

同时在该标签下Keys区域,选择创建一个key如1年有效期,然后点击下端的SAVE按钮,会生成一个Key,注意保存该Key,在使用Graph API时会用到,当离开该页面时,key值会被隐藏

                               

 

再在该页面上的permissions to other applications 区域做相应配置,依次选择Windows Azure Active Directory, Read directory data等

                            

在Azure Mobile Service-wamsaad端,点击API标签,然后点击“CREATE”按钮就创建一个API 如getUserInfo,其SCRIPT类容可参见文档,替换自己的clientID, key及AAD domain值如icesmart.onmicrosoft.com,该API用于与AAD通信,获得基本的Graph 数据;在移动设备端如Windows Store/Phone App中,调用该API,当用户使用AAD账号登录后,App获得用户数据,结果如下截图显示。

public class UserDetails

{

    public String userPrincipalName { get; set; }

    public String displayName { get; set; }

    public String usageLocation { get; set; }

}

private MobileServiceUser user;

private static MobileServiceClient MobileService = new MobileServiceClient(

           "https://wamsaad.azure-mobile.net/", "Application Key");

 

   private async System.Threading.Tasks.Task LoginAAD()

        {

            while (MobileService.CurrentUser == null)

            {

                string message;

                try

                {

                    user = await MobileService.LoginAsync("aad");

                    var result = await MobileService.InvokeApiAsync("getuserinfo", HttpMethod.Get, null);

                    UserDetails currentUser = JsonConvert.DeserializeObject<UserDetails>(result.ToString());               

 

                     message = string.Format("Welcome, {0}! You are now logged in.", result.ToString() + currentUser.userPrincipalName);

                }

                catch (InvalidOperationException)

                {

                    message = "You must log in. Login Required";

                }

 

            }

        }