ITKeyword,专注技术干货聚合推荐

注册 | 登录

asp.net - umbraco public access error when authenticated

itPublisher 分享于

2020腾讯云10周年活动,优惠非常大!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1040

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

推荐:ASP.NET ERROR: Access is denied

前几天重装了电脑,之后原来运行得好好的网站就不能运行了,错误如下: Access is denied: '**************'. Description: An unhandled exception occurred du

up vote 4 down vote favorite I have an issue with public access in Umbraco 7. I use a custom membership provider to authenticate the users by my CRM database. I set a rule to let access to authenticated (front-end) users only and I used a custom role provider to define authenticated users have the visitors role. If they are not authenticated, they are redirected to the login page. When I debug the website the user has the role : I am authenticated and the role for the current user is the good one. But I am still redirected to the login page ! I don't understand. My role provider: public class CustomRoleProvider : Umbraco.Web.Security.Providers.MembersRoleProvider

{

const int SITE_ID = 6;

public override string ApplicationName

{

get

{

return "Site";

}

}

public override string[] GetAllRoles()

{

return new[] { Const.VISITORS_LABEL };

}

public override string[] GetRolesForUser(string username)

{

return new[] { Const.VISITORS_LABEL };

}

/// <summary>

///

/// </summary>

/// <param name="username"></param>

/// <param name="roleName"></param>

/// <returns></returns>

public override bool IsUserInRole(string username, string roleName)

{

//every user is a visitor

if(roleName == Const.VISITORS_LABEL)

{

return true;

}

else

{

return base.IsUserInRole(username, roleName);

}

}

public override string[] GetUsersInRole(string roleName)

{

if(roleName == Const.VISITORS_LABEL)

{

using (var db = new CRMEntities())

{

var usersEmails = db.Customer_View.Where(x => x.SiteID == SITE_ID).Select(x=>x.Email).ToArray();

return usersEmails;

}

}

else

{

return base.GetUsersInRole(roleName);

}

}

}

Here is the controller I use for authentication: public class MemberLoginSurfaceController : Umbraco.Web.Mvc.SurfaceController

{

// The MemberLogin Action returns the view, which we will create later. It also instantiates a new, empty model for our view:

[HttpGet]

[ActionName("MemberLogin")]

public ActionResult MemberLoginGet()

{

return PartialView("MemberLogin", new MemberLoginModel());

}

// The MemberLogout Action signs out the user and redirects to the site home page:

[HttpGet]

public ActionResult MemberLogout()

{

Session.Clear();

FormsAuthentication.SignOut();

return Redirect("/");

}

// The MemberLoginPost Action checks the entered credentials using the standard Asp Net membership provider and redirects the user to the same page. Either as logged in, or with a message set in the TempData dictionary:

[HttpPost]

[ActionName("MemberLogin")]

public ActionResult MemberLoginPost(MemberLoginModel model)

{

if (Membership.ValidateUser(model.Username, model.Password))

{

FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);

return RedirectToCurrentUmbracoPage();

}

else

{

TempData["Status"] = "Invalid username or password";

return RedirectToCurrentUmbracoPage();

}

}

}

My role provider is in the web.config and the Visitors role is detected as role in the administration panel. <roleManager enabled="true" defaultProvider="CustomRoleProvider">

<providers>

<clear />

<add name="UmbracoRoleProvider" type="Umbraco.Web.Security.Providers.MembersRoleProvider" />

<add name="CustomRoleProvider" type="*.UI.Helpers.CustomRoleProvider" />

</providers>

</roleManager>

EDIT: I forgot the membership provider :

public class MyMembershipProvider : Umbraco.Web.Security.Providers.MembersMembershipProvider

