Integrated Windows Authentication in ABP framework

半城伤御伤魂 提交于 2019-11-29 18:17:37

To login the user thru official AspNet Boilerplate API (to have roles and other stuffs) you can use external authentication. It is exactly what you are looking for;

https://aspnetboilerplate.com/Pages/Documents/Zero/User-Management#external-authentication

I tried to do what John suggested, but I had to make a few changes, so this is how I did it.

"angular\src\account\login\login.component.ts"

class LoginComponent {    
  ngOnInit() {
    this.loginService.authenticateModel.userNameOrEmailAddress = 'foo';
    this.loginService.authenticateModel.password = 'bar';
    this.login();
  }
}

"aspnet-core\src\ProjectName.Core\Authentication\AlwaysTrue\AlwaysTrueExternalAuthSource.cs"

public class AlwaysTrueExternalAuthSource: DefaultExternalAuthenticationSource<Tenant, User>, ITransientDependency
{
  public override string Name => "AlwaysTrueExternalAuthSource";

  public override Task<bool> TryAuthenticateAsync(string userNameOrEmailAddress, string plainPassword, Tenant tenant)
  {
    return Task.FromResult(true);
  }
}

"aspnet-core\src\ProjectName.Core\ProjectNameCoreModule.cs"

public class ProjectNameCoreModule : AbpModule
{
  public override void PreInitialize()
  {
    Configuration.Modules.Zero().UserManagement.ExternalAuthenticationSources.Add<AlwaysTrueExternalAuthSource>();
  }
}

"aspnet-core\src\ProjectName.Web.Core\Controllers\TokenAuthController.cs"

public class TokenAuthController : ProjectNameControllerBase
{
  [HttpPost]
  public async Task<AuthenticateResultModel> Authenticate([FromBody] AuthenticateModel model)
  {
    var windowsIdentity = WindowsIdentity.GetCurrent();
    model.UserNameOrEmailAddress = windowsIdentity.Name.ToLowerInvariant().Replace("\\","");

    var loginResult = await GetLoginResultAsync(...)
  }
}

in the spirit of sharing here is how i managed to circumvent the use of the login screen for a Window Authenticated context.

  1. make the Login panel hidden and set some dummy data on the username/password controls (the dummy data is not actually used).
  2. in the js file run the login action immediately (no user interaction)

    abp.ajax({ contentType: 'application/x-www-form-urlencoded', url: $loginForm.attr('action'), data: $loginForm.serialize() });

  3. In the AccountController:

var windowsIdentity = WindowsIdentity.GetCurrent(); loginModel.UsernameOrEmailAddress = windowsIdentity.Name;

var count = (from x in windowsIdentity.Claims where x.Value == "myclaim" select x).Count();

if (count == 0)
{
    throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(AbpLoginResultType.InvalidUserNameOrEmailAddress, loginModel.UsernameOrEmailAddress, null);
}
  1. Create an ExternalAuthSource as described in the answer above. We will always return true becuase the real authentication is already done.

    public override Task<bool> TryAuthenticateAsync(string userNameOrEmailAddress, string plainPassword, Tenant tenant) { return Task.FromResult(true); }

    It has the added advantage that the authenticated user is created by the Apb-framework automatically. The Role the new user is assigned depends on the which role is the Default - see Table AbpUserRoles

Hopefully this helps somebody trying to use the framework in a Windows-Authenticated context.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!