首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.Net框架多租户OIDC认证

.Net框架多租户OIDC认证
EN

Stack Overflow用户
提问于 2022-10-20 08:27:22
回答 1查看 38关注 0票数 0

我们有3个应用程序(桌面,移动,Excel插件),这意味着3个客户端ID,需要调用我们的API。

是否可以配置我们的API来处理这3个客户端ID?下面是当前的配置:

代码语言:javascript
复制
            string OidcAuthority = Config.OidcAuthority;
            string OidcRedirectUrl = Config.OidcRedirectUrl;
            string OidcClientId = Config.OidcClientId;
            string OidcClientSecret = Config.OidcClientSecret;

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            var oidcOptions = new OpenIdConnectAuthenticationOptions
            {
                Authority = OidcAuthority,
                ClientId = OidcClientId,
                ClientSecret = OidcClientSecret,
                PostLogoutRedirectUri = OidcRedirectUrl,
                RedirectUri = OidcRedirectUrl,
                ResponseType = OpenIdConnectResponseType.Code,
                Scope = OpenIdConnectScope.OpenId                    
            };
            app.UseOpenIdConnectAuthentication(oidcOptions);

编辑:

下面是我们在使用oauth2和Auth0服务时使用的代码。

代码语言:javascript
复制
            var domain = Config.Domain;
            var apiIdentifier = Config.ApiIdentifier;
            var keyResolver = new OpenIdConnectSigningKeyResolver(domain);

            app.UseJwtBearerAuthentication(
                new JwtBearerAuthenticationOptions
                {
                    AuthenticationMode = AuthenticationMode.Active,
                    TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidAudience = apiIdentifier,
                        ValidIssuer = domain,
                        IssuerSigningKeyResolver = (token, securityToken, kid, parameters) => keyResolver.GetSigningKey(kid)
                    }
                });

我知道我必须使用类似的东西,但我有3个可能的应用程序可以产生一个令牌,这意味着3个可能的观众.我怎么发动汽车呢?

Edit2:

下面是在桌面应用程序(Ext )中发出访问令牌的代码:

代码语言:javascript
复制
    userLogin: function(){
        let deferred = new Ext.Deferred();
        let self = this;

        if (window.location.href.indexOf("#id_token") >= 0) {
            return self.processLoginResponse(deferred, self);
        }
        
        var settings = {
            authority: 'https://' + ONELOGIN_SUBDOMAIN + '.onelogin.com/oidc/2',    
            client_id: ONELOGIN_CLIENT_ID,
            redirect_uri: window.location.origin,
            response_type: 'id_token token',
            scope: 'openid profile',
        
            filterProtocolClaims: true,
            loadUserInfo: true
        };
        var mgr = new Oidc.UserManager(settings);

        mgr.signinRedirect({state:'some data'}).then(function() {
            deferred.resolve("signin redirect");
        }).catch(function(err) {
            deferred.reject(err);
        });

        return deferred.promise;
    },

    processLoginResponse: function(deferred, self){            
        var settings = {
            authority: 'https://' + ONELOGIN_SUBDOMAIN + '.onelogin.com/oidc/2',    
            client_id: ONELOGIN_CLIENT_ID,
            redirect_uri: window.location.origin,
            response_type: 'id_token token',
            scope: 'openid profile',
        
            filterProtocolClaims: true,
            loadUserInfo: true
        };

        var mgr = new Oidc.UserManager(settings);
        mgr.signinRedirectCallback().then(function(user) {
            Ext.Ajax.setDefaultHeaders({ 'Authorization': 'Bearer ' + user.id_token });
            deferred.resolve("user signed in");
        }).catch(function(err) {
            console.log(err);
            deferred.reject(err);
        });

        return deferred.promise;
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-20 13:13:10

网站v技术栈

您正在使用的技术堆栈是为网站设计的。加载HTML页面时,如果没有有效的身份验证cookie,则会突然将用户重定向到登录。

本地客户端则通过直接HTTP请求调用API,上面的堆栈将尝试重定向这些请求,这将是错误的行为。

相反,本地应用程序应该使用自己的客户机ID来实现自己的OIDC流以获得访问令牌。RFC8252标准描述了这些流。API不需要知道其调用方的客户端ID。

API技术栈行为

对多个相关客户端使用相同的API是可能的,通常也是推荐的。如果使用C#,API通常使用以下选项,其中API对每个请求验证JWT访问令牌:

代码语言:javascript
复制
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = Config.Authority;
        options.Audience = Config.Audience;
    });

这是为了使用它而包含的Microsoft包:

代码语言:javascript
复制
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.10" />

通常,权限是授权服务器的基本URL,而受众是您定义的表示一个或多个相关API的值:

代码语言:javascript
复制
authority: https://login.example.com
audience: api.example.com

如果需要的话,具有相同受众的API可以相互转发JWT,以便它们都可以以相同的方式授权请求。Microsoft安全堆栈将从授权服务器下载并缓存令牌签名公钥,然后使用它对接收到的访问令牌进行数字验证并构建ClaimsPrincipal。

一旦验证了JWT,您还可以信任它发出的声明,并根据它们进行授权,例如定义如下授权策略:

代码语言:javascript
复制
services.AddAuthorization(options =>
{
    options.AddPolicy("myPolicy", policy =>
        policy.RequireAssertion(context =>
            context.User.HasClaim(claim => 
                claim.Type == "myClaim" && claim.Value == "myValue
            )
        )
    );
});

在逻辑级别编写授权代码的一种方法是,控制器随后应用授权属性,以便应用策略:

代码语言:javascript
复制
[HttpGet("/api/resource")]
[Authorize(Policy = "myPolicy")]
public IActionResult GetResource()
{
    return Ok(new { data = "My data" });
}

JWT在.NET框架中的验证

在旧的.NET框架中,概念是相同的,唯一的区别是授权属性的工作方式可能略有不同。下面是如何验证JWT,其中Issuer / Authority仍然表示授权服务器的基本URL:

代码语言:javascript
复制
app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions
    {
        TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidIssuer = Config.Issuer;
            ValidAudience = Config.Audience;
        }
    });
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74136660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档