使用C#开发Android客户端时,需要通过Identity Server 4进行认证。需要安装程序包:IdentityModel.OidcClient,在程序中需要配置:
private OidcClientOptions _options;
_options = new OidcClientOptions
{
Authority = _authority,
Policy= new Policy()
{
Discovery = new DiscoveryPolicy { RequireHttps = false } ,
},
ClientId = "mymobileclient",
Scope = "openid profile poemapi",
RedirectUri = "io.identitymodel.native://callback",
Browser = new ChromeCustomTabsBrowser(this),
};
Login方法中,初始化OidcClient并登录:
var oidcClient = new OidcClient(_options);
var result = await oidcClient.LoginAsync();
_state = new State
{
IdToken = result.IdentityToken,
AccessToken = result.AccessToken,
RefreshToken = result.RefreshToken,
User = result.User,
Error = result.Error,
};
调用Web API
var client = new HttpClient();
client.SetBearerToken(_state.AccessToken);
在认证管理中配置相关的client。
还需要编写自定义的浏览器接口,启动移动设备的浏览器完成认证:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.CustomTabs;
using Android.Views;
using Android.Widget;
using IdentityModel.OidcClient.Browser;
namespace AndroidClient
{
public class ChromeCustomTabsBrowser : IBrowser
{
private readonly Activity _context;
private readonly CustomTabsActivityManager _manager;
public ChromeCustomTabsBrowser(Activity context)
{
_context = context;
_manager = new CustomTabsActivityManager(_context);
}
public Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default(CancellationToken))
{
var task = new TaskCompletionSource<BrowserResult>();
var builder = new CustomTabsIntent.Builder(_manager.Session)
.SetToolbarColor(Color.Argb(255, 52, 152, 219))
.SetShowTitle(true)
.EnableUrlBarHiding();
var customTabsIntent = builder.Build();
// ensures the intent is not kept in the history stack, which makes
// sure navigating away from it will close it
customTabsIntent.Intent.AddFlags(ActivityFlags.NoHistory);
Action<string> callback = null;
callback = url =>
{
OidcCallbackActivity.Callbacks -= callback;
task.SetResult(new BrowserResult()
{
Response = url
});
};
OidcCallbackActivity.Callbacks += callback;
customTabsIntent.LaunchUrl(_context, Android.Net.Uri.Parse(options.StartUrl));
return task.Task;
}
}
}
还需要编写Callback页面的代码,当认证通过后,跳转到这个页面进行处理,然后返回主页面:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace AndroidClient
{
[Activity(Label = "OidcCallbackActivity")]
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = "io.identitymodel.native",
DataHost = "callback")]
public class OidcCallbackActivity : Activity
{
public static event Action<string> Callbacks;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Finish();
Callbacks?.Invoke(Intent.DataString);
}
}
}
网友评论