231 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			231 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 
								 | 
							
								using System;
							 | 
						|||
| 
								 | 
							
								using System.Collections.Generic;
							 | 
						|||
| 
								 | 
							
								using System.Linq;
							 | 
						|||
| 
								 | 
							
								using System.Security.Claims;
							 | 
						|||
| 
								 | 
							
								using System.Threading.Tasks;
							 | 
						|||
| 
								 | 
							
								using System.Web;
							 | 
						|||
| 
								 | 
							
								using LDX.Core;
							 | 
						|||
| 
								 | 
							
								using Microsoft.Owin.Security;
							 | 
						|||
| 
								 | 
							
								using Microsoft.Owin.Security.OAuth;
							 | 
						|||
| 
								 | 
							
								using LDX.BaseData.Domain.IServices;
							 | 
						|||
| 
								 | 
							
								using LDX.BaseData.Domain.Entities;
							 | 
						|||
| 
								 | 
							
								using LDX.MES.Domain.IServices.FM;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace LDX.WebApi.Providers
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    /// <summary>
							 | 
						|||
| 
								 | 
							
								    /// OAuth Provider
							 | 
						|||
| 
								 | 
							
								    /// </summary>
							 | 
						|||
| 
								 | 
							
								    public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        #region fields
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// 管理后台ClientId
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        const string AdminPortalClientId = "witbackstage";
							 | 
						|||
| 
								 | 
							
								        const string AdminPlatformId = "witplatform";
							 | 
						|||
| 
								 | 
							
								        const string AppClientId = "witjitmesapp";
							 | 
						|||
| 
								 | 
							
								        string clientId;
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// 公钥
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        static string _PublicKey;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// 允许的clientId 列表
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        static IList<string> _ClientIdList;
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #region ctor.
							 | 
						|||
| 
								 | 
							
								        public ApplicationOAuthProvider()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        static ApplicationOAuthProvider()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            _PublicKey = "LDX2017#";
							 | 
						|||
| 
								 | 
							
								            _ClientIdList = new List<string>();
							 | 
						|||
| 
								 | 
							
								            for (int i = 1; i <= 40; i++)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                _ClientIdList.Add(string.Concat("wt", i.PadLeft(3, '0')));
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Called when a request to the Token endpoint arrives with a "grant_type" of "password". This occurs when the user has provided name and password
							 | 
						|||
| 
								 | 
							
								        /// credentials directly into the client application's user interface, and the client application is using those to acquire an "access_token" and
							 | 
						|||
| 
								 | 
							
								        /// optional "refresh_token". If the web application supports the
							 | 
						|||
| 
								 | 
							
								        /// resource owner credentials grant type it must validate the context.Username and context.Password as appropriate. To issue an
							 | 
						|||
| 
								 | 
							
								        /// access token the context.Validated must be called with a new ticket containing the claims about the resource owner which should be associated
							 | 
						|||
| 
								 | 
							
								        /// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers.
							 | 
						|||
| 
								 | 
							
								        /// The default behavior is to reject this grant type.
							 | 
						|||
| 
								 | 
							
								        /// See also http://tools.ietf.org/html/rfc6749#section-4.3.2
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="context">The context of the event carries information in and results out.</param>
							 | 
						|||
| 
								 | 
							
								        /// <returns>
							 | 
						|||
| 
								 | 
							
								        /// Task to enable asynchronous execution
							 | 
						|||
| 
								 | 
							
								        /// </returns>
							 | 
						|||
| 
								 | 
							
								        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            //Tuple<string, string> departmentInfo;
							 | 
						|||
| 
								 | 
							
								            var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
							 | 
						|||
| 
								 | 
							
								            try
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                /*
							 | 
						|||
| 
								 | 
							
								                var userService = ServiceLocator.Instance.GetService<IUserService>();
							 | 
						|||
| 
								 | 
							
								                loginUser = userService.Login(context.UserName, context.Password);
							 | 
						|||
| 
								 | 
							
								                if (loginUser == null)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    throw new DomainException("用户名或密码不正确。");
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                if (IsFromAdminPortal(context) && !loginUser.CanLoginAdminPortal)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    throw new DomainException("用户没有登录管理后台的权限。");
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                if (IsFromAdminPortal(context) && !loginUser.CanLoginAdminPortal)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    throw new DomainException("用户没有登录管理后台的权限。");
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                if (IsFromPos(context) && !loginUser.CanLoginPos)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    throw new DomainException("用户没有登录Pos的权限。");
							 | 
						|||
| 
								 | 
							
								                } */
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                //departmentInfo = GetDepartmentInfo(loginUser);
							 | 
						|||
| 
								 | 
							
								                //if (clientId == AdminPortalClientId || clientId == AppClientId)
							 | 
						|||
