how to set up smart-card authorization in web form
i can read ATR of smart card...
try {
m_iCard.Connect( DropDownList1.SelectedItem.Text, SHARE.Shared, PROTOCOL.T0orT1);
try {
// Get the ATR of the card
byte[] atrValue = m_iCard.GetAttribute(SCARD_ATTR_VALUE.ATR_STRING);
} catch {
}
} catch {
}
But further from that no idea.
Do you have the authentication process in place? If not, you can access the link below, it has a tutorial for that:
http://securitythroughabsurdity.com/2007/04/implementing-smartcardauthenticationmod.html
Once the users were authenticated by the SM, you can authorize them:
http://securitythroughabsurdity.com/2007/04/implementing-authorization-in-aspnet.html
You can see on this link the full tutorial:
http://securitythroughabsurdity.com/2007/04/implementing-smartcard-authentication.html
Edited - it’s possible to implement authorization on the following forms:
Declarative
using System.Security.Permissions;
...
[PrincipalPermission(SecurityAction.Demand, Role="Administrator"),
PrincipalPermission(SecurityAction.Demand, Role="Auditors")]
public void DoSomethingImportant()
{
...
}
Imperative
using System.Security.Permissions;
...
public void DoSomethingImportant()
{
PrincipalPermission permCheck = new PrincipalPermission(Nothing, "Administrators");
permCheck.Demand();
}
IPrincipal.IsInRole() Check
if (myPrincipal.IsInRole("Administrators")
{
...
}
Web.Config - Specify access permissions to files and/or folders in the web.config
<configuration>
<system.web>
...
</system.web>
<location path="Admin">
<system.web>
<authorization>
<allow roles="Administrator" />
<deny users="*" />
</authorization>
</system.web>
</location>
<location path="Reports">
<system.web>
<authorization>
<allow roles="Auditor" />
<deny users="*" />
</authorization>
</system.web>
</location>
</configuration>
Related
I am encountering an infinite redirect loop between login.microsoftonline.com and my application. My project is implementing authentication and authorization in an Asp.net 4.8 web forms project. I am able to add authentication using the default Owin startup file and then require authentication in the web config file. The below works correctly for requiring a user to sign in before being able to access pages/AuthRequired
StartupAuth.CS
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
private static string authority = ConfigurationManager.AppSettings["ida:Authority"];
private static string clientSecret = ConfigurationManager.AppSettings["AppRegistrationSecret-Local"];
public void ConfigureAuth(IAppBuilder app)
{
//for debugging
//IdentityModelEventSource.ShowPII = true;
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
ClientSecret = clientSecret,
RedirectUri = postLogoutRedirectUri,
//This allows multitenant
//https://github.com/Azure-Samples/guidance-identity-management-for-multitenant-apps/blob/master/docs/03-authentication.md
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthenticationFailed = (context) =>
{
return Task.FromResult(0);
}
}
}
);
// This makes any middleware defined above this line run before the Authorization rule is applied in web.config
app.UseStageMarker(PipelineStage.Authenticate);
}
}
Web.Config
<configuration>
...
<system.web>
<authentication mode="None" />
</system.web>
<location path="Pages/AuthRequired">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
...
</configuration>
I need to add authorization so that only users with the admin role will be able to access Pages/AuthRequired. I have done that by updating the web config:
<configuration>
...
<system.web>
<authentication mode="None" />
</system.web>
<location path="Pages/AuthRequired">
<system.web>
<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>
</system.web>
</location>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
...
</configuration>
Adding authorization to the authenticated page works correctly if the user has that role, but if a user who doesn't have the role tries to access the page they are redirected back to login.microsoftonline.com and then back to the application in an infinite loop.
I can see that Owin UseOpenIdConnectAuthentication is returning a 302 response on unauthorized and that is causing the loop.
How can I change it so that instead of redirecting unauthorized (but authenticated) users to login.microsoftonline.com, that user should be directed to an app page that displays a 401 error?
Please check if below work around helps:
Its usually possible that if forms authentication is enabled, you will be redirected to the login page when status code is 401.
As a workaround try Adding the below to global.asax in the application end request and you can create own unauthorized page if needed and redirect to that.
if (this.Response.StatusCode == 302&& this.Response.StatusCode == 401
&& this.Response.RedirectLocation.ToLower().Contains("login.aspx"))
{
this.Response.StatusCode = 401;
//or Response.Redirect("Unauthorized.aspx");
}
You can also check this > Redirect unauthorised user to message page in ASP .Net. (microsoft.com)
Other references
Prevent redirect to login on status code 401 (Unauthorized)
(microsoft.com)
asp.net - In-place handling (no redirect) of 401 unauthorized? -
Stack Overflow
ASP.NET URL Authorization doesn't appear to interoperate well with OIDC (i.e. Azure AD).
First remove the URL Authorization from your Web.config:
<configuration>
...
<system.web>
<authentication mode="None" />
</system.web>
<location path="Pages/AuthRequired">
<system.web>
-- <authorization>
-- <allow roles="Admin" />
-- <deny users="*" />
-- </authorization>
</system.web>
</location>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
...
</configuration>
Optionally make authenticated required for all pages globally:
<system.web>
<deny users="?" />
</system.web>
You can override this behaviour with <Allow users="?" /> for specific pages i.e. logins/logouts/erorr pages/etc.
Second add authorization logic to your AuthRequired.aspx page:
public partial class AuthRequired {
protected void Page_Load(object sender, EventArgs e)
{
Authorization.AuthorizeAuthRequiredPage();
...
}
}
public static class Authorization
{
public static void AuthorizeAuthRequiredPage()
{
if (!Authorized(HttpContext.User))
{
Redirect("/Anauthorized.aspx");
}
}
private static bool Authorized(User user) => { ... }
}
I have a problem connecting from SITE A to SITE B on the same IIS Server.
SITE A acts as SPA (aspx) and consumes an API (web api) of SITE B, both on .net 4.6.1.
In my deployment env, they are both subdomains of the same domain living on the same V-Server.
If I'm on my dev environment it works with the following code:
protected async Task<HttpResponseMessage> Get(string urlParam = "")
{
string url = _url;
if (!string.IsNullOrWhiteSpace(urlParam))
{
url = $"{_url}?{urlParam}";
}
NetworkCredential credentials = null;
if (!string.IsNullOrEmpty(ServiceUser))
{
credentials = !string.IsNullOrEmpty(ServiceuserDomain)
? new NetworkCredential(ServiceUser, Servicepassword, ServiceuserDomain)
: new NetworkCredential(ServiceUser, Servicepassword);
}
using (var handler = new HttpClientHandler {Credentials = credentials})
{
using (var httpClient = new HttpClient(handler))
{
HttpResponseMessage responseMessage = null;
try
{
responseMessage = await httpClient.GetAsync(url);
}
...
I can also connect with that code to my deployed API (SITE B)
The web.config of SITE A has no "special" configurations. Anonymous Authentication is enabled and Windows Auth disabled.
The web.config of SITE B has the following "special" configuration:
<system.web>
<compilation debug="true" targetFramework="4.6.1" defaultLanguage="c#" />
<httpRuntime targetFramework="4.6.1" />
<customErrors mode="Off" />
<authentication mode="Windows"/>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
<location path="swagger">
<system.web>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
</system.web>
</location>
<location path="api">
<system.web>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
</system.web>
</location>
Which basically allows anonymous access to the site except for /api and /swagger.
If I test the API call to SITE B from POSTMAN using the new BETA Authentication NTLM it works aswell. The credential are definitly not wrong, but whenever I go throug the log files of SITE B I see:
2019-06-03 12:08:43 212.147.60.15 GET /api/form/ from=0&to=99/ 443 - IP HTTP/1.1 - - sub.domain.ch 401 0 0 2661 114 0
2019-06-03 12:08:43 212.147.60.15 GET /api/form/ from=0&to=99/ 443 - IP HTTP/1.1 - - sub.domain.ch 401 1 3221225581 6661 773 0
Also, both sub-domain on that server have the same IP address, but I don't think that's related.
Unfortunately in my case I cannot access the Windows Server. I just have a PLESK access to manage the domains / files.
I'm have a mvc app that use with form authentication security client and all the manage user's is made in server side with wcf protocol.
and in the server site I'm saving the user tocken in the sessoin
string token = Srv.ValidateUser(out isNewUser, model.UserName, model.Password, model.IdentityNumber);
if (!string.IsNullOrEmpty(token))
{
Session["Token"] = token;
}
with this token I Identifies in the services
and the user name in the form authentication
FormsAuthentication.SetAuthCookie(model.UserName, false);
and now I dont know how to force user change password after first login or after password expired.
My config is:
<system.web>
<sessionState mode="InProc" cookieless="true" timeout="20" />
<authentication mode="Forms">
<forms path="/" loginUrl="~/Account/Login" />
</authentication>
<authorization>
<allow users="*" />
<deny users="?" />
</authorization>
<identity impersonate="true" />
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthenticationModule" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
Can anyone help me?
In your Login post action, you can check LastPasswordChangedDate like so:
var currentUser = Membership.GetUser(model.Email);
if (currentUser != null)
{
if (currentUser.LastPasswordChangedDate == currentUser.CreationDate)
{
// User has not changed password since created.
return RedirectPermanent("Login/?userName=" + model.Email);
}
}
i am using windows authentication with my asp.net application
different users will have different access to parts of the website.
i would like to do something like this in the config file:
<appSettings>
<role1>
<user>agordon</user><user>jsmith</user>
</role1>
<role2><user>dtodd</user><user>kveel</user></role2>
</appSettings>
is this possible to do?
when authenticating i would then get the username like this:
string username = HttpContext.Current.User.Identity.Name.ToString();
and check if that user exists in the specific role
Use the <authorization> element:
<configuration>
<system.web>
<authorization>
<allow users="*" />
<deny users="?"/>
</authorization>
</system.web>
</configuration>
You can then modify that for particular parts of your site:
<location path="Pages/Administration">
<system.web>
<authorization>
<deny roles="*"/>
<allow roles="Admin" />
</authorization>
</system.web>
</location>
You can do this, but it's really not the best way.
The problem here is that appSettings are not controlled by the Web.Config schema, so you'll need to programatically enumerate appSettings in a horrible fashion:
if (configurationSettings.HasKey("Role1")) { ... }
else if (configurationSettings.HasKey("Role2")) { ... }
else if (configurationSettings.HasKey("Role3")) { ... }
//continue ad.nauseum; it's not fun - trust me!
I know it's not what you're asking, but If you're using normal ASP.Net webforms then it's a little it of a slog; in each page/control you need to find out the current user and then determine if that user has access and then redirect or continue.
If you use ASP.Net MVC, it's a lot cleaner as you do this with attributes.
Authorize(Roles = "Managers")]
public ActionResult CompanySecrets()
{
return View();
}
What the code there is doing, is saying If the user doesn't have the Managers role, don't give them access.
To provide an opposite example, here's a similar method using Web form (msdn example):
http://support.microsoft.com/kb/311495
I am having difficulties implementing a custom ASP.NET RoleProvider.
First off, let me show you the relevant settings in my web.config file:
<?xml version="1.0"?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
name="FormsAuthentication"
path="Default.aspx"
timeout="20"/>
</authentication>
<membership defaultProvider="MembershipProvider">
<providers>
<clear />
<add name="MembershipProvider"
type="CompanyName.Security.MembershipProvider" />
</providers>
</membership>
<roleManager defaultProvider="RoleProvider"
enabled="true">
<providers>
<clear />
<add name="RoleProvider"
type="CompanyName.Security.RoleProvider" />
</providers>
</roleManager>
</system.web>
<location path="Employees.aspx">
<system.web>
<authorization>
<deny users="?"/>
<allow roles="Employees"/>
</authorization>
</system.web>
</location>
</configuration>
Here's the code for the login button's event handler:
if (Membership.ValidateUser(tbxUsername.Text, tbxPassword.Text))
Response.Redirect("./Employees.aspx");
else
{
tbxUsername.Text = string.Empty;
tbxPassword.Text = string.Empty;
tbxUsername.Focus();
lblLogin.Visible = true;
}
Side Note based on FormsAuthentication.RedirectFromLoginPage() suggestion:
[It has been suggested that I use FormsAuthentication.RedirectFromLoginPage() instead of Response.Redirect(). Eventually, I'd like to redirect the user to a different page based on his/her role. I don't know how FormsAuthentication.RedirectFromLoginPage() would allow me to do this as it does not accept a redirection url as a parameter. In addition, it is my understanding that I could call FormsAuthentication.SetAuthCookie() prior to Response.Redirect() in order to create the authentication cookie that FormsAuthentication.RedirectFromLoginPage() creates. Please let me know if my thought process here is wrong.]
After stepping through the source, I can see that Membership.ValidateUser() is executing the ValidateUser() function of my custom MembershipProvider class. However, when a valid user logs in, and is redirected to Employees.aspx, the user is returned to Login.aspx**?ReturnUrl=%2fEmployees.aspx**. I assume that this is because although the user authenticates, s/he is failing authorization to the Employees.aspx resource.
With that assumption, I created breakpoints on every function in my custom RoleProvider class to see where things run amuck. Not one of them breaks execution when I debug. Most of the code in my RoleProvider throws NotYetImplementetExceptions, but I would still expect to hit the breakpoints (and would then implement those required functions). Here are two dumbed-down functions I have implemented:
public override string[] GetRolesForUser(string username)
{
return new string[1] {"Employees"};
}
public override bool IsUserInRole(string username, string roleName)
{
return true;
}
I assume that since the RoleProvider code never executes, that something must be wrong with my web.config.
I've searched for an answer to this for the past two days and have tried various changes without success. Does anyone see where I'm going wrong?
Thanks in advance!
After authenticating the user using Membership.ValidateUser, you should call FormsAuthentication.RedirectFromLoginPage rather than Response.Redirect to create the forms authentication ticket.
See the MSDN documentation for Membership.ValidateUser for an example.
EDIT
Or if you want to redirect to a specific page, call FormsAuthentication.SetAuthCookie to create the forms authentication ticket before calling Response.Redirect.
It redirects authenticated users to default.aspx
Actually it redirects back to the page that was originally requested, which is not necessarily default.aspx
EDIT 2
Also there is a problem with your configuration:
The path attribute should not point to a specific page (Default.aspx in your case), but the root directory of the site. The default is "/" because most browsers are case-sensitive and so won't send the cookie if there is a case mismatch.
<forms loginUrl="Login.aspx"
name="FormsAuthentication"
path="/"
timeout="20"/>
Check if user is in role:
If (Roles.IsUserInRole("Employees"))
{
}
or try if it works without role checking:
<allow users="*"/>
maybe helps configuration change:
<location path="Employees.aspx">
<system.web>
<authorization>
<allow roles="Employees"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
I changed the path value (see below) from "Default.aspx" to "/" and now the breakpoints in the custom RoleProvider are being hit!
Does not work:
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
name="FormsAuthentication"
path="Default.aspx"
timeout="20"/>
</authentication>
Works:
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
name="FormsAuthentication"
path="/"
timeout="20"/>
</authentication>