我正试图弄清楚如何使用Thinktecture IdentityServer v3解决遗留Web表单应用程序的SSO(单点登录)问题。不幸的是,我累了。
基础设施是这样的:
- 需要身份验证和授权的WebForm应用程序(可能cookie或承载令牌)
- javascript轻量级应用程序(一旦用户通过身份验证)向WebApi(位于单独的域上)发出请求
我有以下问题,希望能帮助我提出问题:
- 我无法使遗留的webforms应用程序重定向到IdentityServer,即使在Web.Config.中有set。我在Startup.cs应用程序中有。使用CookieAuthentication(….)和应用程序。UseOpenIdConnectAuthentication(….)设置正确(我想)。对于MVC,[Authorize]属性强制重定向到IdentityServer。网络表单应该如何做到这一点
- 一旦用户登录,是否有一种方法可以将存储在cookie中的令牌重新用作从javascript客户端进行的WebApi调用的承载令牌。我只想代表当前登录的用户向WebApi发出请求(再次,webforms应用程序和WebApi位于不同的域上)
任何帮助都将不胜感激。
谢谢!
我目前正在处理同一类型的项目。这就是我到目前为止所发现的。
有4个单独的问题。
- Identity Server-维护身份验证用户/客户端/作用域
- WebApi-使用Identity Server生成的令牌进行授权&用户的身份信息
- WebForms/JQuery-对于我的项目,当前处理现有功能的身份验证重定向到新的WebApi
- 使用Javascript的HTML-严格使用WebApi作为信息
下面的自定义授权是针对当前通过WebForm作为成员对象登录的用户&我不想再次要求用户通过Identity Server重新登录。
要获得直接oAuth身份验证,请查看此处的示例。。
示例Javascript客户端
将Javascript配置为隐式流就可以了。保存与api连接的令牌。
Identity Server v3
我不得不使用进行配置
自定义授予IUserService
自定义授权
这些将显示如何配置自定义授权验证。使用用户服务,您可以让身份服务查询现有用户&自定义声明。
Identity Server有很多配置,可以让它成为您自己的。这在IdentityServer网站上有很好的记录,我不会去介绍如何设置基础知识。
例如:客户端配置
return new List<Client>
{
new Client
{
ClientName = "Custom Grant Client",
Enabled = true,
ClientId = "client",
ClientSecrets = new List<ClientSecret>
{
new ClientSecret("secret".Sha256()),
},
Flow = Flows.Custom,
CustomGrantTypeRestrictions = new List<string>
{
"custom"
}
}
};
WebApi-资源
示例WebApi客户端示例
需要有Nuget包
Thinktecture.IdentityServer.AccessTokenValidation
启动.cs
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
//Location of your identity server
Authority = "https://localhost:44333/core"
});
WebForms后端WebForms调用
需要Nuget包
Thinktecture.IdentityModel.Client
[WebMethod]
[ScriptMethod(ResponseFormat.Json)]
public static string AuthorizeClient()
{
var client = new OAuth2Client(
//location of identity server, ClientId, ClientSecret
new Uri("http://localhost:44333/core/connect/token"),
"client",
"secret");
//ClientGrantRestriction, Scope (I have a Client Scope of read), Listing of claims
var result = client.RequestCustomGrantAsync("custom", "read", new Dictionary<string, string>
{
{ "account_store", "foo" },
{ "legacy_id", "bob" },
{ "legacy_secret", "bob" }
}).Result;
return result.AccessToken;
}
这些是本例的通用声明,但我可以生成自己的与用户相关的声明对象,以发送到Identity Server&重新生成WebApi要使用的标识。
WebForms/JQuery使用
JQuery.cookie
$('#btnTokenCreate').click(function (e) {
//Create Token from User Information
Ajax({
url: "Default.aspx/AuthorizeClient",
type: "POST"
},
null,
function (data) {
sendToken = data.d;
//Clear Cookie
$.removeCookie('UserAccessToken', { path: '/' });
//Make API Wrap Info in Stringify
$.cookie.json = true;
//Save Token as Cookie
$.cookie('UserAccessToken', sendToken, { expires: 7, path: '/' });
});
JQuery WebAPI Ajax示例Ajax方法-注意beforeSend。
function Ajax(options, apiToken, successCallback) {
//Perform Ajax Call
$.ajax({
url: options.url,
data: options.params,
dataType: "json",
type: options.type,
async: false,
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
//Before Sending Ajax Perform Cursor Switch
beforeSend: function (xhr) {
//Adds ApiToken to Ajax Header
if (apiToken) {
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", " Bearer " + apiToken);
}
},
// Sync Results
success: function (data, textStatus, jqXHR) {
successCallback(data, textStatus, jqXHR);
},
//Sync Fail Call back
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
});
}
AngularJS
这与使用的JQuery有着相同的想法
module.run(function($http) {
//Make API Wrap Info in Stringify
$.cookie.json = true;
//Save Token as Cookie
var token = $.cookie('UserAccessToken');
$http.defaults.headers.common.Authorization = 'Bearer ' + token });
这使得假设您使用与WebForm相同的域。否则,我将使用查询字符串重定向到带有标记的Angular页面。
对于CORS支持,需要确保WebApi配置了COR以实现正确的功能。使用
Microsoft.AspNet.WebApi.Cors
希望这能为如何处理提供一些线索