我试图使用授权令牌来保护我的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_token、expires_in、id_token,即JWT、refresh_token和token_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_token和id_token,但是每次我调用安全操作时,我都会得到401。
我该怎么解决这个问题?
也许这是我错过的东西?
Nuget:
Microsoft.Owin -v 3.1.0
Microsoft.Owin.* -v 3.1.0
System.IdentityModel.Tokens.Jwt -v 4.0.1
发布于 2018-01-05 12:15:09
好吧,所以问题就在签名上。我就是这样做的:
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不起作用,所以就这样吧。
https://stackoverflow.com/questions/48100690
复制相似问题