我为ASP.NET MVC 4开发的公司开发了一个数据监控门户(我将其命名为Portal A)。我们与另一家公司达成协议,将该数据监控门户与公司自己的在线门户(如门户网站B)整合。
现在他们想要使用Portal A的一些用户界面,这将节省他们在Portal B中开发自己的UI的时间。两个门户与我门户(Portal A)中集成的WebApi交互,提供所需的数据门户网站A和门户网站B拥有自己的独立数据,除了管理员的登录凭据。两个数据库都包含另一个数据库的确切副本。
Portal A和Portal B都使用Session范围中的变量。问题是;假设用户登录到Portal B,现在我想使用通过Ajax通过Portal B发送的凭据在Portal A中创建会话,这样用户就不必再次登录Portal A.我通过WebApi / Ajax拍摄了一张照片。
我在门户网站A中创建了一个API,仅用于此目的:
[RoutePrefix("monitoring/auth")]
public class UserCheckController : ApiController
{
[EnableCors("*", "*", "*")]
[Route("login/{username}/{password}/{token}")]
[System.Web.Http.HttpGet]
public User UserLogin(string username, string password, string token)
{
User login = new User();
login.UserName = username;
login.Password = password;
if (ValidateUser(login, token) == true)
{
HttpContext.Current.Session[SessionName.UserObject] = login;
HttpContext.Current.Session[SessionName.CurrentToken] = token;
return login;
}
return null;
}
}
我调用此api的jQuery代码如下:
$.ajax({
url: 'http://localhost:4004/monitoring/auth/login/Scott/tiger/THISISATOKEN',
type: 'GET',
contentType: 'application/json',
success: function (data) {
console.log("Login successfull");
console.log(data);
}
});
当我通过Ajax调用api时,我在Debug模式下看到变量被分配给会话,我在控制台中获取了数据对象JSON。
我在同一个API中有另一个函数来检查用户的存在,代码如下:
[EnableCors("*", "*", "*")]
[Route("isalive/{userId}/{username}/{token}")]
[System.Web.Http.HttpGet]
public bool IsAlive(int userId, string username, string token )
{
User user = HttpContext.Current.Session[SessionName.UserObject] as User;
string _token = HttpContext.Current.Session[SessionName.CurrentToken].ToString();
if (user == null)
{
return false;
}
return (id == user.UserId&& user.UserName.Equals(username) && _token.Equals(token));
}
jQuery的:
$.ajax({
url: 'http://localhost:4004/monitoring/auth/isalive/97/Scott/THISISATOKEN',
type: 'GET',
contentType: 'application/json',
success: function (data) {
console.log("Checking for Session");
console.log(data);
}
});
结果显示为false,因为用户为null。 我无法访问前一个ajax创建的会话数据。有没有办法在AJAX / WebApi和浏览器之间保留Portal A中的会话。
解决这个问题的最佳方法是什么?
答案 0 :(得分:3)
听起来你在谈论single sign-on解决方案。这通常通过像OAuth这样的联合身份验证机制来实现,其中用户使用服务进行身份验证,然后给予承载令牌,然后可以将此承载令牌重播到发出它的服务以断言用户凭证的有效性。
在您描述的场景中,门户B将向客户端发出令牌(可能是加密的用户名)以响应成功的登录尝试。然后,使用Portal B的客户端将在调用Portal A时提供该令牌,然后,Portal A将通过服务器到服务器调用将该令牌呈现给Portal B,以测试令牌的有效性,并开始经过身份验证的会话。
我应该补充一点,实际的OAuth实现需要比此处描述的更复杂,并且存在许多相关的安全问题。
答案 1 :(得分:1)
要确保可以访问会话变量,必须在被调用的文件中声明session_start(),并触发文件