| 
								 | 
							
								                //{
							 | 
						|||
| 
								 | 
							
								                    var userService = ServiceLocator.Instance.GetService<IFMUserService>();
							 | 
						|||
| 
								 | 
							
								                    var loginUser = userService.Get(i => (i.CODE.ToUpper() == context.UserName.ToUpper()
							 | 
						|||
| 
								 | 
							
								                        || i.PHONE == context.UserName) && i.PASSWORD.ToUpper() == context.Password.ToUpper());
							 | 
						|||
| 
								 | 
							
								                    if (loginUser == null)
							 | 
						|||
| 
								 | 
							
								                    {
							 | 
						|||
| 
								 | 
							
								                        context.SetError("invalid_grant", "用户不存在或密码错误");
							 | 
						|||
| 
								 | 
							
								                        return;
							 | 
						|||
| 
								 | 
							
								                    }
							 | 
						|||
| 
								 | 
							
								                    else
							 | 
						|||
| 
								 | 
							
								                    {
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                        oAuthIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, loginUser.ID.ToString()));
							 | 
						|||
| 
								 | 
							
								                        oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, loginUser.NAME));
							 | 
						|||
| 
								 | 
							
								                        //oAuthIdentity.AddClaim(new Claim(ClaimTypes.Role, loginUser.ROLE));
							 | 
						|||
| 
								 | 
							
								                        //oAuthIdentity.AddClaim(new Claim(ClaimTypes.Uri, context.Request.Uri.AbsoluteUri));
							 | 
						|||
| 
								 | 
							
								                        oAuthIdentity.AddClaim(new Claim(LDX.Core.Security.ClaimTypes.UserCode, loginUser.CODE));
							 | 
						|||
| 
								 | 
							
														if (loginUser.ORG_ID != null)
							 | 
						|||
| 
								 | 
							
															oAuthIdentity.AddClaim(new Claim(LDX.Core.Security.ClaimTypes.OrgId, loginUser.ORG_ID.ToString()));
							 | 
						|||
| 
								 | 
							
								                        //oAuthIdentity.AddClaim(new Claim(LDX.Core.Security.ClaimTypes.DepartmentId, loginUser.DEPARTMENT_ID == null ? "" : loginUser.DEPARTMENT_ID.ToString()));
							 | 
						|||
| 
								 | 
							
								                    }
							 | 
						|||
| 
								 | 
							
								    //            }
							 | 
						|||
| 
								 | 
							
								    //            else
							 | 
						|||
| 
								 | 
							
								    //            {
							 | 
						|||
| 
								 | 
							
												//	context.SetError("invalid_grant", "用户不存在或密码错误");
							 | 
						|||
| 
								 | 
							
												//	return;
							 | 
						|||
| 
								 | 
							
												//	//var platformUserService = ServiceLocator.Instance.GetService<IPlatformUserService>();
							 | 
						|||
| 
								 | 
							
												//	//var platUser = platformUserService.Get(i => i.LOGIN_NAME.ToUpper() == context.UserName.ToUpper() && i.PASSWORD == context.Password.ToUpper());
							 | 
						|||
| 
								 | 
							
												//	//if (platUser == null)
							 | 
						|||
| 
								 | 
							
												//	//{
							 | 
						|||
| 
								 | 
							
												//	//    context.SetError("invalid_grant", "用户不存在或密码错误");
							 | 
						|||
| 
								 | 
							
												//	//    return;
							 | 
						|||
| 
								 | 
							
												//	//}
							 | 
						|||
| 
								 | 
							
												//	//else
							 | 
						|||
| 
								 | 
							
												//	//{
							 | 
						|||
| 
								 | 
							
												//	//    oAuthIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, platUser.ID.ToString()));
							 | 
						|||
| 
								 | 
							
												//	//    //oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, platUser.NAME));
							 | 
						|||
| 
								 | 
							
												//	//    oAuthIdentity.AddClaim(new Claim(LDX.Core.Security.ClaimTypes.UserCode, platUser.LOGIN_NAME));
							 | 
						|||
| 
								 | 
							
												//	//    oAuthIdentity.AddClaim(new Claim(LDX.Core.Security.ClaimTypes.Cid, platUser.CID));
							 | 
						|||
| 
								 | 
							
												//	//}
							 | 
						|||
| 
								 | 
							
												//}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								            catch (DomainException domainEx)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                context.SetError("invalid_grant", domainEx.Message);
							 | 
						|||
| 
								 | 
							
								                return;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            catch (Exception ex)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                context.SetError("invalid_grant", ex.Message);
							 | 
						|||
| 
								 | 
							
								                return;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
							 | 
						|||
| 
								 | 
							
								            context.Validated(ticket);
							 | 
						|||
