我正在使用带有.NET后端的Xamarin Forms移动应用程序。我跟着this guide并成功设置了自定义身份验证,并在Startup.cs中进行了一次更改:
app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
{
SigningKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY"),
ValidAudiences = new[] { Identifiers.Environment.ApiUrl },
ValidIssuers = new[] { Identifiers.Environment.ApiUrl },
TokenHandler = config.GetAppServiceTokenHandler()
});
没有" if(string.IsNullOrEmpty(settings.HostName))"。否则,我在登录后总是未经授权处理所有请求。
服务器项目:
验证控制器
public class ClubrAuthController:ApiController { private readonly ClubrContext dbContext; private readonly ILoggerService loggerService;
public ClubrAuthController(ILoggerService loggerService)
{
this.loggerService = loggerService;
dbContext = new ClubrContext();
}
public async Task<IHttpActionResult> Post(LoginRequest loginRequest)
{
var user = await dbContext.Users.FirstOrDefaultAsync(x => x.Email == loginRequest.username);
if (user == null)
{
user = await CreateUser(loginRequest);
}
var token = GetAuthenticationTokenForUser(user.Email);
return Ok(new
{
authenticationToken = token.RawData,
user = new { userId = loginRequest.username }
});
}
private JwtSecurityToken GetAuthenticationTokenForUser(string userEmail)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, userEmail)
};
var secretKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY");
var audience = Identifiers.Environment.ApiUrl;
var issuer = Identifiers.Environment.ApiUrl;
var token = AppServiceLoginHandler.CreateToken(
claims,
secretKey,
audience,
issuer,
TimeSpan.FromHours(24)
);
return token;
}
}
Startup.cs
ConfigureMobileAppAuth(app, config, container);
app.UseWebApi(config);
}
private void ConfigureMobileAppAuth(IAppBuilder app, HttpConfiguration config, IContainer container)
{
config.Routes.MapHttpRoute("ClubrAuth", ".auth/login/ClubrAuth", new { controller = "ClubrAuth" });
app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
{
SigningKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY"),
ValidAudiences = new[] { Identifiers.Environment.ApiUrl },
ValidIssuers = new[] { Identifiers.Environment.ApiUrl },
TokenHandler = config.GetAppServiceTokenHandler()
});
}
客户项目:
MobileServiceUser user = await MobileClient.LoginAsync(loginProvider, jtoken);
此外,我在azure门户中配置了Facebook提供程序,如here所述。 但它只有在我注释掉app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions(){...})时才有效;在Startup.cs中。 我缺少两种类型的身份验证同时工作?
答案 0 :(得分:0)
由于您启用了应用服务身份验证/授权,因此已经验证了令牌。它会假设您的令牌结构,例如让受众和发布者与您的应用URL相同(默认情况下)。
app.UseAppServiceAuthentication()
也会验证令牌,因为它是meant for local development。因此,在您的示例中,令牌将被验证两次。除了潜在的性能影响,这通常很好。但是,这意味着令牌必须在两个层上都通过验证,我怀疑情况并非如此,因此错误。
检查这一点的一种方法是检查令牌本身。在客户端应用程序中设置断点并获取从LoginAsync()
获取的令牌,该令牌将成为该用户对象的一部分。然后前往http://jwt.io之类的服务,查看令牌内容的样子。我怀疑Facebook令牌与您为aud
配置的iss
具有不同的Identifiers.Environment.ApiUrl
和app.UseAppServiceAuthentication()
声明,而自定义令牌可能与您匹配{#1}} 39;在第一个代码段中重新使用该值。
如果这是成立的,那么你应该处于两个令牌都失败的状态。 Facebook令牌将通过托管验证但在本地中间件上失败,而自定义令牌将失败托管验证但传递本地中间件。
此处最简单的解决方案是在云中托管时删除app.UseAppServiceAuthentication()
。您还需要确保拨打CreateToken()
的电话使用基于云的网址作为受众和发布者。
对于发现此问题的其他人
答案 1 :(得分:-1)
您引用的代码仅适用于本地部署。对于Azure部署,您需要打开应用服务身份验证/授权 - 即使您没有配置身份验证提供程序(在自定义身份验证的情况下也不会这样做)。
查看我的书的第2章 - http://aka.ms/zumobook