通过WebApi进行ASP.Net用户身份验证

时间:2018-02-11 13:36:35

标签: c# asp.net

我正在编写通过WebApi与Asp.Net MVC 5交互的Android应用程序,我使用ASP Boilerplate Module ZERO。我成功在Android App中发送和接收数据,问题是如何使用webApi中预定义的AccountController函数登录和验证用户表单App? Github的Boilerplate零项目来自这个AccountController

  public class AccountController : AbpApiController
{
    public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }

    private readonly LogInManager _logInManager;

    static AccountController()
    {
        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
    }

    public AccountController(LogInManager logInManager)
    {
        _logInManager = logInManager;
        LocalizationSourceName = MisituConsts.LocalizationSourceName;
    }

    [HttpPost]
    public async Task<AjaxResponse> Authenticate(LoginModel loginModel)
    {
        CheckModelState();

        var loginResult = await GetLoginResultAsync(
            loginModel.UsernameOrEmailAddress,
            loginModel.Password,
            loginModel.TenancyName
            );

        var ticket = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties());

        var currentUtc = new SystemClock().UtcNow;
        ticket.Properties.IssuedUtc = currentUtc;
        ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));

        return new AjaxResponse(OAuthBearerOptions.AccessTokenFormat.Protect(ticket));
    }

    private async Task<AbpLoginResult<Tenant, User>> GetLoginResultAsync(string usernameOrEmailAddress, string password, string tenancyName)
    {
        var loginResult = await _logInManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);

        switch (loginResult.Result)
        {
            case AbpLoginResultType.Success:
                return loginResult;
            default:
                throw CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
        }
    }

    private Exception CreateExceptionForFailedLoginAttempt(AbpLoginResultType result, string usernameOrEmailAddress, string tenancyName)
    {
        switch (result)
        {
            case AbpLoginResultType.Success:
                return new ApplicationException("Don't call this method with a success result!");
            case AbpLoginResultType.InvalidUserNameOrEmailAddress:
            case AbpLoginResultType.InvalidPassword:
                return new UserFriendlyException(L("LoginFailed"), L("InvalidUserNameOrPassword"));
            case AbpLoginResultType.InvalidTenancyName:
                return new UserFriendlyException(L("LoginFailed"), L("ThereIsNoTenantDefinedWithName{0}", tenancyName));
            case AbpLoginResultType.TenantIsNotActive:
                return new UserFriendlyException(L("LoginFailed"), L("TenantIsNotActive", tenancyName));
            case AbpLoginResultType.UserIsNotActive:
                return new UserFriendlyException(L("LoginFailed"), L("UserIsNotActiveAndCanNotLogin", usernameOrEmailAddress));
            case AbpLoginResultType.UserEmailIsNotConfirmed:
                return new UserFriendlyException(L("LoginFailed"), "Your email address is not confirmed. You can not login");
                //TODO: localize message
            default: 
                //Can not fall to default actually. But other result types can be added in the future and we may forget to handle it
                Logger.Warn("Unhandled login fail reason: " + result);
                return new UserFriendlyException(L("LoginFailed"));
        }
    }

    protected virtual void CheckModelState()
    {
        if (!ModelState.IsValid)
        {
            throw new UserFriendlyException("Invalid request!");
        }
    }
}

0 个答案:

没有答案