| 
								 | 
							
								            await base.GrantResourceOwnerCredentials(context);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private bool IsFromAdminPortal(OAuthGrantResourceOwnerCredentialsContext context)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return AdminPortalClientId.Equals(context.ClientId);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private bool IsFromPos(OAuthGrantResourceOwnerCredentialsContext context)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return !IsFromAdminPortal(context);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        //private Tuple<string, string> GetDepartmentInfo(BaseData.Domain.Entities.User loginUser)
							 | 
						|||
| 
								 | 
							
								        //{
							 | 
						|||
| 
								 | 
							
								        //    var departmentCode = System.Configuration.ConfigurationManager.AppSettings["DepartmentCode"];
							 | 
						|||
| 
								 | 
							
								        //    var departmentService = ServiceLocator.Instance.GetService<IDepartmentService>();
							 | 
						|||
| 
								 | 
							
								        //    var department = string.IsNullOrWhiteSpace(departmentCode) ? departmentService.Get(loginUser.DepartmentID) : departmentService.Query(p => p.Code == departmentCode).FirstOrDefault();
							 | 
						|||
| 
								 | 
							
								        //    if (department == null)
							 | 
						|||
| 
								 | 
							
								        //        throw new DomainException("服务端异常,未找到配置的门店信息。");
							 | 
						|||
| 
								 | 
							
								        //    return new Tuple<string, string>(department.ID.ToString(), department.Name);
							 | 
						|||
| 
								 | 
							
								        //}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Called when a request to the Token endpoint arrives with a "grant_type" of "client_credentials". This occurs when a registered client
							 | 
						|||
| 
								 | 
							
								        /// application wishes to acquire an "access_token" to interact with protected resources on it's own behalf, rather than on behalf of an authenticated user.
							 | 
						|||
| 
								 | 
							
								        /// If the web application supports the client credentials it may assume the context.ClientId has been validated by the ValidateClientAuthentication call.
							 | 
						|||
| 
								 | 
							
								        /// To issue an access token the context.Validated must be called with a new ticket containing the claims about the client application which should be associated
							 | 
						|||
| 
								 | 
							
								        /// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers.
							 | 
						|||
| 
								 | 
							
								        /// The default behavior is to reject this grant type.
							 | 
						|||
| 
								 | 
							
								        /// See also http://tools.ietf.org/html/rfc6749#section-4.4.2
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="context">The context of the event carries information in and results out.</param>
							 | 
						|||
| 
								 | 
							
								        /// <returns>
							 | 
						|||
| 
								 | 
							
								        /// Task to enable asynchronous execution
							 | 
						|||
| 
								 | 
							
								        /// </returns>
							 | 
						|||
| 
								 | 
							
								        public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
							 | 
						|||
| 
								 | 
							
								            oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.ClientId));
							 | 
						|||
| 
								 | 
							
								            var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
							 | 
						|||
| 
								 | 
							
								            context.Validated(ticket);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            return base.GrantClientCredentials(context);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that client are
							 | 
						|||
| 
								 | 
							
								        /// present on the request. If the web application accepts Basic authentication credentials,
							 | 
						|||
| 
								 | 
							
								        /// context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. If the web
							 | 
						|||
| 
								 | 
							
								        /// application accepts "client_id" and "client_secret" as form encoded POST parameters,
							 | 
						|||
| 
								 | 
							
								        /// context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body.
							 | 
						|||
| 
								 | 
							
								        /// If context.Validated is not called the request will not proceed further.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="context">The context of the event carries information in and results out.</param>
							 | 
						|||
| 
								 | 
							
								        /// <returns>
							 | 
						|||
| 
								 | 
							
								        /// Task to enable asynchronous execution
							 | 
						|||
| 
								 | 
							
								        /// </returns>
							 | 
						|||
| 
								 | 
							
								        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            string clientSecret;
							 | 
						|||
| 
								 | 
							
								            context.TryGetBasicCredentials(out clientId, out clientSecret);
							 | 
						|||
| 
								 | 
							
								            //if (AdminPortalClientId.Equals(clientId) || AppClientId.Equals(clientId) || AdminPlatformId.Equals(clientId))//管理后台,授权通过
							 | 
						|||
| 
								 | 
							
								            //{
							 | 
						|||
| 
								 | 
							
								                context.Validated(clientId);
							 | 
						|||
| 
								 | 
							
								            //}
							 | 
						|||
| 
								 | 
							
								            //else if (_ClientIdList.Contains(clientId) && _PublicKey.Equals(clientSecret))//校验POS前端私钥和公钥
							 | 
						|||
| 
								 | 
							
								            //{
							 | 
						|||
| 
								 | 
							
								            //    context.Validated(clientId);
							 | 
						|||
| 
								 | 
							
								            //}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            return base.ValidateClientAuthentication(context);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |