【问题标题】:FormsAuthentication and Roles problemsFormsAuthentication 和角色问题
【发布时间】:2010-08-03 19:14:28
【问题描述】:
  1. URL 中的垃圾是什么?登录后,我被定向到: @987654321@

  2. 当我调试时,我看到在 Global.asax 和 AccountController 中我的 userRoles/accessLevel 被正确地找到并作为身份验证票证的一部分插入。我的属性设置了查看操作所需的角色。 GET 加载,当我保存 POST 提示登录时,它会不断循环。知道发生了什么吗?此外,当我输出我的 authTicket.UserData 时,我看到我的角色(作者|管理员)但 HttpContext.User.IsInRole("Author"); && HttpContext.User.IsInRole("Author"); 返回 false。我需要在 web.config 中启用 roleManager 吗?如果我将这些信息放在票证中,我应该将其设置为什么?

SpotlightsController.cs:

// GET: /Spotlights/Edit/5
[Authorize(Roles="Author,Admin")]
public ActionResult Edit(int id)
{
    Spotlight spotlight = spotlightRepository.GetSpotlight(id);

    return View(new SpotlightFormViewModel(spotlight));
}

//
// POST: /Spotlights/Edit/5

[Authorize(Roles="Author,Admin"), HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
    Spotlight spotlight = spotlightRepository.GetSpotlight(id);

    try
    {
        spotlight.ModifiedDate = DateTimeOffset.Now;
        UpdateModel(spotlight);

        spotlightRepository.Save();

        return RedirectToAction("Details", new { id = spotlight.SpotlightID });
    }
    catch
    {
        ModelState.AddRuleViolations(spotlight.GetRuleViolations());

        return View(new SpotlightFormViewModel(spotlight));
    }
}

Global.asax.cs:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    //Fires upon attempting to authenticate the use
    if (!(HttpContext.Current.User == null) &&
        HttpContext.Current.User.Identity.IsAuthenticated &&
        HttpContext.Current.User.Identity.GetType() == typeof(FormsIdentity))
    {
        HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
        FormsIdentity userIdentity = (FormsIdentity)HttpContext.Current.User.Identity;
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        String[] userRoles = authTicket.UserData.Split('|');
        HttpContext.Current.User = new GenericPrincipal(userIdentity, userRoles);
    }
}

AccountController.cs:

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        if (MembershipService.ValidateUser(model.UserName, model.Password))
        {
            //string accessLevel = userRepository.FindUserByCWID(model.UserName).AccessLevel.LevelName;
            string accessLevel = userRepository.FindUserByCWID(model.UserName).Roles;

            FormsAuthenticationTicket authTicket = new
                    FormsAuthenticationTicket(1, //version
                    model.UserName, // user name
                    DateTime.Now,             //creation
                    DateTime.Now.AddMinutes(30), //Expiration
                    model.RememberMe, //Persistent
                    accessLevel); // add roles?

            string encTicket = FormsAuthentication.Encrypt(authTicket);
            this.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));

            FormsService.SignIn(model.UserName, model.RememberMe);

            if (!String.IsNullOrEmpty(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
        else
        {
            ModelState.AddModelError("", "The user name or password provided is incorrect.");
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

Web.config:

<?xml version="1.0"?>

<configuration>
  <connectionStrings>
    <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
      providerName="System.Data.SqlClient" />
    <add name="devConnectionString" snip"
      providerName="System.Data.SqlClient" />
    <add name="ADConnectionString" connectionString="LDAP://my.domain/DC=my,DC=domain"/>
  </connectionStrings>

  <system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </assemblies>
    </compilation>

    <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="2880" />
    </authentication>

    <membership defaultProvider="MyADMembershipProvider">
      <providers>
        <clear/>
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
             enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
             applicationName="/" />
        <add name="MyADMembershipProvider"
             type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionStringName="ADConnectionString"
             attributeMapUsername="sAMAccountName" connectionProtection="Secure"
             enablePasswordReset="false" maxInvalidPasswordAttempts="1" passwordAttemptWindow="15" 
             passwordAnswerAttemptLockoutDuration="1" minRequiredNonalphanumericCharacters="0" attributeMapEmail="mail"
             />

      </providers>
    </membership>

    <profile>
      <providers>
        <clear/>
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
      </providers>
    </profile>

    <roleManager enabled="false" defaultProvider="MySqlRoleProvider">
      <providers>
        <clear/>
        <add name="MySqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="myApp" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
      </providers>
    </roleManager>

    <pages>
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
      </namespaces>
    </pages>
  </system.web>

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

【问题讨论】:

  • 在没有elses 的情况下,为什么你有if (condition1) { if (condition2) { ... 而不是if (condition1 &amp;&amp; condition2) { ...
  • 有效点。可读性我想,虽然我发现它是一个例子,但我没有写它
  • 就可读性而言,最好将它们组合成一个 IMO 条件。
  • 同意。至于其余的,有什么想法吗?即使使用调试器也很难可视化过去的属性。这可能是一件小而愚蠢的事情

标签: c# asp.net-mvc-2 forms-authentication


【解决方案1】:

由于某种原因没有使用 Cookie。在 web.config 中设置 cookieless="UseCookies" 一切正常:)

【讨论】:

    猜你喜欢
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    相关资源
    最近更新 更多