{

const int SITE_ID = 6;

//we dont let user change their password using RC website

public override bool AllowManuallyChangingPassword

{

get

{

return false;

}

}

public override bool EnablePasswordReset

{

get

{

return false;

}

}

public override bool EnablePasswordRetrieval

{

get

{

return false;

}

}

public override bool ValidateUser(string username, string password)

{

Customer_View user;

//just to avoid errors with uppercase letters

username = username.ToLowerInvariant();

using (var db = new CRMEntities())

{

user = db.Customer_View.SingleOrDefault(x => x.Email == username && x.SiteID == SITE_ID);

//no user with this email

if (user == null)

return false;

//check if password is same

return user.Password == password;

}

}

public override MembershipUser GetUser(string username, bool userIsOnline)

{

//just to avoid errors with uppercase letters

username = username.ToLowerInvariant();

MembershipUser toReturn;

using (var db = new CRMEntities())

{

Customer_View user = db.Customer_View.SingleOrDefault(x => x.Email == username && x.SiteID == SITE_ID);

toReturn = user != null ? new MembershipUser(

//provider name

"MyMembershipProvider", string.Format("{0} {1}", user.FirstName, user.LastName),

username, username, string.Empty, string.Empty, true, true, user.CreateDate, new DateTime(), new DateTime(), new DateTime(), new DateTime()) :

null;

}

return toReturn;

}

public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)

{

return this.GetUser(providerUserKey as string, userIsOnline);

}

}

Every time I try to access a page that has specific access I get redirected to the login page even if I am authenticated: How can I solve it ? asp.net authentication umbraco umbraco7 roleprovider
  |
  this question edited May 20 '15 at 14:32 asked May 11 '15 at 16:46 Giu 914 9 26      UmbracoContext.Security.CurrentUser returns null even if I am authenticated ! It's the right track. I will add the MemberLoginSurfaceController for more details. –  Giu May 12 '15 at 14:18      My bad. I wasn't clear, I want to let access to front-end authenticated users. UmbracoContext.Security.CurrentUser is for back-end users, right ? –  Giu May 12 '15 at 15:26      yes, its for backoffice users. Your controller seem to be alright. Take a look at what is returned from Umbraco.MemberIsLoggedOn() and Members.GetCurrentMember() - also at line 6 –  anikiforov May 12 '15 at 15:47      basically I think that your member is not authenticated. Please check the result of the above methods, and also check if the call to Membership.ValidateUser in your controller returns true –  anikiforov May 12 '15 at 15:55      My member is authenticated. Membership.ValidateUser returns true every time. I added another picture to show that the role for the current user is the good one. –  Giu May 12 '15 at 20:23  |  show 4 more comments 2 Answers

up vote 2 down vote ---Accepted---Accepted---Accepted---

+50 Why do you want to add custom role provider. Just keep it simple. If you have a registration page for the site you can assign member type and member role programmatically And if you add member from backend, you can add "Visitor" role easily. So in both cases "Visitor" role can be applied easily to all members and you can keep your page behind login for visitor role(all authenticated) easily. EDIT: I have removed the code of adding role to user programmatically as that is not needed by you and solution is as below: As you know for custom role provider and custom membership provider go hand in hand. You have added the custom membership provider and overrided ValidateUser method, but for all this to work you need to override two more methods of GetUser See the code for custom provider as below and it would work MemberShipProvider public class MyMembershipProvider : MembersMembershipProvider

{

public override bool ValidateUser(string username, string password)

{

if (base.ValidateUser(username,password))

{

//if this is umbraco user validate by base method

return true;

}

else

{

var allow = //add your validation code for CRM, I have checked if username is "tester" and allowed for testing purpose.

return allow;

}

}

// These two methods below which you have not overridden and need to override for public access to work

public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)

{

if(base.GetUser(providerUserKey, false)!=null)

//if this is umbraco user add it as is.

return base.GetUser(providerUserKey,userIsOnline);

else

//Add your CRM user, I do not have database, so added test user

return new MembershipUser("UmbracoMembershipProvider", "tester", 1233, "tester@test.com", null, null, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);

}

public override MembershipUser GetUser(string username, bool userIsOnline)

{

if (true)//check if this is CRM user here

{

return new MembershipUser("UmbracoMembershipProvider", "tester", 1233, "tester@test.com", null, null, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);

//I am adding test user, you should create user from your CRM database

}

else

return base.GetUser(username,false);

}

}

