首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能设置OWIN + OneLogin + Bearer

不能设置OWIN + OneLogin + Bearer
EN

Stack Overflow用户
提问于 2018-01-04 17:38:35
回答 1查看 547关注 0票数 0

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

代码语言:javascript
复制
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);
}

我也有控制员:

代码语言:javascript
复制
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,我有如下所示:

报头

代码语言:javascript
复制
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "xxx"
}

有效载荷

代码语言:javascript
复制
{
  "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

EN

回答 1

Stack Overflow用户

发布于 2018-01-05 12:15:09

好吧,所以问题就在签名上。我就是这样做的:

代码语言:javascript
复制
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

代码语言:javascript
复制
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration httpConfig = new HttpConfiguration();
        WebApiConfig.Register(httpConfig);

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

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

代码语言:javascript
复制
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter("Bearer"));

Nuget

代码语言:javascript
复制
<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提供的很好的手册。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48100690

复制
相关文章

相似问题

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