使用WebForms和WebApi思考IdentityServer v3

Nik*_*kov 5 asp.net webforms asp.net-web-api thinktecture-ident-server

我正在尝试用一段时间来弄清楚如何使用Thinktecture IdentityServer v3为传统的webforms应用程序解决SSO(单点登录).不幸的是我堆积了.

基础设施是这样的:

  • 需要身份验证和授权的WebForm应用程序(可能是cookie或承载令牌)
  • 一个javascript轻量级应用程序(一旦用户通过身份验证)向WebApi发出请求(在单独的域上)

我有以下问题希望能帮助我解决问题:

  1. 我无法将旧的webforms应用程序重定向到IdentityServer,即使在Web.Config中设置也是如此.我在Startup.cs中有app.UseCookieAuthentication(....)和app.UseOpenIdConnectAuthentication(....)正确设置(我猜).对于MVC,[Authorize]属性强制重定向到IdentityServer.如何为webforms做到这一点?
  2. 一旦用户登录,是否有一种方法可以将存储在cookie中的令牌作为持有者令牌重用于从javascript客户端进行的WebApi调用.我只是想代表当前登录的用户对WebApi做请求(webforms应用程序和webapi再次位于不同的域上)

任何帮助都感激不尽.

谢谢!

Der*_*k S 4

我目前正在从事同一类型的项目。这是我到目前为止所发现的。

有 4 个单独的问题。

  1. 身份服务器 - 维护对用户/客户端/范围进行身份验证
  2. WebApi - 使用身份服务器生成的令牌来获取用户的授权和身份信息。
  3. WebForms / JQuery - 对于我的项目,当前处理现有功能重定向到新 WebApi 的身份验证。
  4. 使用 Javascript 的 HTML - 严格使用 WebApi 来获取信息。

下面的自定义授权适用于当前通过 WebForm 作为成员资格对象登录的用户,我不想再次要求用户通过 Identity Server 重新登录。

对于直接 oAuth 身份验证,请查看此处的示例。

示例 Javascript 客户端

配置 Javascript 隐式流程就可以正常工作。保存与 api 连接的令牌。

身份服务器 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"
                    }
                }
            };
Run Code Online (Sandbox Code Playgroud)

WebApi - 资源

WebApi 客户端示例示例

需要有Nuget包

Thinktecture.IdentityServer.AccessTokenValidation

启动.cs

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
                {
                    //Location of your identity server
                    Authority = "https://localhost:44333/core"
                });
Run Code Online (Sandbox Code Playgroud)

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;
        }
Run Code Online (Sandbox Code Playgroud)

这些是本示例的通用声明,但是我可以生成与用户相关的自己的声明对象,以发送到身份服务器并重新生成身份以供 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: '/' });

   });
Run Code Online (Sandbox Code Playgroud)

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);
        }

    });
}
Run Code Online (Sandbox Code Playgroud)

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 });
Run Code Online (Sandbox Code Playgroud)

这假设您使用与 WebForm 相同的域。否则,我将使用查询字符串重定向到带有令牌的 Angular 页面。

对于 CORS 支持,需要确保 WebApi 已配置 Cors 以实现正确的功能。使用

Microsoft.AspNet.WebApi.Cors

希望这对如何解决这个问题有所启发