我们有一个带有个人用户身份验证的mvc 5应用程序,我们还有一个xamarin表单应用程序。当我们通过我们正在创建的xamarin应用程序登录时,我们需要能够使用在Web应用程序上创建的相同登录详细信息。我们已成功地使用Web应用程序中的现有模型创建Web api控制器,并在xamarin应用程序中读/写数据。但问题是我们无法向xamarin应用程序提供相同的身份验证(用户名和密码以及分配给用户的角色)。我们怎样才能创建一个从我们现有的数据库中读取的api控制器。请注意我们的应用程序是在带有sql数据库的azure上托管的。
基本上我们想通过移动应用程序提供对我们的Web应用程序的登录。
答案 0 :(得分:1)
您需要查看Adrian Halls的书 - 第2章介绍了您需要的自定义身份验证。
https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter2/custom/
关键点是将移动应用设置为在Azure门户中使用身份验证,但不要设置任何身份验证提供程序(这使其自定义)
然后,您需要实现自己的自定义身份验证控制器来处理身份验证回调,就像这个从Adrian的书中获取的示例一样;
using System;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security.Claims;
using System.Web.Http;
using Microsoft.Azure.Mobile.Server.Login;
using Newtonsoft.Json;
namespace AWPBackend.Controllers
{
[Route(".auth/login/custom")]
public class CustomAuthController : ApiController
{
private MobileServiceContext db;
private string signingKey, audience, issuer;
public CustomAuthController()
{
db = new MobileServiceContext();
signingKey = Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY");
var website = Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME");
audience = $"https://{website}/";
issuer = $"https://{website}/";
}
[HttpPost]
public IHttpActionResult Post([FromBody] User body)
{
if (body == null || body.Username == null || body.Password == null ||
body.Username.Length == 0 || body.Password.Length == 0)
{
return BadRequest(); ;
}
if (!IsValidUser(body))
{
return Unauthorized();
}
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, body.Username)
};
JwtSecurityToken token = AppServiceLoginHandler.CreateToken(
claims, signingKey, audience, issuer, TimeSpan.FromDays(30));
return Ok(new LoginResult()
{
AuthenticationToken = token.RawData,
User = new LoginResultUser { UserId = body.Username }
});
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool IsValidUser(User user)
{
return db.Users.Count(u => u.Username.Equals(user.Username) && u.Password.Equals(user.Password)) > 0;
}
}
public class LoginResult
{
[JsonProperty(PropertyName = "authenticationToken")]
public string AuthenticationToken { get; set; }
[JsonProperty(PropertyName = "user")]
public LoginResultUser User { get; set; }
}
public class LoginResultUser
{
[JsonProperty(PropertyName = "userId")]
public string UserId { get; set; }
}
实际的自定义身份验证发生在IsValidUser函数中,并且应链接到您现有的内部身份验证方法(请勿使用此处的示例,这仅用于演示)
自定义身份验证必须使用也符合您要求的客户端流程。