And ultimately never logs in.
After coding and modifying a console app as provided in one of the examples, I can authenticate to On-Prem Windows Server AD.
Here's the working code for the console app, slightly modified. Note using static LdapForNet... was necessary and all LdapForNet.Native was required.
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using LdapForNet;
using LdapForNet.Native;
using static LdapForNet.Native.Native;
/**********************
cmd to find logon DC
systeminfo | find /i "logon server"
distinguished name (DN) = CN=Doe\, Michael,OU=DEVELOPERS,OU=MarketSt,OU=MYOU,DC=mydomain,DC=local (DN ldap entry for Michael Doe)
Filter example: ds.Filter = "(&(objectCategory=User)(objectClass=person)(name=" + userName + "*))";
********************/
namespace LDAPTester
{
public class Program
{
static async Task Main(string[] args)
{
var server = "10.10.10.11";
var serverPort = 389;
var baseDc = "OU=users,DC=mydomain,DC=local";
using (var cn = new LdapConnection())
{
try
{
cn.Connect("ldap://10.10.10.11:389");
// bind using userdn and password
cn.Bind(LdapAuthMechanism.SIMPLE, "mydomain\\michaeldoe", "Password111444");
var entries = cn.Search("DC=mydomain,DC=local", "(&(objectCategory=user)(objectClass=person) (sAMAccountName=michaeldoe))").Take(10);
foreach (var entry in entries)
{
var x = entry;
// key/value pairs of attributes directoryAttributes are the LDAP //field category names, givenName, surName etc.
var de = x.ToDirectoryEntry();
Console.WriteLine(entry);
//Debug.WriteLine(x.Dn["name"][0].ToString());
}
string s = "";
}
catch (Exception exception)
{
string msg = exception.Message;
bool stopHere = true;
}
}
```
Thank you for the quick reply. NO: Not using IIS\WINDOWS authentication.
2. protected virtual async Task<string> NormalizeUserNameAsync(string userName)
{
string usertoLogin=$"mydomain\\{userName}, {await LdapSettingProvider.GetBaseDcAsync()}";
return usertoLogin;
// not used: return $"uid={userName}, {await LdapSettingProvider.GetBaseDcAsync()}";
}
When I login with the built-in admin account:
OpenLdapManager calls ConnectAsync
schema var gets set to LDAP
Next,`ldapConnection.Connect(await LdapSettingProvider.GetServerHostAsync(), await LdapSettingProvider.GetServerPortAsync(), schema);` is called.
I expect this to fail, of course. I get an invalid username and password. The login does not fall back to a local ABP account. Can't login at all.
Next. trying a domain account in format mydomain\myusername and I get further:
In Method DetermineProviderCultureResult(HttpContext httpContext)
and I get to this point:
`string returnUrl = request.Query[ReturnUrl]; // this is empty.
if (returnUrl.IsNullOrWhiteSpace())
{
return await NullProviderCultureResult;
}`
action returns and same message invalid username and password.
At some point the code keeps moving along and I get the authservermodule
`.AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, options =>
{
//Personal Microsoft accounts as an example.
options.AuthorizationEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize";
options.TokenEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token";
options.ClaimActions.MapCustomJson("picture", _ => "https://graph.microsoft.com/v1.0/me/photo/$value");
options.SaveTokens = true;
})`
Another issue is it seems the AD being looked for is some generic AD, not windows AD. Many code changes for AD had to be made to finally authenticate. Even then, it seems something is missing. Shouldn't be this much work.
Where in code do we start?
If you want automatic user creation on first login
Use the same logic in the login callback (after AD validation) to create the ABP IdentityUser record the first time that AD user signs in.
Hi, can you try to install the related module with source code via ABP Studio (https://abp.io/docs/latest/studio/solution-explorer#replace-with-source-code)?
If you look at the first part of my problem, that is exactly what I did. And that is what causes the problem. Thanks for looking into this.
Cms Kit also doesn't work well since it's missing a library
I found that there are some missing libraries installed too (Created the project from ABP STUDIO)
In Application project, It's missing Volo.CmsKit.Pro.Common.Application
In Application.Contracts, it's missing Volo.CmsKit.Pro.Common.Application.Contracts
In HtpApi.Client, it's missing Volo.CmsKit.Pro.Admin.HttpApi.Client
In Web, It's missing Volo.CsmKit.Pro.WebCodeMirror changed a lot from version 5 to version 6, ABP tries to use CodeMirror 6 but is not updated with the actual new project structure
In a MVC project created from ABP Studio
I small workaround is to add the libraries and run the following npm
npm i codemirror@5.65.18Do we want to use CodeMirror6? is there a plan to make it work or was just a mistake to push codemirror6 in the npm?
After updating my project to 8.3.1 and 0.9.1 for ABP Studio, codemirror Error is popping up. My fix was to add the code mirror v5 files from codemirror's website to my main web app wwwroot/lib/codemirror folder. Then everything started working again. I must admit I am getting extremely frustrated going from a working project to one that completely fails everytime I update or add source code. It is costing many,many hours of development downtime trying to figure out what just broke? I like ABP and Studio, I would really like the product if I wasn't constantly beta testing everything.
Hi,
There are two ways to put it.
1 Use BundleContributor https://abp.io/docs/latest/framework/ui/mvc-razor-pages/bundling-minification#contributor-dependencies
[DependsOn(typeof(JQueryScriptContributor))] //Define the dependency public class MyExtensionScriptBundleContributor : BundleContributor { //... }
- Use layout hook https://abp.io/docs/latest/framework/ui/mvc-razor-pages/layout-hooks
Thanks for your quick reply. Will attempt to impliment and check results. I forgot all about the layout-hooks. As I was asking the question, I could not for the life of me remember the term, although I had used the layout-hooks in a previous project.
I tried to reproduce it but unfortunately couldn't. Please share the content of .json files under the .suite folder.
I can also share a fully built-out project. Meanwhile, JSON text is too long to put into a post. I am attaching the .suite files in a github repo Link to .SUITE JSON files in repo with a readme.html file in each folder. There is no code in the repo, just the .suite JSON files.
There is a readme.html file in each folder. I just created this example and the problem still exists. In the provided example: I can add a Company, and add employees to the company after Navigations are created. The problem: There are two related child forms for Company. 1. Sites. 2. Vehicles. When I click Sites after establishing the Company many-to-many navigation and building it, etc. I can add Sites. I can add Employees to the Company via the Employees tab on the Company form. When I click the Sites link, all site records show up. When I click the Company Vehicles link, no vehicles show up. The Add New Vehicle button does not launch the Create Company vehicle form.
When there is no Employees Navigation property, everything works as expected.
The newly generated index.js in the Company page produces:
function initDataGrids(data) { initSiteGrid(data) $("#CompanyVehicles-tab-" + data.id).one("click", function (e) { initCompanyVehicleGrid(data); }); }
The data.id property is null. Normally, the data.id property gets populated when the many-to-many employees isn't used.
To fix the issue, I had to change data.id to data.company.id which solves the problem.
The next line calls initCompanyVehicleGrid(data)
Here is a piece of the ABP generated function call. Notice it is using data.company.id? :
function initCompanyVehicleGrid(data) { if(!abp.auth.isGranted("MstrWithTwoCh.CompanyVehicles")) { return; } var companyId = data.company.id; var companyVehicleService = window.mstrWithTwoCh.controllers.companyVehicleNs.companyVehicle; ... }
However, when code gets regenerated via suite, the fix gets clobbered because it is not in a customization comment region.
Thanks for your reply. How do I put the scripts in the head tag using ABP methods with BundleContributor (After jQuery)? YES: I do have a license for Telerik Ultimate. I am using licensed versions with my license file correctly detected. SO: Telerik controls are working. I would like to defer scripts so that each generated control is not surrounded by Telerik generated script tags.
I researched this issue in the past. It seems there is a way to specify where scripts are placed and in which specific order. For example, the myriad of scripts used by ABP are not placed by accident.
Hi, thanks for the detailed explanation. I'll try to reproduce the problem and let you know.
Hi, any luck with a quick solution or even a work-around that will stick when project is rebuilt in ABP Suite/ABP Studio using customizations?