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);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|