My login is..at controller
MemberShipProvider objMProvider = new MemberShipProvider();
var abc =RedirectToAction("Index", "Home");
if (ModelState.IsValid)
{
var checkVal = objMProvider.ValidateUser(m.username, m.password);
if (checkVal == true)
{
Session["User"] = m.username;
TempData["userName"] = m.username;
//IdentityHelper.RedirectToReturnUrl("~/User_Dashboard.aspx");
abc=RedirectToAction("Dashboard","User");
}
else if (checkVal == false)
{
abc = RedirectToAction("Index", "Home");
return abc;
}
}
my webconfig membership setting...
<system.web>
<membership defaultProvider="MemberShipProvider">
<providers>
<clear/>
<add name="MemberShipProvider" type="FndooMvc.Models.Common.MemberShipProvider"
connectionStringName="mycon"
applicationName="/" />
</providers>
</membership>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
my custom membership provider logincheck code is
public override bool ValidateUser(string username, string password)
{
return objLogin.IsValid(username,password) == true ? true : false;
}
i used flat login code then i decided to use custom membership as per demand. help me use this identity and principle feature with this custom membership
for now i want to know why my request.IsAuthenicated
have a look at this :
The ASP.NET Identity system is designed to replace the previous ASP.NET Membership and Simple Membership systems. It includes profile support, OAuth integration, works with OWIN, and is included with the ASP.NET templates shipped with Visual Studio 2013.
and if you want a good article in identity and principle feature
i needed this code block in global config in authenticate request event.
HttpCookie authCookie =Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket =
FormsAuthentication.Decrypt(authCookie.Value);
string[] roles = authTicket.UserData.Split(new Char[] { ',' });
GenericPrincipal userPrincipal =
new GenericPrincipal(new GenericIdentity(authTicket.Name),
roles);
Context.User = userPrincipal;
}
now request.isAuthenticated works.
how ever i am gonna change this provider and use as Hboubati suggested.
Related
This question already has answers here:
How to create asp.net web page with basic authentication
(1 answer)
Simplest way to add Basic authentication to web.config with user/pass
(1 answer)
Closed 2 years ago.
I want to implement a basic authentication in .net. So here i dont want an aspx page.
I only need web.config file and that should ask me for username and password( if i am not wrong we can have browser asking for username and password.)
Currently i have the below code which needs login.aspx page which i want to remove.
<?xml version="1.0"?>
<configuration>
<system.web>
<customErrors mode="Off"/>
<compilation debug="false" />
<authentication mode="Forms">
<forms>
<credentials passwordFormat="Clear">
<user name="abc" password="abc#123" />
</credentials>
</forms>
</authentication>
<!-- Unless specified in a sub-folder's Web.config file,
any user can access any resource in the site -->
<authorization>
<deny users="?" />
</authorization>
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthenticationModule" />
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
</modules>
</system.webServer>
</configuration>
This isn't done in your application.
This is done in IIS, where you enable basic authentication and disable anonymous authentication.
But if you insist on doing it in code, you can add a HTTP-module, where you can check for basic authentication yourselfs.
E.g.
class SurroundingClass
{
public void ProcessRequest(HttpContext context)
{
if (!Authenticate(context))
{
context.Response.Status = "401 Unauthorized";
context.Response.StatusCode = 401;
context.Response.AddHeader("WWW-Authenticate", "Basic");
// // context.CompleteRequest();
context.Response.Flush();
context.Response.End();
return;
}
} // ProcessRequest
private static string[] ParseAuthHeader(string authHeader)
{
// Check if this is a Basic Auth header
if (authHeader == null || authHeader.Length == 0 || !authHeader.StartsWith("Basic"))
return null;
// Pull out the Credentials with are seperated by ':' and Base64 encoded
string base64Credentials = authHeader.Substring(6);
string[] credentials = System.Text.Encoding.ASCII.GetString(System.Convert.FromBase64String(base64Credentials)).Split(':');
if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[0]))
return null;
return credentials;
} // ParseAuthHeader
private static bool TryGetPrincipal(string[] creds, ref System.Security.Principal.IPrincipal principal)
{
if (creds[0] == "Administrator" && creds[1] == "SecurePassword")
{
principal = new System.Security.Principal.GenericPrincipal(new System.Security.Principal.GenericIdentity("Administrator"), new string[] { "Administrator", "User" });
return true;
}
else if (creds[0] == "JoeBlogs" && creds[1] == "Password")
{
principal = new System.Security.Principal.GenericPrincipal(new System.Security.Principal.GenericIdentity("JoeBlogs"), new string[] { "User" });
return true;
}
else if (!string.IsNullOrEmpty(creds[0]) && !string.IsNullOrEmpty(creds[1]))
{
// GenericPrincipal(GenericIdentity identity, string[] Roles)
principal = new System.Security.Principal.GenericPrincipal(new System.Security.Principal.GenericIdentity(creds[0]), new string[] { "Administrator", "User" });
return true;
}
else
principal = null;
return false;
} // TryGetPrincipal
// http://blogs.msdn.com/b/odatateam/archive/2010/07/21/odata-and-authentication-part-6-custom-basic-authentication.aspx
public static bool Authenticate(HttpContext context)
{
// DANGER: On the developer system, we need to be able to test it without SSL certificate
// If Not context.Request.IsSecureConnection Then
// Return False
// End If
string authHeader = context.Request.Headers["Authorization"];
if (string.IsNullOrEmpty(authHeader))
return false;
string[] credentials = ParseAuthHeader(authHeader);
System.Console.WriteLine(credentials);
System.Security.Principal.IPrincipal principal = null;
if (TryGetPrincipal(credentials, ref principal))
{
HttpContext.Current.User = principal;
return true;
}
return false;
} // Authenticate
}
I have a WebForms application that uses Active Directory for authentication. The entire company should be able to access the application (and they can), but there are several forms in a "Mgr" folder that should only be accessed by AD group "ta_admins". I have read several threads on SO, but I can't seem to get anything to work.
I created a Web.config file inside the "Mgr" folder and tried the following:
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow roles = "ta_admins" />
<deny users = "*" />
</authorization>
</system.web>
</configuration>
I have tried changing "
Method is only supported if the user name parameter matches the user name in the current Windows Identity.
I am a member of ta_admins.
Here is part of the application's Web.config:
<system.web>
<authorization>
<deny users="?" />
</authorization>
<authentication mode="Windows" />
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
<providers>
<clear />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
..............
</system.web>
The aspx page has a grid that is populated with the members of a specific AD group. This works just fine when I'm not attempting to control the user group that can access the "Mgr" folder. The code behind is below (not sure if it's needed, but just-in-case...):
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[5]
{
new DataColumn("givenName", typeof (string)),
new DataColumn("sn", typeof (string)),
new DataColumn("mail", typeof (string)),
new DataColumn("department", typeof (string)),
new DataColumn("manager", typeof (string))
});
using (var context = new PrincipalContext(ContextType.Domain, null))
{
using (var group = (GroupPrincipal.FindByIdentity(context, "reps")))
{
var users = group.GetMembers(true);
foreach (UserPrincipal user in users)
{
DirectoryEntry de = user.GetUnderlyingObject() as DirectoryEntry;
dt.Rows.Add
(
Convert.ToString(de.Properties["givenName"].Value),
Convert.ToString(de.Properties["sn"].Value),
Convert.ToString(de.Properties["mail"].Value),
Convert.ToString(de.Properties["department"].Value),
Regex.Replace((Convert.ToString(de.Properties["manager"].Value)), #"CN=([^,]*),.*$", "$1")
);
}
rgAdUsrs.DataSource = dt;
rgAdUsrs.DataBind();
}
}
}
Please let me know if additional information is required.
Well I found and different way to get this done. I just get a list of all groups the user is in and base form access on that.
PrincipalSearchResult<Principal> groups = UserPrincipal.Current.GetGroups();
IEnumerable<string> groupNames = groups.Select(x => x.SamAccountName);
if (!groupNames.Contains("ta_admins"))
{
Response.Redirect("~/AccessDenied.aspx");
}
}
Then I disabled directoryBrowse in the web.config of the folder.
I have https website and I am using membership for logins and
my code in controller:
int timeout = rememberme ? 2880 : 2; // Timeout in minutes,525600 = 365 days
var ticket = new FormsAuthenticationTicket(username, rememberme, timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = DateTime.Now.AddMinutes(timeout);//My Line
Response.Cookies.Add(cookie);
string returnurl = FormsAuthentication.GetRedirectUrl(username, rememberme);
if (string.IsNullOrEmpty(returnurl)) returnurl = "/Panel/Login";
if (string.IsNullOrEmpty(returnurl)) returnurl = "/Panel/Login";
if (rol == "User")
return Redirect("/Panel/Dashboard");
else if (rol == "Admin")
return Redirect("/Panel/DashboardAdmin");
return View();
and in we.config:
<httpRuntime targetFramework="4.6.2" executionTimeout="100000000" maxRequestLength="2147483647" />
<authentication mode="Forms">
<forms loginUrl="~/Panel/Login" requireSSL="true" slidingExpiration="true" />
</authentication>
<httpCookies httpOnlyCookies="true" requireSSL="true" />
so its just keep login for 2 minutes and remember me is not working
what should I do?
we should add this to system.web in web.config file
an U can generate this key in iis but if U can access to iis U can use this code
<machineKey
decryptionKey="1513F567EE75F7FB5AC0AC4D79E1D9F25430E3E2F1BCDD3370BCFC4EFC97A541"
validationKey="32CBA563F26041EE5B5FE9581076C40618DCC1218F5F447634EDE8624508A129"
decryption="AES"
validation="SHA1"
/>
I need to protect my web api with one or more specific users from the active directory, in the web.config I have the following code:
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="users" type="System.Configuration.NameValueFileSectionHandler,System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<users>
<add key="user" value="domain\loginname" />
</users>
<system.web>
<authentication mode="Windows" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
Then I have a custom authorize attribute which reads the user from the web.config section shown above.
public class MyAuthorizeAttribute : AuthorizeAttribute
{
public MyAuthorizeAttribute(params string[] userKeys)
{
List<string> users = new List<string>(userKeys.Length);
var allUsers = (NameValueCollection)ConfigurationManager.GetSection("users");
foreach (var userKey in userKeys)
{
users.Add(allUsers[userKey]);
}
this.Users = string.Join(",", users);
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool isAuthorized = base.AuthorizeCore(httpContext);
bool isRequestHeaderOk = false;
return isAuthorized && isRequestHeaderOk;
}
}
The problem is that the Authorize Core is never hit in the debugger, the JSON in the browser is always shown even if I put a hardcoded false , the breakpoint is never hit there.
Then I decorate my controllers with the custom authorize attribute
[MyAuthorize("user")]
[ResponseType(typeof(tblCargo))]
public IHttpActionResult GettblCargosByActivo()
{
var query = from c in db.tblCargos
orderby c.strCargo
select c;
//var result = Newtonsoft.Json.JsonConvert.SerializeObject(query);
//return result;
return Ok(query);
}
And in IIS, the only enabled method is Windows Authentication
when I browse to the site from another computer, then I get the authentication window, but the authoze method shown above is never hit.
THis is a nice post that lead me to the right direction (I believe)
Custom Authorization in Asp.net WebApi - what a mess?
You should use AuthorizeAttribute in System.Web.Http instead of System.Web.Mvc
Implement IsAuthorized instead.
protected override bool IsAuthorized(HttpActionContext actionContext)
{
bool isAuthorized = base.IsAuthorized(actionContext);
bool isRequestHeaderOk = false;
return isAuthorized && isRequestHeaderOk;
}
In my case, while refactoring, my controller class was no longer extending ApiController. This was necessary for my filter to fire.
I have an asp.net web app that uses forms-based authentication, a SqlMembershipProvider (using an encrypted password format), and a SqlRoleProvider. I need to know if it's possible to administer the users (create new users, assign them to roles, etc.) from a windows application - the powers that be don't want any administrative functionality in the web app itself.
Here is the membership provider definition from web.config:
<membership defaultProvider="MyProvider">
<providers>
<add name="MyProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="MyConnectionString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/MyWebApp"
requiresUniqueEmail="true"
passwordFormat="Encrypted"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""/>
</providers>
</membership>
And the role manager definition:
<roleManager enabled="true" defaultProvider="MyRoleManager">
<providers>
<add name="MyRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="MyConnectionString"
applicationName="/MyWebApp" />
</providers>
</roleManager>
And here is the machineKey definition (necessary to be able to use encrypted passwords):
<machineKey
validationKey="BC50A82A6AF6A015C34C7946D29B817C00F04D2AB10BC2128D1E2433D0E365E426E57337CECAE9A0681A2C736B9779B42F75D60F09F142C60E9E0E8F9840DB46"
decryptionKey="122035576C5476DCD8F3611954C837CDA5FE33BCDBBF23F7"
validation="SHA1"
decryption="AES"/>
So, obviously, I have a Sql Server database that contains the users and roles for the web app. I'd like to create a separate windows app that references the web app assembly, and use the configured MembershipProvider, RoleProvider, and machineKey to create users, assign users to roles, etc. If that's not possible, I can duplicate the configuration settings from web.config within the windows app. But I don't know how to do this either.
Am I way out of line thinking that this is possible? I've tried googling for a solution, but the signal-to-noise ratio is really bad.
Some options:
You could use the Web Site
Administration Tool, which isn't
Windows-Forms-based, but isn't part
of your Web app, either. It comes
with Visual Studio and can be
accessed by clicking the ASP.NET
Configuration icon in the Solution
Explorer.
It's possible to directly manipulate
the provider database used by a
SqlMembershipProvider from a Windows
Forms app, but you might have to be
careful not to break things.
If you were to create a custom
membership provider, you'd be in
control of how membership and role
data is persisted. If you did that
you could create a reusable library
that could be used in the Web app and
a Windows Forms app, too.
I don't think trying to use a SqlMembershipProvider from a Windows Forms app is a practical approach.
I've come up with a solution, based on the other answers (who both got +1), and some other sites out there.
First, I created Application Config file (app.config). It mirrors exactly what is found in web.config from the web app, with the exception of how the connection string was handled:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="MyConnectionString"
connectionString ="SERVER=abc;UID=def;PWD=hij;Initial Catalog=klm;MultipleActiveResultsets=True"/>
</connectionStrings>
<system.web>
<membership defaultProvider="MySqlMembershipProvider">
<providers>
<add name="MySqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="MyConnectionString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/MyWebApp"
requiresUniqueEmail="true"
passwordFormat="Encrypted"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""/>
</providers>
</membership>
<roleManager enabled="true" defaultProvider="MySqlRoleManager">
<providers>
<add name="MySqlRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="MyConnectionString"
applicationName="/MyWebApp" />
</providers>
</roleManager>
<machineKey
validationKey="BC50A82A6AF6A015C34C7946D29B817C00F04D2AB10BC2128D1E2433D0E365E426E57337CECAE9A0681A2C736B9779B42F75D60F09F142C60E9E0E8F9840DB46"
decryptionKey="122035576C5476DCD8F3611954C837CDA5FE33BCDBBF23F7"
validation="SHA1"
decryption="AES"/>
</system.web>
</configuration>
Then I created a helper class that provides access to two singletons: a MembershipProvider and a RoleProvider. This turned out to be easier than I thought, once I knew how to do it:
using System.Configuration;
using System.Reflection;
using System.Web.Security;
namespace WebAdminViaWindows
{
internal static class Provider
{
private static readonly string assemblyFilePath = Assembly.GetExecutingAssembly().Location;
static Provider()
{
Membership = CreateMembershipProvider();
Role = CreateRoleProvider();
}
public static MembershipProvider Membership { get; private set; }
public static RoleProvider Role { get; private set; }
private static MembershipProvider CreateMembershipProvider()
{
var config = ConfigurationManager.OpenExeConfiguration(assemblyFilePath);
var systemWebGroup = config.SectionGroups["system.web"];
if (systemWebGroup == null)
{
throw new ConfigurationErrorsException("system.web group not found in configuration");
}
var membershipSection = systemWebGroup.Sections["membership"];
if (membershipSection == null)
{
throw new ConfigurationErrorsException("membership section not found in system.web group");
}
var defaultProviderProperty = membershipSection.ElementInformation.Properties["defaultProvider"];
if (defaultProviderProperty == null)
{
throw new ConfigurationErrorsException("defaultProvider property not found in membership section");
}
var defaultProviderName = defaultProviderProperty.Value as string;
if (defaultProviderName == null)
{
throw new ConfigurationErrorsException("defaultProvider property is not a string value");
}
var providersProperty = membershipSection.ElementInformation.Properties["providers"];
if (providersProperty == null)
{
throw new ConfigurationErrorsException("providers property not found in membership section");
}
var providerCollection = providersProperty.Value as ProviderSettingsCollection;
if (providerCollection == null)
{
throw new ConfigurationErrorsException("providers property is not an instance of ProviderSettingsCollection");
}
ProviderSettings membershipProviderSettings = null;
foreach (ProviderSettings providerSetting in providerCollection)
{
if (providerSetting.Name == defaultProviderName)
{
membershipProviderSettings = providerSetting;
}
}
if (membershipProviderSettings == null)
{
if (providerCollection.Count > 0)
{
membershipProviderSettings = providerCollection[0];
}
else
{
throw new ConfigurationErrorsException("No providers found in configuration");
}
}
var provider = new SqlMembershipProvider();
provider.Initialize("MySqlMembershipProvider", membershipProviderSettings.Parameters);
return provider;
}
private static RoleProvider CreateRoleProvider()
{
var config = ConfigurationManager.OpenExeConfiguration(assemblyFilePath);
var systemWebGroup = config.SectionGroups["system.web"];
if (systemWebGroup == null)
{
throw new ConfigurationErrorsException("system.web group not found in configuration");
}
var roleManagerSection = systemWebGroup.Sections["roleManager"];
if (roleManagerSection == null)
{
throw new ConfigurationErrorsException("roleManager section not found in system.web group");
}
var defaultProviderProperty = roleManagerSection.ElementInformation.Properties["defaultProvider"];
if (defaultProviderProperty == null)
{
throw new ConfigurationErrorsException("defaultProvider property not found in roleManager section");
}
var defaultProviderName = defaultProviderProperty.Value as string;
if (defaultProviderName == null)
{
throw new ConfigurationErrorsException("defaultProvider property is not a string value");
}
var providersProperty = roleManagerSection.ElementInformation.Properties["providers"];
if (providersProperty == null)
{
throw new ConfigurationErrorsException("providers property not found in roleManagerSection section");
}
var providerCollection = providersProperty.Value as ProviderSettingsCollection;
if (providerCollection == null)
{
throw new ConfigurationErrorsException("providers property is not an instance of ProviderSettingsCollection");
}
ProviderSettings roleProviderSettings = null;
foreach (ProviderSettings providerSetting in providerCollection)
{
if (providerSetting.Name == defaultProviderName)
{
roleProviderSettings = providerSetting;
}
}
if (roleProviderSettings == null)
{
if (providerCollection.Count > 0)
{
roleProviderSettings = providerCollection[0];
}
else
{
throw new ConfigurationErrorsException("No providers found in configuration");
}
}
var provider = new SqlRoleProvider();
provider.Initialize("MySqlRoleManager", roleProviderSettings.Parameters);
return provider;
}
}
}
At this point all that's needed is to access the Membership and Role properties of the Provider class. As an example, the following prints out the first 10 users and their roles:
int total;
foreach (MembershipUser user in Provider.Membership.GetAllUsers(0, 10, out total))
{
var sb = new StringBuilder();
sb.AppendLine(user.UserName);
foreach (var role in Provider.Role.GetRolesForUser(user.UserName))
{
sb.AppendLine("\t" + role);
}
Console.WriteLine(sb.ToString());
}
I'm not sure what "best-practice" would be here, but a simple way that should work is this.
Make a new windows app
Add an Application Config file
(app.config)
Copy the appropriate settings into
the app.config (settings from above
^)
Add a reference to System.Web
And copy the code from your web app
that uses the above settings to
connect to the database
That should do what you want.