I have a ASP .NET MVC5 application in which I am not using Windows Authentication.
Everything was working fine until I tried running the application outside of the Domain in which it was being developed and (for whatever reason) got a:
The trust relationship between this workstation and the primary domain failed.
when I'm trying to do User.IsInRole("Admin").
I am using custom Identity, Role, IdentityStore, RoleStore, etc. from .NET's Identity and I can see that the User and Role data is being retrieved from the (MongoDB) database correctly.
There are plenty of questions regarding this issue, but they're from people who want to use Windows Auth. and impersonation in their MVC applications:
With windows authentication, The trust relationship between the primary domain and the trusted domain failed, when calling IsInRole
How to configure Windows Authentication / Impersonation + IIS 7 + MVC
The trust relationship between the primary domain and the trusted domain failed
My.User.IsInRole("Role Name") throws a Trust Relationship error on Windows 7
So why exactly am I getting this SystemException if I'm not using Active Directory and (as far as I know) not doing anything that might depend on the PC's domain? Am I missing some configuration (either in my Web.config or IIS Express)?
EDIT:
Ok, so narrowing it down a bit...
My User.IsInRole("Admin") line is inside an if() statement in my _Layout.cshtml View (i.e., to know what to show in the nav. bar depending on the role).
I now know I only get the error above when no user is authenticated and I'm not in the domain I used for dev. If I place a breakpoint on that line, I can see that the User object is is a System.Security.Principal.WindowsIdentity and its underlying Identity is System.Security.Principal.WindowsIdentity.
On the other hand, if the user is authenticated, then the User object and ts Identity are System.Security.Claims.ClaimsPrincipal and System.Security.Claims.ClaimsIdentity.
Why is it using Windows Identity at all (when unauthenticated) and how can I disable it?
So, based on my EDIT, I've modified my _Layout.cshtml so that instead of having
#if(User.IsInRole("Admin")) {...}
I have
#if(User.Identity.IsAuthenticated && User.IsInRole("Admin")) {...}
which seems to solve the problem.
I believe the problem was that ASP .NET Identity uses an empty WindowsIdentity when no user is authenticated and when I try to check for the User.IsInRole, then it will try to check the roles of a WindowsIdentity against an Active Directory that I don't have. Obviously I should first check if the user is even logged in before attempting to check its roles, so mea culpa.
But, even though the change above seems to fix my code, I'd be very interested in knowing more about this behavior: why is it using an empty System.Security.Principal.WindowsIdentity when no user is authenticated. I'll accept any answer which explains that.
I've had this issue - It failed for me if I tested an active directory group that didn't exist.
Make sure you're using a group that exists!
I was having this issue with Asp.Net Core 3.1 with Windows Authentication, but this thread came up first when searching the internet. I ended up resolving the issue by decorating the controller class declaration with the following:
using Microsoft.AspNetCore.Authorization;
[Authorize]
public class SetupController : Controller
Hope this is helpful for someone that is using Windows Authentication and is having the same error.
We were having this same issue on a new production server. Using the Identity Framework and restricting access to a specific directory with a web.config file denying any unauthenticated users. When unauthenticated users tried to access a page in this directory that contained any User.IsInRole("RoleName") code, they were getting the "Trust relationship..." error.
None of the fixes mentioned in other SO answers worked for us.
Turns out we just had to enable Forms Authentication in IIS - problem solved.
The "trust relationship between the primary domain and the workstation has failed" error message usaully requires that the computer be removed from the domain and then rejoined. Now there are a few ways to do this. As included in the link above, are instructions on how to do so either on the computer displaying the error or remotely. You can also do so in Active Directory and in PowerShell.
<authorization>
<allow roles="pri\Domain Users" users="pri\domain_user" />
<deny users="?" />
</authorization>
make sure that you have the above line in your web.config file and complete the user field with the correct user name.
I've just resolved this in our systems, unfortunately, none of the other suggestions worked for me. The issue was caused by an orphaned SID in a network folder the code was attempting to access. Once removed it started working again.
I had exactly the same scenario with custom Authentication Module and the same error when doing IsInRole. The highest ranking solution (User.Identity.IsAuthenticated && ...) did NOT help. So, I played quite a bit with it. Finally I found that I had to remove a (preCondition="managedHandler") attribute from my module declaration in web.config file. So, instead of:
<system.webServer>
...
<modules>
...
<add name="CompanyAuthentication" type="Company.Authentication.AuthHttpHandler" preCondition="managedHandler" />
</modules>
I would have to have:
<system.webServer>
...
<modules>
...
<add name="CompanyAuthentication" type="Company.Authentication.AuthHttpHandler" />
</modules>
That did the trick for me!
For me, the whole membership provider configuration tags were missing. After i copy those from one our previous apps, it worked fine.
<system.web>
<authentication mode="Windows" />
<compilation debug="true" targetFramework="4.7.1" />
<httpRuntime targetFramework="4.7.1" />
<httpModules>
<add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
</httpModules>
<profile defaultProvider="DefaultProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<roleManager defaultProvider="CustomRoleProvider" enabled="true" cacheRolesInCookie="false">
<providers>
<add name="CustomRoleProvider" type="ABC.ABCModels.ABCRoleProvider" />
</providers>
</roleManager>
<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>
On my case, I am not using User.Identity but rather Thread.CurrentPrincipal.Identity.Name
So when I approach this line of code:
Thread.CurrentPrincipal.IsInRole("admin");
That's where I will encounter the same error message of:
The trust relationship between this workstation and the primary domain failed.
There are two cases why I encountered the same issue and of course the fixes I made:
I was disconnected with my VPN. This will look for the role that doesn't exist since I am not connected with my VPN and not connecting with my AD accounts.
If I am connected with my VPN and the role admin doesn't exist based on my code above, it will certainly trigger the same error message.
I think it is worth sharing how I've fixed on my situation as these answers helped me to figure it out.
We were allowing/restricting access to pages via web.config and this was happening before touching any code (so it didn't matter where the breakpoint was, the error was coming).
Since this was not amazing too, I've decided to implement this validation in the code manually instead of using the web.config one.
our web.config used to look like this:
<configuration>
<system.web>
<authorization>
<allow roles="10,5"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration>
We've changed to:
Created a page (called restricted page) that inherits from Page
This page has a protected variable called RequiredAccessLevel
The OnLoad of the page we check if the user is in the role of the RequiredAccessLevel and if it is not, we redirect to a custom AccessDenied page
Made the pages that should have this restriction inherit from RestrictedPage instead of Page
On the constructor of the pages that are inheriting from RestrictedPage we set the access level necessary
Like this:
RestrictedPage.cs
public class RestrictedPage : Page
{
protected int[] RequiredAccessLevel { get; set; } = { };
protected override void OnLoad(EventArgs e)
{
if (RequiredAccessLevel.Length > 0)
{
var allowed = false;
foreach (var ral in RequiredAccessLevel)
{
if (Page.User.IsInRole(ral.ToString()))
{
allowed = true;
break;
}
}
if (!allowed)
{
Response.Redirect("~/AccessDenied.aspx");
}
}
base.OnLoad(e);
}
}
Example.cs
public partial class Example: RestrictedPage
{
public Example()
{
RequiredAccessLevel = new[] {10};
}
}
I would like to use mvc4 Simple membership provider. So I set up a new MVC4 internet application. Click Debug and I see that db and tables were created for me.
Is this all I need to do?.
Some articles:
http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx
http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/
tell me to add
<membership defaultProvider >...
section. is this necessary?
Also:
I can't get ASP.Net configuration tool to work. It says "An error was encountered. Please return to the previous page and try again. "
??
If you created a new MVC 4 web application using the Internet template it should have wired up SimpleMembership for a basic log-on/log-off functionality. It should have already updated your web.config with the proper settings. It should have setup the membership and roles and they should looks something like this.
<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>
SimpleMembership does not use the ASP.NET Configuration Tool used with the traditional ASP.NET membership. You have to create your own web pages for managing roles and users.
The Internet template just creates the basic functionality for authentication and authorization in your application. But SimpleMembership is very extensible. For example it is fairly easy to customize what type of information you want to capture in the user profile or setup email confirmation of new users.
In an ASP.NET website it is possible with a few short additions to the Web.Config section to add auto-magically wired properties to the user profile.
So for example with some XML like this.
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
<properties>
<add name="Name" allowAnonymous="true"/>
<add name="VisitedOn" type="System.DateTime" allowAnonymous="true"/>
</properties>
</profile>
You would end up with the ability to do this. Without having to declare any further code.
Profile.Name = "Some Test Value";
Profile.VisitedOn = DateTime.Now;
Profile.Save();
I have attempted to duplicate this functionality in an ASP.NET Web App and can't even seem to find the base Profile declaration let alone the custom properties.
I have however found that System.Web.Profile.DefaultProfile.Properties does infact contain the custom declared properties I define in the Web.Config.
So where might I be going wrong? What is the process for getting auto wired properties in web apps working?
The properties are created during the Compilation of ASP.NET Web Application when the first request arrives.
Ref: ASP.NET Application Life Cycle Overview for IIS 5.0 and 6.0
Profile properties defined in the Web.config file If profile
properties are defined in the application's Web.config file, an
assembly is generated that contains a profile object.
You can hook into this Compilation by writing a custom BuildProvider and registering the same. This build provider can be used for generating the auto wired properties.
Very simple question actually:
I currently have IIS anonymous access disabled, users are automatically logged on using their Windows login. However calling User.IsInRole("Role name") returns false. I double-checked User.Identity.Name() and the "Role name" and it should return true.
I currently have this in my Web.Config:
UPDATE
I was calling User.IsInRole("Role name") where I should call User.IsInRole("DOMAIN\Role name")
However I still like to know if the <membership> entry is needed at all?
What should I change? (and is the <membership> entry needed at all?)
<authentication mode="Windows">
<forms
name=".ADAuthCookie"
timeout="10" />
</authentication>
<membership defaultProvider="ADMembershipProvider">
<providers>
<clear/>
<add
name="ADMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
connectionUsername="XXX\specialAdUser"
connectionPassword="xx"
/>
</providers>
</membership>
<roleManager enabled="true" defaultProvider="WindowsProvider">
<providers>
<clear />
<add name="WindowsProvider" type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
If you use Windows authentication IsInRole will work with no extra configuration, as long as you remember to prefix the role with the domain, i.e. DOMAIN\groupName.
In addition you can role (pun intended) your own and use Windows auth against, for example, a SQL Role Provider, where you don't want your AD littered with custom roles for your application.
So no, you don't need the provider configuration at all.
The membership provider here isn't going to help. The ActiveDirectoryMembershipProvider seems to best(only?) fit with Forms authentication.
BlogEngine.NET has an Active Directory role provider.
Pretty sure the only thing you need in there is the roleManager group (along with the base authentication mode='windows' setting)
Out of the box, there's no role provider to use Active Directory directly. You can use the role table in the ASP.NET membership- and role-system, or you can use Authorization Manager (AzMan).
There's an article on CodeProject which shows the implementation of a role provider which works against the Active Directory - with full source code. Maybe this helps?
Marc
i'm a little confused while trying to find out how ActiveDirectory and ASP.NET Membership work... I've created a new MVC project and removed the AccountController / Views. I've changed the Web.Config so that it uses ActiveDirectory and automatically authenticates users based on their current Windows login:
Web.Config
<authentication mode="Windows">
<forms
name=".ADAuthCookie"
timeout="10" />
</authentication>
<membership defaultProvider="MyADMembershipProvider">
<providers>
<clear/>
<add
name="MyADMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
connectionUsername="MYDOMAIN\myuser"
connectionPassword="xxx"
/>
</providers>
</membership>
This works nicely, as I can do the following to get the users username like this:
User.Idenity.Name() 'Gives MYDOMAIN\myuser
Looking at the following, actually makes me confused:
Threading.Thread.CurrentPrincipal.Identity.Name() 'Gives MYDOMAIN\myuser
1. Shouldn't the thread identity be IUSR_WORKSTATION or ASPNET_WP username?
2. What's the difference between Authentication and Impersonation?
myuser is the Authenticated user on that application, that's why your CurrentPrincipal is giving you MYDOMAIN/myuser. The application impersonates IUSR_WORKSTATION when it uses resources like the database, and is a completely different issue.
If you go to Project on your toolbar, and select ASP.NET Configuration, it will open a website that lets you access these settings and create users, roles etc.