Car*_*any 2 c# console-application azure azure-active-directory adal
我创建了一个使用Azure Active Directory进行身份验证的Web API.它使用多租户AAD.为了测试它,我还创建了一个控制台应用程序,它使用ADAL库对AAD进行身份验证,以便我可以访问我的API.在主要的AAD租户中,一切运作良好,因为我不需要授予任何东西.但是当从第二个租户访问应用程序时,我首先触发管理员同意流程(添加一个prompt=admin_consent).但是当我再次退出并打开应用程序时,如果我尝试使用没有管理员权限的用户登录AAD,它会尝试打开用户同意并且失败(因为用户无权访问AAD).如果我已经给予管理员同意,那么用户是否应该同意?
测试应用程序的代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Authentication;
using System.Threading.Tasks;
using System.Web;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;
namespace TestConsole
{
internal class Program
{
private const string _commonAuthority = "https://login.microsoftonline.com/common/";
private static void Main(string[] args)
{
ConsoleKeyInfo kinfo = Console.ReadKey(true);
AuthenticationContext ac = new AuthenticationContext(_commonAuthority);
while (kinfo.Key != ConsoleKey.Escape)
{
if (kinfo.Key == ConsoleKey.A)
{
AuthenticationResult ar = ac.AcquireToken("https://babtecportal.onmicrosoft.com/Portal2015.Api", "client_id", new Uri("https://out.es"), PromptBehavior.Auto, UserIdentifier.AnyUser, "prompt=admin_consent");
}
else if (kinfo.Key == ConsoleKey.C)
{
Console.WriteLine("Token cache length: {0}.", ac.TokenCache.Count);
}
else if (kinfo.Key == ConsoleKey.L)
{
ac.TokenCache.Clear();
HttpClient client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, _commonAuthority + "oauth2/logout?post_logout_redirect_uri=" + HttpUtility.UrlEncode("https://out.es"));
var response=client.SendAsync(request).Result;
Console.WriteLine(response.StatusCode);
ac=new AuthenticationContext(_commonAuthority);
}
else
{
int num;
if (int.TryParse(Console.ReadLine(), out num))
{
try
{
AuthenticationResult ar = ac.AcquireToken("https://babtecportal.onmicrosoft.com/Portal2015.Api", "client_id", new Uri("http://out.es"),PromptBehavior.Auto,UserIdentifier.AnyUser);
ac = new AuthenticationContext(ac.TokenCache.ReadItems().First().Authority);
// Call Web API
string authHeader = ar.CreateAuthorizationHeader();
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format("http://localhost:62607/api/Values?num={0}", num));
request.Headers.TryAddWithoutValidation("Authorization", authHeader);
HttpResponseMessage response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
string responseString = response.Content.ReadAsStringAsync().Result;
Values vals = JsonConvert.DeserializeObject<Values>(responseString);
Console.WriteLine("Username: {0}", vals.Username);
Console.WriteLine("Name: {0}", vals.FullName);
vals.Range.ToList().ForEach(Console.WriteLine);
}
else
{
Console.WriteLine("Status code: {0}", response.StatusCode);
Console.WriteLine("Reason: {0}", response.ReasonPhrase);
}
}
catch (AdalException ex)
{
Console.WriteLine(ex.Message);
}
}
}
kinfo = Console.ReadKey(true);
}
}
}
public class Values
{
public string Username { get; set; }
public string FullName { get; set; }
public IEnumerable<int> Range { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
您的测试应用程序是本机客户端.在OAuth术语中,它是一个公共客户端.这些条款适用于没有客户机密或自己的证书凭证的任何客户.管理员同意功能不适用于本机客户端,仅适用于Web应用程序.理想情况下,当尝试对本机应用程序进行管理员同意时,会返回错误,表明该组合不受支持.我们将在未来考虑返回这样的错误以防止这种混淆.
与此同时,当用户登录本机客户端时,无法阻止用户查看同意对话.
如果本机应用程序调用web api,其中本机应用程序和web api都由同一供应商/租户拥有,则情况稍微复杂一些.如果设置正确,则用户将看到一个组合同意对话框,允许用户同意本机应用程序和Web api.将永久记录对web api的同意.对本机应用程序的同意仅适用于该登录会话,其方式与未涉及web api时相同.如果以这种方式涉及web api,则可以调用管理员同意.然后,管理员可以代表所有用户同意web api.但是,个人用户仍需要同意本机应用.
要正确设置此同意链,您需要在web api的应用程序清单中使用"knownClientApplication"属性.您将此属性的值设置为本机应用程序的客户端ID.您可以在此示例中看到此操作:
https://github.com/AzureADSamples/NativeClient-WebAPI-MultiTenant-WindowsStore/blob/master/README.md
基本上,您通过门户网站下载应用程序清单,更新此特定值,然后上载它.
这里有一些关于这些主题的更全面的文档:
https://msdn.microsoft.com/en-us/library/azure/dn132599.aspx
更新: 上面对调用web api的本机应用程序的解释中的一条规定是它们都必须在同一个租户中.如果他们不在同一个房客那么事情会变得更复杂.当ISV创建了一个他们希望提供给客户编写的应用程序的Web API时就是这种情况.为了让应用获取资源的令牌,两个应用必须在同一个租户中注册.因此,客户需要做的第一件事就是在自己的租户中注册web api.如果web api在应用程序库中,那么他们只需去那里安装应用程序.ISV不必在应用程序库中拥有应用程序以允许客户注册它,但注册变得更加复杂.ISV将需要创建一个在ISV租户中注册的网站,客户管理员可以访问该网站.该网站需要在管理员中签名,以便以触发同意过程的方式获取Web api的令牌.完成后,api将在客户租户中注册并可供客户应用使用.
要将您的应用应用到应用程序库,请按照本页底部附近的说明操作:
http://azure.microsoft.com/en-us/marketplace/active-directory/
| 归档时间: |
|
| 查看次数: |
3492 次 |
| 最近记录: |