In our asp.net intranet application we are using windows authentication to authenticate the users.
We have recently had a request to give the user a reason for why they cannot login. For example, tell the user they can't login because their password has expired vs they can't login because their account is locked out.
When an account is locked out or the password has expired, the user cannot log on to the application. IIS will deny the access and redirect the user to the Access Denied (401) page after 3 login attempts. As the username is not passed to web application when IIS authentication fails, we won’t be able to check if the account is locked out or the password has expired.
Any suggestions on how to get this information?
Are we going to have to move to Forms authentication with an AD provider?
The simple solution to this is to move to forms authentication. But being that I know you did not want to hear that and it is not allowed or a viable solution your next option is to:
Look into System.DirectoryServices
Below I'm just pasting some quick code you can play with. Notice how to determine if a user is locked out or not. This is vb.net but can be easily changed to C#.
Try
Dim dirEntry As DirectoryEntry
dirEntry = New DirectoryEntry("LDAP://yourDomainInfoHere/OU=Users,OU=YourDomain,OU=YourOU,OU=CORP,DC=YourDC,DC=com", "ExecuateAsUser", "Password")
Dim entries As DirectoryEntries = dirEntry.Children
' Set login name and full name.
Dim newUser As DirectoryEntry = entries.Add("CN=JONNY BOY", "User")
newUser.Properties("sAMAccountName").Add("jboy")
newUser.CommitChanges()
newUser.Invoke("SetPassword", "hi2343145gfdtgwdt")
Dim flags As Integer
flags = CInt(newUser.Properties("userAccountControl").Value)
'enable user below
newUser.Properties("userAccountControl").Value = flags And Not &H2
'disable user below
newUser.Properties("userAccountControl").Value = flags Or &H1
'lockout property
Dim l As Long
l = CType(newUser.Properties("lockoutTime").Value, Long)
If l <> 0 Then
'account is locked out
'so how do we unlock it?
'we unlock it by setting it to 0
newUser.Properties("lockoutTime").Value = 0
Else
'account is 0 it is NOT locked out
End If
newUser.CommitChanges()
Dim j As DirectoryEntry = entries.Find("CN=JONNY BOY", "User")
j.Properties("mail").Value = "jon#yahoo.com"
j.CommitChanges()
Catch ex As Exception
Throw ex
End Try
Related
I have a problem with webview2. I have WPF/vb.net app
First I can't make auto log in to the page.
Second, I tested it on remote computer and it doesn't work. It doesn't give errors, just empty field.
I appreciate any help
p.s.WebView2 Runtime is installed on both computers
front:
<wv2:WebView2 Name="webView2 " Source="pageName" CoreWebView2InitializationCompleted="zzz_CoreWebView2InitializationCompleted">
</wv2:WebView2>
back:
webView2 .EnsureCoreWebView2Async()
Private Sub webView2 _CoreWebView2InitializationCompleted(sender As Object, e As Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs)
Dim userName ="user"
Dim password = "password" webView2.CoreWebView2.ExecuteScriptAsync("document.getElementById(""signin_username"").InnerText='" & userName & "';")
p.s. for front I just deleted source and at the back I didn't wrote here the code for password and button, I think I will manage to do it if you can help me with just username.
I am currently working within Access 2013. I am building a database for a small group of people, in which the database will be in a shared folder (split database). The problem that I am having with the database is that, I can login successfully through the login screen, but when someone else tries to login they will get "Run-time error '3051': The Microsoft Jet database engine cannot open the file 'xxx.mdb'. It is already opened exclusively by another user, or you need permission to view its data". Also, when they bypass the login in screen by going to design view (a function only used for testing), they cannot open a table.
My code:
Option Compare Database
Option Explicit
Private Sub btnLogin_Click()
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("tblUser", dbOpenSnapshot, dbReadOnly)
rs.FindFirst "UserName='" & Me.txtUserName & "'"
If rs.NoMatch = True Then
Me.lblWrongUser.Visible = True
Me.txtUserName.SetFocus
Exit Sub
End If
Me.lblWrongUser.Visible = False
If rs!Password <> Nz(Me.txtPassword, "") Then
Me.lblWrongPass.Visible = True
Me.txtPassword.SetFocus
Exit Sub
End If
Me.lblWrongPass.Visible = False
DoCmd.OpenForm "frmPersonal Information"
DoCmd.Close acForm, Me.Name
End Sub
When running the debug it is showing that something is wrong with:
Set rs = CurrentDb.OpenRecordset("tblUser", dbOpenSnapshot, dbReadOnly)
Is there anything that I am doing wrong or do I need to split the database and turn the front end into a ACCDE file?
We recently upgraded from IIS 6 to IIS 7.5.
We moved all of our sites to the new system and they all worked aside from one.
The broken site gives information about out ftp servers, and after some experimenting we determined what code was causing the problem.
This is the line of code that asks the server for the expiration date of the FTP site:
Set objuser = objRoot.OpenDSObject("LDAP://CN="&user&",dc=companySite,OU=FTP", strUserDN, strPassword, ADS_SECURE_AUTHENTICATION)
This is the rest of the function for context:
function expiration(user)
Set con = Server.CreateObject("ADODB.Connection")
con.provider ="ADsDSOObject"
con.open "Active Directory Provider"
Set Com = CreateObject("ADODB.Command")
Set Com.ActiveConnection = con
Const ADS_SECURE_AUTHENTICATION = 1
strUserDN = "cn=ftplist,cn=users,dc=companySite,dc=com"
strPassword = "password"
Set objRoot = GetObject("LDAP:")
Set objuser = objRoot.OpenDSObject("LDAP://CN="&user&",dc=companySite,OU=FTP", strUserDN, strPassword, ADS_SECURE_AUTHENTICATION)
On error resume next
expiry = objuser.AccountExpirationDate
If expiry = "1/1/1970" Or expiry = "1/01/1601 10:00:00 AM" Or Err.Number = -2147467259 then
expiration = "No expiration"
else
expiration = formatdatetime(objuser.AccountExpirationDate, vbshortdate)
end if
response.write expiration
end function
The error the page displays is as follows:
Active Directory error '8007203b'
A local error has occurred.
/ftp-search.asp, line 28
I am unfamiliar with the database our company uses, so I cannot discern what caused the problem.
I did some research but have been unable to find a solution so far.
Any tips would be appreciated!
Your distinguished name seems to be off. The domain part should go after the organizational unit:
Set objuser = objRoot.OpenDSObject("LDAP://CN=" & user & _
",OU=FTP,dc=barghausen", strUserDN, strPassword, ADS_SECURE_AUTHENTICATION)
I have an Azure webrole that requires ACSv2 authentication that I want to access from a winforms application. Many of my clients use Windows XP so I can not use the WIF (which is not available on Windows XP). What is the best way to get an authentication token for my web request in this case?
For desktop applications you can do the following:
Get the list of identity providers from your ACS namespace
Display these in a WebBrowser control
After the user logs in, get the token from the WebBrowser control and parse it.
This is similar to when you want to use ACS in a Windows Phone application. I suggest you take a look at this blog post: Azure ACS on Windows Phone 7. And here is the sample code which parses the token after the user logs in through the WebBrowser control (on WP7):
private void SignInWebBrowserControl_ScriptNotify(object sender, NotifyEventArgs e)
{
var acsResponse = ACSResponse.FromJSON(e.Value);
RequestSecurityTokenResponse rstr = null;
Exception exception = null;
try
{
string binaryToken = HttpUtility.HtmlDecode(acsResponse.securityToken);
string tokenText = RequestSecurityTokenResponseDeserializer.ProcessBinaryToken(binaryToken);
DateTime expiration = DateTime.Now + TimeSpan.FromSeconds(acsResponse.expires – acsResponse.created);
rstr = new RequestSecurityTokenResponse
{
Expiration = expiration,
TokenString = tokenText,
TokenType = acsResponse.tokenType
};
I need to "impersonate" a user in a VB.NET 2008 WinForms application, so that the application can accept the Active Directory login of any user on a PC regardless of who is actually logged in to Windows. I want the application's My.User to be the AD account of the person who logged in to the application. I succeeded in this with the following code:
Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As String, ByVal lpszDomain As String, _
ByVal lpszPassword As String, ByVal dwLogonType As Integer, _
ByVal dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean
Const LOGON32_LOGON_INTERACTIVE As Long = 2
Const LOGON32_LOGON_NETWORK As Long = 3
Const LOGON32_PROVIDER_DEFAULT As Long = 0
Const LOGON32_PROVIDER_WINNT35 As Long = 1
Const LOGON32_PROVIDER_WINNT40 As Long = 2
Const LOGON32_PROVIDER_WINNT50 As Long = 3
' Influenced from the example at http://aspalliance.com/39
Public Shared Function Login(ByVal uid As String, ByVal pwd As String) As Boolean
' Get the user's domain name.
Dim domainName As String = My.User.Name.Substring(0, My.User.Name.IndexOf("\"))
' This token is returned by the LogonUser API call (variable is passed ByRef).
Dim token As IntPtr
If LogonUser(uid, domainName, pwd, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, token) Then
' Added this line per response to this question:
WindowsIdentity.Impersonate(token)
' If the login succeeds, then impersonate that user by changing CurrentPrincipal.
Dim wi As New Principal.WindowsIdentity(token)
Dim wp As New Principal.WindowsPrincipal(wi)
My.User.CurrentPrincipal = wp
Return True
Else
Return False
End If
End Function
However, the application uses a .DLL with the Data Access Layer which is connecting to SQL Server 2000. It appears that SQL Server, using "Integrated Security=SSPI" in the connection string, is receiving the login of the account logged in to Windows and not the account returned My.User.CurrentPrincipal.Identity, when stepping through the code, in both the WinForms app code and the .DLL's app code.
Both the WinForms app and .DLL code properly recognize My.User.CurrentPrincipal.Identity as the account logged in to the app, not Windows. It's just not propagating to SQL Server. This is evidenced by Stored procedures writing SUSER_SNAME() to a table's column in T-SQL.
Can anyone see what I'm going wrong?
EDIT: I've added the line WindowsIdentity.Impersonate(token) as stated, but now when my .DLL tries to create an SQL Server connection it throws this error:
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.
You need to call WindowsIdentity.Impersonate();:
If LogonUser(...) Then
WindowsIdentity.Impersonate(token)