1

我一直在尝试在我们的 .Net 4.5.2 网站项目中实施一个可行的解决方案。 我的目标是将我的网站项目(一个 Web 表单应用程序(不是 MVC))转换为使用身份服务器 3(可能通过 thinktecture 的实现)来验证/授权用户。

这可能吗? 站点生命周期将如何变化,或者它可以对会话对象说同样的话?我可以使用身份服务器获取访问令牌然后设置会话,并且仅在会话到期或访问令牌到期时请求新的访问令牌吗?

一些背景故事:

我在以下位置https://localhost:44399确实有一个有效的身份服务器 3 设置。当我使用直接的 html 文件时,它会响应所有适当的调用和限制,但是当我尝试在登录页面 (portal.aspx) 中实现相同的东西时,它似乎忘记了用户并且行为不一样。该网站(客户端)设置在https://localhost:9898上。登录页面是https://localhost:9898/portal.aspx

我在 portal.aspx 页面上使用了 oidc-client.js,但是当它尝试进行身份验证时,我不断收到 CORS(跨浏览器源脚本)错误。 这是 Web 表单的问题吗?使用常规 html 页面时不会发生这种情况?

这是一个 .net 4.5.2 “网站项目”(不是“网络应用程序项目”),它使用 Web 表单,而不是 MVC。我有许多演示 MVC 应用程序可以正常工作,但是当我尝试将我所拥有的知识用于 Web 表单应用程序时,我发现我真的不了解正在发生的事情。

我添加了以下 nuget 包:

Microsoft.Bcl v1.1.10
Microsoft.Owin v3.0.1
Microsoft.Bcl.Async v1.0.168
System.IdentityModel.Tokens.Jwt v5.1.0
Newtonsoft.Json v9.0.1
Owin v1.0.0
Microsoft.IdentityModel.Logging v1.1.0
Microsoft.Owin.Host.SystemWeb v3.0.1
System.IdentityModel.Tokens.Jwt v5.1.0
Microsoft.IdentityModel.Tokens v5.1.0
Microsoft.Bcl.Build v1.0.21
Thinktecture.IdentityModel v3.6.1

当我尝试添加 startup.cs 类时,它告诉我这些类通常添加到 App_Code 目录中,我想把它放在那里吗?我已经尝试过 root 和 App_Code 目录,但在调用它们时似乎都没有注册。我已经添加了包,认为这就是调用的内容:

Microsoft.Owin.Host.SystemWeb

但似乎启动类没有注册。 那么我如何让它在管道中注册,以便 401 未授权错误将用户发送到身份服务器?

这是我的启动课:

using ExpenseTracker.WebClient.Helpers;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Newtonsoft.Json.Linq;
using Owin;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Web;
using System.Web.Helpers;
using Thinktecture.IdentityModel.Client;


[assembly: OwinStartup(typeof(ExpenseTracker.WebClient.Startup))]

namespace ExpenseTracker.WebClient
{
public class Startup
{

    public void Configuration(IAppBuilder app)
    {
        JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();

        AntiForgeryConfig.UniqueClaimTypeIdentifier = "unique_user_key";

        app.UseResourceAuthorization(new AuthorizationManager());

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            ClientId = "mvc",
            Authority = ExpenseTrackerConstants.IdSrv,
            RedirectUri = ExpenseTrackerConstants.ExpenseTrackerClient,
            SignInAsAuthenticationType = "Cookies",

            ResponseType = "code id_token token",
            Scope = "openid profile roles expensetrackerapi offline_access",

            Notifications = new OpenIdConnectAuthenticationNotifications()
            {

                MessageReceived = async n =>
                {
                    EndpointAndTokenHelper.DecodeAndWrite(n.ProtocolMessage.IdToken);
                    EndpointAndTokenHelper.DecodeAndWrite(n.ProtocolMessage.AccessToken);

                    //var userInfo = await EndpointAndTokenHelper.CallUserInfoEndpoint(n.ProtocolMessage.AccessToken);    

                },

                SecurityTokenValidated = async n =>
                {                         
                    var userInfo = await EndpointAndTokenHelper.CallUserInfoEndpoint(n.ProtocolMessage.AccessToken);


                    // use the authorization code to get a refresh token 
                    var tokenEndpointClient = new OAuth2Client(
                        new Uri(ExpenseTrackerConstants.IdSrvToken),
                        "mvc", "secret");

                    var tokenResponse = await tokenEndpointClient.RequestAuthorizationCodeAsync(
                        n.ProtocolMessage.Code, ExpenseTrackerConstants.ExpenseTrackerClient);



                    var givenNameClaim = new Claim(
                        Thinktecture.IdentityModel.Client.JwtClaimTypes.GivenName,
                        userInfo.Value<string>("given_name"));

                    var familyNameClaim = new Claim(
                        Thinktecture.IdentityModel.Client.JwtClaimTypes.FamilyName,
                        userInfo.Value<string>("family_name"));

                    var roles = userInfo.Value<JArray>("role").ToList();

                    var newIdentity = new ClaimsIdentity(
                       n.AuthenticationTicket.Identity.AuthenticationType,
                       Thinktecture.IdentityModel.Client.JwtClaimTypes.GivenName,
                       Thinktecture.IdentityModel.Client.JwtClaimTypes.Role);

                    newIdentity.AddClaim(givenNameClaim);
                    newIdentity.AddClaim(familyNameClaim);

                    foreach (var role in roles)
                    {
                        newIdentity.AddClaim(new Claim(
                        Thinktecture.IdentityModel.Client.JwtClaimTypes.Role,
                        role.ToString()));
                    }

                    var issuerClaim = n.AuthenticationTicket.Identity
                        .FindFirst(Thinktecture.IdentityModel.Client.JwtClaimTypes.Issuer);
                    var subjectClaim = n.AuthenticationTicket.Identity
                        .FindFirst(Thinktecture.IdentityModel.Client.JwtClaimTypes.Subject);

                    newIdentity.AddClaim(new Claim("unique_user_key",
                        issuerClaim.Value + "_" + subjectClaim.Value));


                    newIdentity.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken));
                    newIdentity.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
                    newIdentity.AddClaim(new Claim("expires_at",  
                        DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString()));

                    n.AuthenticationTicket = new AuthenticationTicket(
                        newIdentity,
                        n.AuthenticationTicket.Properties);

                },


            }



            });


    }

}
}

更糟糕的是,添加 Microsoft.Owin.Host.SystemWeb 由于以下奇怪的错误而无法编译:

    The type or namespace name 'SessionState' does not exist in the 
    namespace 'System.Web' (are you missing an assembly reference?)
4

0 回答 0