WebAPI + SimpleMembership + WebSecurity - 无法进行身份验证?

3
我正在尝试实现一个单页应用程序。我从另一个项目(MVC4)中搬运了我的一些工作代码来实现身份验证。现在我看到了 cookie 的设置,但是 WebSecurity / User.Identity 似乎因某种原因而无法工作。登录后,后续请求始终不会通过 WebSecurity.IsAuthenticated 或 User.Identity.IsAuthenticated 进行身份验证。有人知道这是为什么吗?
控制器代码:
public class AccountController : ApiController {

    private readonly UserService _userService;

    public AccountController() {}

    public AccountController(UserService userService) {
        _userService = userService;
    }

    [AllowAnonymous]
    [HttpGet]
    [Route("api/authpayload")]
    // This gets called when the app loads.  Always, User.Identity.IsAuthenticated is false. 
    public HttpResponseMessage AuthPayload() {
        var payload = new AuthPayloadDto();
        try {
            var userId = WebSecurity.GetUserId(User.Identity.Name);
            if (User.Identity.IsAuthenticated && userId > 0) {
                payload.Username = User.Identity.Name;
            } else {
                LogOut();
                payload.IsAuthenticated = false;
            }
            return Request.CreateResponse(HttpStatusCode.OK, payload);
        } catch (Exception e) {
            return Request.CreateResponse(HttpStatusCode.InternalServerError, e);
        }
    }

    [HttpPost]
    [Route("api/login")]
    [AllowAnonymous]
    public HttpResponseMessage LogIn(LoginModel model) {
        if (!ModelState.IsValid)
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        try {
            if (WebSecurity.IsAuthenticated)
                return Request.CreateResponse(HttpStatusCode.Conflict, "already logged in.");
            if (!WebSecurity.UserExists(model.Username))
                return Request.CreateResponse(HttpStatusCode.Conflict, "User does not exist.");
            if (WebSecurity.Login(model.Username, model.Password, persistCookie: model.RememberMe)) {
                // This code always gets hit when I log in, no problems.  I see a new cookie get sent down as well, using Chrome debugger.
                var payload = new AuthPayloadDto();
                return Request.CreateResponse(HttpStatusCode.OK, payload);
            }
            LogOut();
            return Request.CreateResponse(HttpStatusCode.Forbidden, "Login Failed.");
        } catch (Exception e) {
            return Request.CreateResponse(HttpStatusCode.InternalServerError, e);
        }
    }

Web.config:

<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <authentication mode="Forms">
      <forms loginUrl="~/" timeout="2880" />
    </authentication>
    <roleManager enabled="true" defaultProvider="simple">
      <providers>
        <clear />
        <add name="simple" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
      </providers>
    </roleManager>
    <membership defaultProvider="simple">
      <providers>
        <clear />
        <add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
      </providers>
    </membership>
    <!--
            If you are deploying to a cloud environment that has multiple web server instances,
            you should change session state mode from "InProc" to "Custom". In addition,
            change the connection string named "DefaultConnection" to connect to an instance
            of SQL Server (including SQL Azure and SQL  Compact) instead of to SQL Server Express.
      -->
    <sessionState mode="InProc" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>

  </system.web>

登录后发送的cookie没有过期,随后的请求中也会将其发送回来,但IsAuthenticated始终为false。我做错了什么?

更新:

我更新了我的web.config文件以使一切正常:

<system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <roleManager enabled="true" defaultProvider="SimpleRoleProvider">
      <providers>
        <clear />
        <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
      </providers>
    </roleManager>
    <membership defaultProvider="SimpleMembershipProvider">
      <providers>
        <clear />
        <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
      </providers>
    </membership>
  </system.web>

但我希望您能给出一个解释,为什么这个方法有效;我感到有些困惑。


根据我的个人经验,我从未能够通过MVC的Web API(使用MVC 4和5)使身份验证工作。如果用户通过MVC的社交登录进行登录,那么我可以通过Web API检查当前用户是否已登录。但是尝试实际登录用户始终是一个挑战。还有其他第三方身份验证服务可与MVC一起使用以解决此问题(例如auth0.com)。 - ahmed.eltawil
你解决了你的问题吗?我也遇到了同样的问题。它成功验证了用户,但isauthenticated仍然为false。 - UmarKashmiri
1个回答

0
在我的当前MVC 4项目中,使用的是MSSQL数据库, 这是一个简单的项目,所以我只需要一个非常简单的成员资格提供程序 我禁用了 InitializeSimpleMembershipAttribute 通过。
[Authorize]
//[InitializeSimpleMembership]
public partial class AccountController : Controller

并将此代码添加到 Application_Start 下的 global.asax 中

WebSecurity.InitializeDatabaseConnection(
             connectionStringName: "DefaultConnection",
             userTableName: "UserProfile",
             userIdColumn: "UserID",
             userNameColumn: "UserName",
             autoCreateTables: true);

在我的 MySQL 数据库中,应用程序创建了一些表,其中之一是“Roles”和“UserInRoles”,只需添加我需要的角色,如管理员、客户等... 我通过添加以下代码来限制对某些控制器或操作的访问。
[Authorize(Roles = "Admin")]
public class MessagesController : Controller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接