EDIT2 Okay, I have debugged every bit of code in roleprovider and membershipprovider, after the user is logged in when user tries to access protected page, first GetUser(string username, bool userIsOnline) gets called which, if failed, returns login page, after this is success GetUser(object providerUserKey, bool userIsOnline) gets a call. If this returns null, Insufficient access page is shown else GetRolesForUser(string username) gets called. and upon all success page is shown. I have set break point on each method of both files, so only these 3 methods are involved. as you see login page, my guess is Get

推荐:解决错误:ASP.NET Error: Failed to access IIS metabase

解决错误:ASP.NET Error: Failed to access IIS metabase 今天重新装了系统,然后重新安装了vs2005,突然记起忘记安装iis了。并且出现了如下错误 //以下是错误信

User(string username, bool userIsOnline) this first call is failing somewhere. Below are my files if it helps roles config part <roleManager enabled="true" defaultProvider="UmbracoRoleProvider">

<providers>

<clear />

<!--<add name="UmbracoRoleProvider" type="Umbraco.Web.Security.Providers.MembersRoleProvider" />-->

<add name="UmbracoRoleProvider" type="Assembly.Providers.MyRolesProvider" />

</providers>

</roleManager>

membership config part <membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">

<providers>

<clear />

<add name="UmbracoMembershipProvider" type="Assembly.Providers.MyMemberShipProvider, Assembly" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswers
="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" />

<!--<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswers
="false" passwordFormat="Hashed" />-->

<add name="UsersMembershipProvider" type="Assembly.Providers.MyUserMembershipProvider, Assembly" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswers
="false" passwordFormat="Hashed" />

</providers>

</membership>

AccountController public class AccountSurfaceController : Umbraco.Web.Mvc.SurfaceController

{

[HttpPost]

public ActionResult LoginForm(LoginModel model)

{

//model not valid, do not save, but return current umbraco page

if (!ModelState.IsValid)

{

//Perhaps you might want to add a custom message to the TempData or ViewBag

//which will be available on the View when it renders (since we're not

//redirecting)

return CurrentUmbracoPage();

}

// Login

if (Membership.ValidateUser(model.Username, model.Password))

{

FormsAuthentication.SetAuthCookie(model.Username, false);

return RedirectToCurrentUmbracoUrl();

}

else

{

ModelState.AddModelError("Username", "Username is not valid");

return CurrentUmbracoPage();

}

}

}

public class LoginModel

{

[Required]

public string Username { get; set; }

[Required]

[DataType(DataType.Password)]

public string Password { get; set; }

}

RolesProvider public class MyRolesProvider : MembersRoleProvider

{

const string VISITORS_LABEL = "Visitor";

public override string[] GetAllRoles()

{

var roles = base.GetAllRoles().ToList();

roles.Add(VISITORS_LABEL);

return roles.ToArray();

}

public override string[] FindUsersInRole(string roleName, string usernameToMatch)

{

if(roleName== VISITORS_LABEL)

{

var users = ApplicationContext.Current.Services.MemberService

.GetAllMembers().Select(m => m.Email).ToList();

users.Add("tester@test.com");

return users.ToArray();

}

return base.FindUsersInRole(roleName, usernameToMatch);

}

public override bool RoleExists(string roleName)

{

if(roleName == VISITORS_LABEL)

{

return true;

}

return base.RoleExists(roleName);

}

public override string[] GetRolesForUser(string username)

{

var roles = base.GetRolesForUser(username).ToList();

roles.Add(VISITORS_LABEL);

return roles.ToArray();

}

public override bool IsUserInRole(string username, string roleName)

{

if(roleName == VISITORS_LABEL)

{

return true;

}

return base.IsUserInRole(username, roleName);

}

public override string[] GetUsersInRole(string roleName)

{

if(roleName == VISITORS_LABEL)

{

var list = ApplicationContext.Current.Services.MemberService

.GetAllMembers().Select(m => m.Email).ToList();

list.Add("tester@test.com");

return list.ToArray();

}

return base.GetUsersInRole(roleName);

}

}

