Sal*_*ony 7 asp.net oauth access-token jwt asp.net-web-api
遵循本手册并构建了令牌认证.它在调试模式下完美运行,但在发布模式下,调用TokenEndpointPath会导致调用
未找到路径'/ bps/oauth/token'的控制器或未实现IController.
由于Web.config文件中的WebBaseUri,URI具有/ bps/part.
<appSettings>
<add key="WebBaseUrl" value="/bps/" />
<add key="WebApiBaseUrl" value="/api/" />
<add key="owin:AutomaticAppStartup" value="true" />
<add key="LoginErrorMessage" value="Login or email is wrong" />
Run Code Online (Sandbox Code Playgroud)
Startup类如下:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use<OwinExceptionHandlerMiddleware>();
var container = new WindsorContainer().Install(new WindsorInstaller());
container.Register(Component.For<IAppBuilder>().Instance(app));
var httpDependencyResolver = new WindsorHttpDependencyResolver(container);
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.DependencyResolver = httpDependencyResolver;
app.CreatePerOwinContext(() => container.Resolve<ApplicationUserManager>());
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new WindsorControllerActivator(container));
ConfigureOAuthTokenGeneration(app, container);
ConfigureOAuthTokenConsumption(app);
app.UseWebApi(config);
}
private void ConfigureOAuthTokenGeneration(IAppBuilder app, IWindsorContainer container)
{
var OAuthServerOptions = new OAuthAuthorizationServerOptions
{
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = container.Resolve<IOAuthAuthorizationServerProvider>(),
AccessTokenFormat = container.Resolve<CustomJwtFormat>(),
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
private void ConfigureOAuthTokenConsumption(IAppBuilder app)
{
var issuer = ConfigurationManager.AppSettings["ServerAddress"];
string audienceId = ConfigurationManager.AppSettings["AudienceId"];
byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["AudienceSecret"]);
// Api controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { audienceId },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
这是为Provider属性解析的IOAuthAuthorizationServerProvider的实现:
public class OAuthService : OAuthAuthorizationServerProvider
{
private readonly IApplicationUserService _userService;
private readonly ICredentialsValidatior _credentialsValidatior;
public OAuthService(IApplicationUserService userService, ICredentialsValidatior credentialsValidatior)
{
this._userService = userService;
_credentialsValidatior = credentialsValidatior;
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
return Task.FromResult<object>(null);
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");
if (allowedOrigin == null) allowedOrigin = "*";
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
/* Some user validation logick */
var user = await _userService.FindByNameAsync(context.UserName);
ClaimsIdentity oAuthIdentity = await GenerateUserIdentityAsync(user);
var ticket = new AuthenticationTicket(oAuthIdentity, null);
context.Validated(ticket);
}
private async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUser user)
{
const string authenticationType = "JWT";
var userIdentity = await _userService.CreateIdentityAsync(user, authenticationType);
return userIdentity;
}
}
Run Code Online (Sandbox Code Playgroud)
正在为AccessTokenFormat属性解析的类:
public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
private readonly string _issuer;
public CustomJwtFormat(string issuer)
{
_issuer = issuer;
}
public string Protect(AuthenticationTicket data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
string audienceId = ConfigurationManager.AppSettings["AudienceId"];
string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["AudienceSecret"];
var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
var signingKey = new HmacSigningCredentials(keyByteArray);
var issued = data.Properties.IssuedUtc;
var expires = data.Properties.ExpiresUtc;
var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);
var handler = new JwtSecurityTokenHandler();
var jwt = handler.WriteToken(token);
return jwt;
}
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
此代码在我的本地计算机上运行,并在调试和发布模式下正常运行.
将此代码以调试模式发布到开发服务器时,会出现此问题.
我发现在本地计算机上将AllowInsecureHttp属性切换为false会导致此错误,但dev服务器上的版本完全相同.我检查了IL代码,并且AllowInsecureHttp属性设置为1.
UPDATE
我试图将/ bps/part添加到TokenEndpointPath但它没有帮助.
由于未知原因,它甚至在本地也不起作用.我发现项目的设置是这样的

不幸的是,我试图在开发服务器上找到这些设置,因为我缺乏关于IIS的知识,我没有找到任何东西.
我还尝试检查OWIN管道,发现通过管道传递的URL与Startup.cs中配置的URL相同.
我还在StackOverflow上发现了这个问题.
| 归档时间: |
|
| 查看次数: |
1084 次 |
| 最近记录: |