当前位置: 首页 > 知识库问答 >
问题:

IdentityServer SSO-受信任的应用程序

李康安
2023-03-14

我需要SSO(单点登录)来自我的应用程序的用户(使用ASPNET会话状态的身份提供者),并将他们重定向到我的另一个应用程序(服务提供者),该应用程序html" target="_blank">配置为使用IdentityServer4的隐式流。我需要在不要求用户重新登录和不提供用户密码的情况下实现这一点。

我最初的想法是,我可以使用身份提供者的客户端密码将用户重定向到IdentityServer4身份验证endpoint,并将访问令牌作为查询参数,然后使用自定义验证器或扩展授权来颁发身份令牌,以便与服务提供者应用程序一起使用,而无需同时提供用户的密码。

我成功地向身份提供者发出访问令牌,然后将用户重定向到IdentityServer4,但事实证明,发出身份令牌对我来说很困难。我已经把样品和文档都翻了一遍,至少可以说我很困惑。

我正在寻找这个场景的适当方法的方向,也许是C#中的一个全面示例。我逐渐了解到,我可以使用混合流来发布访问令牌和身份令牌。我认为我最大的困难是如何重定向用户,并基于访问令牌向用户颁发身份令牌(如果这是一种可接受的方法)。

简单地说:我想基于对身份提供者的信任(通过客户端机密?),将用户从应用程序A重定向到IdentityServer4,再重定向到应用程序B。

注意:我知道这可以被认为是一个基于意见的问题,但是根据我的研究,我相信有一个最佳实践,这就是我所要求的。

共有2个答案

韩欣怿
2023-03-14

我想我可能会先处理应用程序A的身份验证,然后转到下一个应用程序...

应用程序A--

您可以在returnUrl中包含一些自定义参数,应用程序A可以在从IdentityServer返回时读取这些参数,从而触发重定向到应用程序B。

孟佑运
2023-03-14

我设法通过以下流程使其工作:

  1. 在应用程序A(身份提供者)中授权用户

共享秘密的配置:

向客户端添加适当的授予类型、机密和新作用域名称。新的作用域将有助于调试日志中的访问令牌问题(尤其是当有多个应用程序访问ID4服务器时)。还要确保将服务提供商的URL添加到客户端重定向URI,否则您将收到“无效重定向”错误。

            AllowedGrantTypes = new List<string> { GrantType.Implicit, GrantType.ClientCredentials },
            ClientSecrets = new List<Secret> {
                new Secret(_clientSecrets.ExternalIdpSecret.Sha256(), clientID)
            },
            AllowedScopes = new List<string>
            {
                "newScopeName"
            },
            RedirectUris = new List<string>
            {
                $"http://localhost:<portnumber>"
            }

接下来,添加自定义中间件。

public class QueryStringOAuthBearerMiddleware
{
    private readonly RequestDelegate next;

    public QueryStringOAuthBearerMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        this.BeginInvoke(context);
        await this.next.Invoke(context);
        this.EndInvoke(context);
    }

    private void BeginInvoke(HttpContext context)
    {
        if (context.Request.Query.ContainsKey("accesstokenparametername"))
        {
            var accessToken = context.Request.Query.First(p => p.Key == "accesstokenparametername");

            if (!string.IsNullOrEmpty(accessToken.Value))
            {
                context.Request.Headers.Add("Authorization", "Bearer " + accessToken.Value);
            }
        }
    }

    private void EndInvoke(HttpContext context)
    {
    }
}

并将中间件添加到您的配置中。

        app.UseMiddleware<QueryStringOAuthBearerMiddleware>();

创建您的登录方法

    [HttpGet]
    [Authorize]
    public async Task<IActionResult> Login2(string userName, string returnURL)
    {
        await _httpContextWrapper.SignInAsync(userName);

        return Redirect(returnURL);
    }

客户端应用程序(IDP)配置:

客户端代码应如下所示:

var disco = await DiscoveryClient.GetAsync("http://localhost:<portnumber>");
var tokenClient = new TokenClient(disco.TokenEndpoint, "clientIdentifier", "IUsedAGuidHere");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("newScopeName");

var redirectURL = string.Format("http://localhost:2228/account/Login2?userName=<UserIDValue>&returnURL={1}&accesstokenparametername={0}",
            tokenResponse.AccessToken,
            Server.UrlEncode(
                string.Format("/connect/authorize/login?client_id={3}&redirect_uri={2}&response_type=id_token%20token&scope=<ImplicitFlowScopes>&state={0}&nonce={1}",
                CryptoRandom.CreateUniqueId(),
                CryptoRandom.CreateUniqueId(),
                Server.UrlEncode("http://localhost:<PortNumber>"),
                "ClientIdentifier")));

Response.Redirect(redirectURL, false);

注意:请理解,您将无法按原样使用此代码并使其正常工作。我对其进行了大量修改,以保护我资源的安全。

 类似资料:
  • 我一直在学习JavaFX的任务,并使用这些任务通过或任务的方法等与应用程序线程进行通信。但是,我的需要知道用户何时按下 GUI 上的按钮,因为这可能会更改任务的 方法需要返回的值。我该怎么做?我知道如何响应单线程应用程序上的按钮按下事件,但不确定如何以线程安全的方式处理它。 到目前为止,这是我所拥有的,这是实现按钮事件的明智方式吗?

  • 我正在开发一个企业应用程序。当我在iOS8测试版中测试它时,我看到了以下警报视图: 它只是第一次出现。我能设法避免吗?它与什么有关?

  • 我们正在构建一个通过RabbitMQ接收消息的Spring Boot应用程序(2.0.4版本)。因此,包含与rabbit相关的配置: 配置: 原因:java.lang.IllegalArgumentException:类“My.Fancy.Package.Clazz”不在受信任的包[java.util,java.lang]中。如果您认为反序列化该类是安全的,请提供它的名称。如果序列化仅由受信任的源

  • 由于我在.netcore方面的知识非常有限,如果有人能给我指明正确的方向,我将不胜感激。

  • 我试图用JUnit实现一些Selenium2WebDriver测试。有关硒的文件。org和web让我感到困惑,因为它似乎在seleniumrc和Webdriver之间来回跳跃。另外,我的Java不是很强。几年前我上过几门课,但没怎么用。我想让JUnit测试在无头CI服务器上运行,并让Firefox通过使用Webdriver在远程客户端系统上运行。 根据我收集的信息,我可以使用以下代码在本地系统上打

  • 我正在使用OpenSSL以避免为此付费。我的服务器正在运行IIS 8和Windows server 2012。 我创建证书的方式是: openssl请求-new-key cakey.pem-x509-days 1825-extensions v3_ca-out ca.crt 最后,我使用以下内容签署了证书请求: openssl x509-req-days 365-in certreq.txt-ca