EDIT3: I reproduced your scenario, it is related to web.config configuration when I kept web config for membership as below it did not hit my provider unless i called <membership defaultProvider="MyMembershipProvider" userIsOnlineTimeWindow="15">

<providers>

<clear />

<add name="UmbracoMembershipProvider" type="Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswers
="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" />

<add name="MyMembershipProvider" type="Umbraco724.Providers.MyMembersMembershipProvider, Umbraco724" />

<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswers
="false" passwordFormat="Hashed" />

</providers>

</membership>

But when changed it to as given below it worked. please check the difference in config carefully. <membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">

<providers>

<clear />

<add name="UmbracoMembershipProvider" type="Umbraco724.Providers.MyMembersMembershipProvider, Umbraco724"

minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswers
="false" defaultMemberTypeAlias="Visitor" passwordFormat="Hashed" />

<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswers
="false" passwordFormat="Hashed" />

</providers>

</membership>

I think umbraco only takes one provider for members as well as users. Also when its name should be UmbracoMembershipProvider only. when I kept that different then also there was error.
  |
  this answer edited May 22 '15 at 12:30 answered May 19 '15 at 13:15 Chaitanya Gadkari 1,296 1 11 30 1   I have to use a custom membership provider to access our CRM database and I don't want to duplicate data and save them in the umbraco database. The custom role provider is mandatory with the custom membership provider. –  Giu May 19 '15 at 13:55 1   @GiuDo: you are right, I created a role provider and reproduced the issue. If that custom role is applied to the member from umbraco backend, it works fine, the the user is also from other source, it redirects to login. I'll update you if I find out the missing link. –  Chaitanya Gadkari May 20 '15 at 6:12 1   From my debugging GetUser(string username, bool userIsOnline) is where you have problem.. see my all files if it helps, updated answer –  Chaitanya Gadkari May 21 '15 at 6:37 1   updated answer. –  Chaitanya Gadkari May 22 '15 at 12:32 1   Yes, i was also thinking same –  Chaitanya Gadkari May 22 '15 at 14:16  |  show 13 more comments up vote 0 down vote With Umbraco's public access, when a user is logged out and they try to access a protected page they'll be presented with the login page. However, the URL in their address bar will be that of the page that they tried to access. Upon validating the user RedirectToCurrentUmbracoPage() will actually perform a full redirect to the login page and the URL in the address bar will update accordingly. What you actually want to do is to redirect them to the current URL. You can do this by replacing the first RedirectToCurrentUmbracoPage() in your MemberLoginPost method with RedirectToCurrentUmbracoUrl(). You're also using RedirectToCurrentUmbracoPage() for when the user's credentials are incorrect, which will also cause a full redirect to the login page. If you simply return the CurrentUmbracoPage() to the user then everything should work properly. See the updated method below: [HttpPost]

[ActionName("MemberLogin")]

public ActionResult MemberLoginPost(MemberLoginModel model)

{

if (Membership.ValidateUser(model.Username, model.Password))

{

FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);

return RedirectToCurrentUmbracoUrl();

}

else

{

TempData["Status"] = "Invalid username or password";

return CurrentUmbracoPage();

}

}


  |
  this answer answered May 17 '15 at 13:48 Rob Purcell 1,110 1 5 15      I tried with these functions but it has no effect, I added a screenshot of the login page for more details. I don't think the login page redirection is related to this issue, even when I manually type the url (as authenticated user) the content of my page is the login page. –  Giu May 19 '15 at 14:08



 | 

推荐:Redirecting to custom 401 page when "Access denied" occures within an ASP.NET application with Windows authentication

If you have an ASP.NET application with authentication mode set to Windows: <authentication mode="Windows"/><authorization><deny users="" /></

up vote 4 down vote favorite I have an issue with public access in Umbraco 7. I use a custom membership provider to authenticate the users by my CRM database. I set a rule to let a

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。