我将以新类的形式创建一个额外的包装器,在里面配置您的服务。证书问题(http或https)使用策略配置解决:
Policy = new IdentityModel.OidcClient.Policy()
{
Discovery = new IdentityModel.Client.DiscoveryPolicy()
{
RequireHttps = config.GetRequiredSection("IdentityServer").GetValue<bool>("RequireHttps")
}
}
详细的客户端移动示例:
//In this class, you can add any additional logic and use it as a kind of decorator
public class Auth0Client
{
//Your real service.
private readonly OidcClient oidcClient;
public Auth0Client(Auth0ClientOptions options)
{
oidcClient = new OidcClient(new OidcClientOptions
{
Authority = options.Authority,
ClientId = options.ClientId,
ClientSecret = options.ClientSecret,
Scope = options.Scope,
RedirectUri = options.RedirectUri,
PostLogoutRedirectUri = options.PostLogoutRedirectUri,
Policy = options.Policy,
Browser = options.Browser
});
}
public IdentityModel.OidcClient.Browser.IBrowser Browser
{
get
{
return oidcClient.Options.Browser;
}
set
{
oidcClient.Options.Browser = value;
}
}
public async Task<LoginResult> LoginAsync()
{
return await oidcClient.LoginAsync();
}
public async Task<LogoutResult> LogoutAsync(string identityToken)
{
LogoutResult logoutResult = await oidcClient.LogoutAsync(new LogoutRequest { IdTokenHint = identityToken });
return logoutResult;
}
}
public class Auth0ClientOptions
{
public Auth0ClientOptions()
{
Browser = new WebBrowserAuthenticator();
}
public string Authority { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string RedirectUri { get; set; }
public string PostLogoutRedirectUri { get; set; }
public string Scope { get; set; }
public Policy Policy { get; set; }
public IdentityModel.OidcClient.Browser.IBrowser Browser { get; set; }
}
public class WebBrowserAuthenticator : IdentityModel.OidcClient.Browser.IBrowser
{
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
{
try
{
WebAuthenticatorResult result = await WebAuthenticator.Default.AuthenticateAsync(
new Uri(options.StartUrl),
new Uri(options.EndUrl));
var url = new RequestUrl(options.EndUrl)
.Create(new Parameters(result.Properties));
return new BrowserResult
{
Response = url,
ResultType = BrowserResultType.Success
};
}
catch (TaskCanceledException)
{
return new BrowserResult
{
ResultType = BrowserResultType.UserCancel,
ErrorDescription = "Login canceled by the user."
};
}
}
}
配置服务
builder.Services.AddScoped(new Auth0Client(new Auth0ClientOptions()
{
Authority = config.GetRequiredSection("IdentityServer:Authority").Value,
ClientId = config.GetRequiredSection("IdentityServer:ClientId").Value,
ClientSecret = config.GetRequiredSection("IdentityServer:ClientSecret").Value,
Scope = config.GetRequiredSection("IdentityServer:Scope").Value,
RedirectUri = config.GetRequiredSection("IdentityServer:RedirectUri").Value,
PostLogoutRedirectUri = config.GetRequiredSection("IdentityServer:PostLogoutRedirectUri").Value,
Policy = new IdentityModel.OidcClient.Policy()
{
Discovery = new IdentityModel.Client.DiscoveryPolicy()
{
RequireHttps = config.GetRequiredSection("IdentityServer").GetValue<bool>("RequireHttps")
}
}
}));
使用服务
public partial class MainPage : ContentPage
{
private readonly Auth0Client auth0Client;
public MainPage(Auth0Client client)
{
InitializeComponent();
auth0Client = client;
}
private async void OnLoginClicked(object sender, EventArgs e)
{
var loginResult = await auth0Client.LoginAsync();
}
private async void OnLogoutClicked(object sender, EventArgs e)
{
var logoutResult = await auth0Client.LogoutAsync("");
}
我还建议使用secrets.json来存储设置(URI等)。YouTube上有一段关于如何将他们与毛伊岛项目联系起来的视频。视频名为:
“.Net MAUI和Xamarin Forms从secrets.json或appsettings.json获取设置”
最重要的是,在包装器中实现try-catch块会更容易
如果要将服务直接注入到页面构造函数中,请不要忘记为其指定依赖项
builder.Services.AddScoped<MainPage>();
settings.json
{
"IdentityServer": {
"Authority": "http://test-site.com",
"ClientId": "mobile-client",
"ClientSecret" : "qwerty123*",
"Scope": "openid profile",
"RedirectUri": "mauiclient://signin-oidc",
"PostLogoutRedirectUri": "mauiclient://signout-callback-oidc",
"RequireHttps" : "false"
}
}
如果使用http协议,则添加到清单(Android)
<application
android:usesCleartextTraffic="true">
</application>