无法设置OWIN + OneLogin + Bearer
我正在尝试使用授权令牌来保护我的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。 在Authentication Flow之后,我得到了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
好的,问题出在Signature上。 这是我如何使它工作:
public static class AuthConfig { public static JwtBearerAuthenticationOptions GetOptions() { var keyResolver = new KeyResolver(System.Configuration.ConfigurationManager.AppSettings["OneLoginOpenIdConfigurationDomain"]); //https://.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($"{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
这个添加到WebApiConfig
,但我不确定这真的有帮助。
config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter("Bearer"));
Nuget :
在我的测试System.IdentityModel.Tokens.Jwt
版本大于4.0.4不起作用,所以保持这样。
另外,我要感谢Auth0及其Github的精彩手册。