ABP目前的认证方式有两种,一种是基于Cookie的登录认证,一种是基于token的登录认证。使用Cookie的认证方式一般在PC端用得比较多,使用token的认证方式一般在移动端用得比较多。ABP自带的Token认证方式通过UseOAuthBearerAuthentication启用的,既然已经自带了Token的认证方式,为什么还要使用OAuth2呢?使用此方式是无法实现Token的刷新的,Token过期后必须通过用户名和密码重新登录,这样客户端会弹出登录框让用户登录,用户体验不是很好,当然也可以在客户端存储用户名和密码,发现Token过期后,在后台自动登录,这样用户也是不知道的,只是存在账号安全问题(其实这些都不是问题,主要原因是使用OAuth2后B格更高)。下面我们来看一下怎么在ABP中使用OAuth2:

1.到ABP的官网上下载一个自动生成的项目模板

2.添加OAuth相关的代码

  a) 添加一个SimpleAuthorizationServerProvider类,用于验证客户端和用户名密码,网上能够找到类似的代码,直接拿来修改一下就可以

作者:loyldg 出处:http://www.cnblogs.com/loyldg/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以邮件:loyldg@126.com 联系我,非常感谢。
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider, ITransientDependency
    {
        /// <summary>
        /// The _user manager
        /// </summary>
        private readonly UserManager _userManager;

        public SimpleAuthorizationServerProvider(UserManager userManager)
        {
            _userManager = userManager;
        }

        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            string clientId;
            string clientSecret;
            if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
            {
                context.TryGetFormCredentials(out clientId, out clientSecret);
            }
            var isValidClient = string.CompareOrdinal(clientId, "app") == 0 &&
                                string.CompareOrdinal(clientSecret, "app") == 0;
            if (isValidClient)
            {
                context.OwinContext.Set("as:client_id", clientId);
                context.Validated(clientId);
            }
            else
            {
                context.SetError("invalid client");                
            }
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var tenantId = context.Request.Query["tenantId"];
            var result = await GetLoginResultAsync(context, context.UserName, context.Password, tenantId);
            if (result.Result == AbpLoginResultType.Success)
            {
                //var claimsIdentity = result.Identity;                
                var claimsIdentity = new ClaimsIdentity(result.Identity);
                claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
                var ticket = new AuthenticationTicket(claimsIdentity, new AuthenticationProperties());                
                context.Validated(ticket);
            }
        }

        public override async Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
        {
            var originalClient = context.OwinContext.Get<string>("as:client_id"); 
            var currentClient = context.ClientId;

            // enforce client binding of refresh token
            if (originalClient != currentClient)
            {
                context.Rejected();
                return;
            }

            // chance to change authentication ticket for refresh token requests
            var newId = new ClaimsIdentity(context.Ticket.Identity);
            newId.AddClaim(new Claim("newClaim", "refreshToken"));

            var newTicket = new AuthenticationTicket(newId, context.Ticket.Properties);
            context.Validated(newTicket);            
        }

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

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

        private void CreateExceptionForFailedLoginAttempt(OAuthGrantResourceOwnerCredentialsContext context, AbpLoginResultType result, string usernameOrEmailAddress, string tenancyName)
        {
            switch (result)
            {
                case AbpLoginResultType.Success:
                    throw new ApplicationException("Don't call this method with a success result!");
                case AbpLoginResultType.InvalidUserNameOrEmailAddress:
                case AbpLoginResultType.InvalidPassword:
                    context.SetError(L("LoginFailed"), L("InvalidUserNameOrPassword"));
                    break;
                //    return new UserFriendlyException(("LoginFailed"), ("InvalidUserNameOrPassword"));
                case AbpLoginResultType.InvalidTenancyName:
                    context.SetError(L("LoginFailed"), L("ThereIsNoTenantDefinedWithName", tenancyName));
                    break;
                //    return new UserFriendlyException(("LoginFailed"), string.Format("ThereIsNoTenantDefinedWithName{0}", tenancyName));
                case AbpLoginResultType.TenantIsNotActive:
                    context.SetError(L("LoginFailed"), L("TenantIsNotActive", tenancyName));
                    break;
                //    return new UserFriendlyException(("LoginFailed"), string.Format("TenantIsNotActive {0}", tenancyName));
                case AbpLoginResultType.UserIsNotActive:
                    context.SetError(L("LoginFailed"), L("UserIsNotActiveAndCanNotLogin", usernameOrEmailAddress));
                    break;
                //    return new UserFriendlyException(("LoginFailed"), string.Format("UserIsNotActiveAndCanNotLogin {0}", usernameOrEmailAddress));
                case AbpLoginResultType.UserEmailIsNotConfirmed:
                    context.SetError(L("LoginFailed"), L("UserEmailIsNotConfirmedAndCanNotLogin"));
                    break;
                //    return new UserFriendlyException(("LoginFailed"), ("UserEmailIsNotConfirmedAndCanNotLogin"));
                //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(("LoginFailed"));
            }
        }
        
        private static string L(string name, params object[] args)
        {
            //return new LocalizedString(name);
            return IocManager.Instance.Resolve<ILocalizationService>().L(name, args);
        }

    }
View Code

相关文章:

  • 2022-12-23
  • 2021-06-19
  • 2022-12-23
  • 2022-12-23
  • 2022-01-29
  • 2021-09-22
  • 2021-06-13
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-07-12
  • 2022-02-09
  • 2021-09-01
  • 2021-10-03
  • 2022-02-19
相关资源
相似解决方案