无法设置 OWIN + OneLogin + Bearer

Posted

技术标签:

【中文标题】无法设置 OWIN + OneLogin + Bearer【英文标题】:Can't setup OWIN + OneLogin + Bearer 【发布时间】:2018-06-14 12:05:27 【问题描述】:

我正在尝试使用授权令牌来保护我的 WebAPI 项目。我不想使用 cookie,我只想使用 Authorization 这样的标头:Authorization: Bearer xxx_access_or_id_token_xxx。我使用OneLogin OIDC 作为外部提供者。这是我的Startup.cs

using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using Microsoft.Owin.Security.Jwt;
using Owin;
using System.Web.Http;   

public void Configuration(IAppBuilder app)

    var issuer = "https://openid-connect.onelogin.com/oidc/";
    var audience = ConfigurationManager.AppSettings["OneLoginClientId"];
    var secret = TextEncodings.Base64.Encode((TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["OneLoginClientSecret"])));

    app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions 
        AuthenticationMode = AuthenticationMode.Active,
        AllowedAudiences = new[]  audience ,
        IssuerSecurityTokenProviders = new[]  new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret) 
    );

    HttpConfiguration httpConfig = new HttpConfiguration();
    WebApiConfig.Register(httpConfig);
    app.UseWebApi(httpConfig);

我也有控制器:

public class ValueController: ApiController

    [HttpGet]
    [AllowAnonymous]
    public string NotSecure()
    
        return "Not secure";
    

    [HttpGet]
    [Authorize]
    public strnig Secure()
    
        return "Secure";
    

好的,现在让我们来看看 OneLogin 部分。 经过身份验证流程后,我得到了 5 个字段:access_tokenexpires_inid_token,即 JWT、refresh_tokentoken_type

使用jwt.io 我可以解析我的id_token,我有这样的东西:

标题


  "alg": "RS256",
  "typ": "JWT",
  "kid": "xxx"

有效载荷


  "sub": "33827172",
  "email": "john.smith@company.com",
  "name": "John Smith",
  "iat": 1515083928,
  "exp": 1515091128,
  "aud": "onelogin_client_id",
  "iss": "https://openid-connect.onelogin.com/oidc"

我正在尝试使用授权令牌发送到我的 api 请求。我尝试同时发送:access_tokenid_token,但每次我调用安全操作时,都会收到 401。

我该如何解决这个问题?

也许我错过了什么?

Nuget:

Microsoft.Owin -v 3.1.0

Microsoft.Owin.* -v 3.1.0

System.IdentityModel.Tokens.Jwt -v 4.0.1

【问题讨论】:

你安装Microsoft.Owin.Host.SystemWeb了吗? 您是否检查过只在授权标头中放置 access_token 而没有放置“承载”字样? @talha-junaid,是的,当然。它是与另一个软件包一起安装的。 需要调试 SymmetricKeyIssuerSecurityTokenProvider 【参考方案1】:

好的,问题出在签名上。 以下是我的工作方式:

public static class AuthConfig

    public static JwtBearerAuthenticationOptions GetOptions()
    
        var keyResolver = new KeyResolver(System.Configuration.ConfigurationManager.AppSettings["OneLoginOpenIdConfigurationDomain"]); //https://<your_domain>.onelogin.com/oidc

        return new JwtBearerAuthenticationOptions
        
            AuthenticationMode = AuthenticationMode.Active,
            TokenValidationParameters = new TokenValidationParameters
            
                ValidIssuer = System.Configuration.ConfigurationManager.AppSettings["OneLoginJWTIssuer"], //https://openid-connect.onelogin.com/oidc
                ValidAudience = System.Configuration.ConfigurationManager.AppSettings["OneLoginClientId"],
                IssuerSigningKeyResolver = (token, securityToken, identifier, paramaters) => keyResolver.GetSigningKey(identifier)
            
        ;
    


#region Helpers
public class KeyResolver

    private readonly OpenIdConnectConfiguration openIdConfig;
    private static readonly TaskFactory TaskFactory = new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default);

    public KeyResolver(string domain)
    
        var cm = new ConfigurationManager<OpenIdConnectConfiguration>($"domain/.well-known/openid-configuration");
        openIdConfig = TaskFactory.StartNew(async () => await cm.GetConfigurationAsync()).Unwrap().GetAwaiter().GetResult();
    

    public SecurityKey GetSigningKey(SecurityKeyIdentifier identifier)
    
        // Find the security token which matches the identifier
        var securityToken = openIdConfig.SigningTokens.FirstOrDefault(t =>
        
            // Each identifier has multiple clauses. Try and match for each
            foreach (var securityKeyIdentifierClause in identifier)
                if (t.MatchesKeyIdentifierClause(securityKeyIdentifierClause))
                    return true;

            return false;
        );

        // Return the first key of the security token (if found)
        return securityToken?.SecurityKeys.FirstOrDefault();
    


#endregion

这里是Startup.cs

public class Startup

    public void Configuration(IAppBuilder app)
    
        HttpConfiguration httpConfig = new HttpConfiguration();
        WebApiConfig.Register(httpConfig);

        app.UseJwtBearerAuthentication(AuthConfig.GetOptions());
        app.UseWebApi(httpConfig);
    

我也将此添加到 WebApiConfig,但我不确定这是否真的有帮助。

config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter("Bearer"));

Nuget

<package id="Microsoft.AspNet.Cors" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.IdentityModel.Logging" version="1.1.5" targetFramework="net45" />
<package id="Microsoft.IdentityModel.Protocol.Extensions" version="1.0.4.403061554" targetFramework="net45" />
<package id="Microsoft.IdentityModel.Tokens" version="5.1.5" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Cookies" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Jwt" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security.OAuth" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security.OpenIdConnect" version="3.1.0" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="System.IdentityModel.Tokens.Jwt" version="4.0.4.403061554" targetFramework="net45" />

在我的测试中,大于 4.0.4 的版本 System.IdentityModel.Tokens.Jwt 无法正常工作,所以就这样吧。

我还要感谢Auth0 和他们的Github 提供的出色手册。

【讨论】:

以上是关于无法设置 OWIN + OneLogin + Bearer的主要内容,如果未能解决你的问题,请参考以下文章

无法让 OpenID 身份验证与 Onelogin 和 Azure Web 应用程序一起使用

SSO 与 Onelogin 针对 SSOCircle

使用 OneLogin 和 DotNetOpenAuth 在 CrossDomain 上进行 ASP.Net 单点登录

OWIN OpenIdConnect 中间件 IDX10311 随机数无法验证

OneLogin SAML 注销功能

OneLogin 签名的 Authnrequest HTTP 重定向方法