mh_lcmk_sms_service/APT.Utility/Providers/ApplicationOAuthProvider.cs
2024-07-12 16:37:09 +08:00

231 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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