ASP.NET Core 는 사용자 정의 인증 속성 제어 접근 권한 을 사용 합 니 다.
응용 프로그램 에서 우 리 는 방문 한 클 라 이언 트 에 대해 유효성 검증 을 해 야 한 다 는 것 을 잘 알 고 있 습 니 다.유효한 증빙(AccessToken)을 제공 하 는 터미널 응용 프로그램 만 우리 의 제어 사이트(예 를 들 어 WebAPI 사이트)를 방문 할 수 있 습 니 다.이때 우 리 는 속성 을 검증 하 는 방법 으로 해결 할 수 있 습 니 다.
본 고 는 ASP.NET Core 가 사용자 정의 인증 속성 을 사용 하여 접근 권한 을 제어 하 는 것 과 관련 된 내용 을 상세 하 게 소개 하고 참고 학습 을 제공 할 것 입 니 다.다음은 더 이상 할 말 이 없 으 니 상세 한 소 개 를 해 보 겠 습 니 다.
방법 은 아래 와 같다.
1.Public class Startup 설정:
// ( )
services.AddCors(options =>
{
options.AddPolicy("AllowOriginOtherBis",
builder => builder.WithOrigins("https://1.16.9.12:4432", "https://pc12.ato.biz:4432", "https://localhost:44384", "https://1.16.9.12:4432", "https://pc12.ato.biz:4432").AllowAnyMethod().AllowAnyHeader());
});
// Action [TerminalApp()] 。
services.AddSingleton<IAuthorizationHandler, TerminalAppAuthorizationHandler>();
services.AddAuthorization(options =>
{
options.AddPolicy("TerminalApp", policyBuilder =>
{
policyBuilder.Requirements.Add(new TerminalAppAuthorizationRequirement());
});
});
2.Public void Configure(IApplicationBuilder app,IHosting Environment env)의 설정:
app.UseHttpsRedirection(); // Https
app.UseCors("AllowOriginOtherBis"); //
3.예시 WebApi 프로젝트 구조:4.주요 코드(내 가 사용 한 데이터베이스 에서 검증):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
internal class TerminalAppAttribute : AuthorizeAttribute
{
public string AppID { get; }
/// <summary>
/// API
/// </summary>
/// <param name="appID"></param>
public TerminalAppAttribute(string appID="") : base("TerminalApp")
{
AppID = appID;
}
}
public abstract class AttributeAuthorizationHandler<TRequirement, TAttribute> : AuthorizationHandler<TRequirement> where TRequirement : IAuthorizationRequirement where TAttribute : Attribute
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement)
{
var attributes = new List<TAttribute>();
if ((context.Resource as AuthorizationFilterContext)?.ActionDescriptor is ControllerActionDescriptor action)
{
attributes.AddRange(GetAttributes(action.ControllerTypeInfo.UnderlyingSystemType));
attributes.AddRange(GetAttributes(action.MethodInfo));
}
return HandleRequirementAsync(context, requirement, attributes);
}
protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement, IEnumerable<TAttribute> attributes);
private static IEnumerable<TAttribute> GetAttributes(MemberInfo memberInfo)
{
return memberInfo.GetCustomAttributes(typeof(TAttribute), false).Cast<TAttribute>();
}
}
internal class TerminalAppAuthorizationHandler : AttributeAuthorizationHandler<TerminalAppAuthorizationRequirement,TerminalAppAttribute>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TerminalAppAuthorizationRequirement requirement, IEnumerable<TerminalAppAttribute> attributes)
{
object errorMsg = string.Empty;
// , , 403
if (context.Resource is AuthorizationFilterContext filterContext &&
filterContext.ActionDescriptor is ControllerActionDescriptor descriptor)
{
// ,
if (descriptor != null)
{
var actionAttributes = descriptor.MethodInfo.GetCustomAttributes(inherit: true);
bool isAnonymous = actionAttributes.Any(a => a is AllowAnonymousAttribute);
// , accesstoken
if (isAnonymous)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
//url access_token
// AuthorizationHandlerContext HttpContext,
var httpContext = (context.Resource as AuthorizationFilterContext).HttpContext;
//var questUrl = httpContext.Request.Path.Value.ToLower();
string requestAppID = httpContext.Request.Headers["appid"];
string requestAccessToken = httpContext.Request.Headers["access_token"];
if ((!string.IsNullOrEmpty(requestAppID)) && (!string.IsNullOrEmpty(requestAccessToken)))
{
if (attributes != null)
{
// AppID
if (attributes.ToArray().ToString()=="")
{
// App , APPID ID
bool mat = false;
foreach (var terminalAppAttribute in attributes)
{
if (terminalAppAttribute.AppID == requestAppID)
{
mat = true;
break;
}
}
if (!mat)
{
errorMsg = ReturnStd.NotAuthorize(" .");
return HandleBlockedAsync(context, requirement, errorMsg);
}
}
}
// attributes, , ID
string valRst = ValidateToken(requestAppID, requestAccessToken);
if (string.IsNullOrEmpty(valRst))
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
errorMsg = ReturnStd.NotAuthorize("AccessToken (" + valRst + ")","91");
return HandleBlockedAsync(context, requirement, errorMsg);
}
}
else
{
errorMsg = ReturnStd.NotAuthorize(" AppID Token.");
return HandleBlockedAsync(context, requirement, errorMsg);
//return Task.CompletedTask;
}
}
}
}
else
{
errorMsg = ReturnStd.NotAuthorize("FilterContext .");
return HandleBlockedAsync(context, requirement, errorMsg);
}
errorMsg = ReturnStd.NotAuthorize(" .");
return HandleBlockedAsync(context,requirement, errorMsg);
}
// ( )
/// <summary>
/// AccessToken
/// </summary>
/// <param name="appID"> APP ID</param>
/// <param name="accessToken"> APP AppKEY AccessToken, </param>
/// <returns></returns>
private string ValidateToken(string appID,string accessToken)
{
try
{
DBContextMain dBContext = new DBContextMain();
string appKeyOnServer = string.Empty;
// AppID KEY( KEY AES_KEY
AuthApp authApp = dBContext.AuthApps.FirstOrDefault(a => a.AppID == appID);
if (authApp == null)
{
return " !";
}
else
{
appKeyOnServer = authApp.APPKey;
}
if (string.IsNullOrEmpty(appKeyOnServer))
{
return " !";
}
string tmpToken = string.Empty;
tmpToken = System.Net.WebUtility.UrlDecode(accessToken);// Token ( += , )
tmpToken = OCrypto.AES16Decrypt(tmpToken, appKeyOnServer); // APPKEY
if (string.IsNullOrEmpty(tmpToken))
{
return " !";
}
else
{
try
{
// im_cloud_sv001-appid-ticks
// , , 10
long tmpTime =Convert.ToInt64(tmpToken.Substring(tmpToken.LastIndexOf("-")+1));
//DateTime dt = DateTime.ParseExact(tmpTime, "yyyyMMddHHmmss", CultureInfo.CurrentCulture);
DateTime dt= new DateTime(tmpTime);
bool IsInTimeSpan = (Convert.ToDouble(ODateTime.DateDiffSeconds(dt, DateTime.Now)) <= 7200);
bool IsInternalApp = (tmpToken.IndexOf("im_cloud_sv001-") >= 0);
if (!IsInternalApp || !IsInTimeSpan)
{
return " !";
}
else
{
return string.Empty; //
}
}
catch (Exception ex)
{
return " (" + ex.Message + ")";
}
}
}
catch (Exception ex)
{
return " (" + ex.Message + ")";
}
}
private Task HandleBlockedAsync(AuthorizationHandlerContext context, TerminalAppAuthorizationRequirement requirement, object errorMsg)
{
var authorizationFilterContext = context.Resource as AuthorizationFilterContext;
authorizationFilterContext.Result = new JsonResult(errorMsg) { StatusCode = 202 };
// 403 , Accepted202,
context.Succeed(requirement);
return Task.CompletedTask;
}
}
internal class TerminalAppAuthorizationRequirement : IAuthorizationRequirement
{
public TerminalAppAuthorizationRequirement()
{
}
}
5.해당 Token 인증 코드:
[AutoValidateAntiforgeryToken] //
[Route("api/get_accesstoken")]
public class GetAccessTokenController : Controller
{
//
// {"access_token":"ACCESS_TOKEN","expires_in":7200} 2
// {"errcode":40013,"errmsg":"invalid appid"}
[AllowAnonymous]
public ActionResult<string> Get()
{
try
{
string tmpToken = string.Empty;
string appID = HttpContext.Request.Headers["appid"];
string appKey = HttpContext.Request.Headers["appkey"];
if ((appID.Length < 5) || appKey.Length != 32)
{
return "{'errcode':10000,'errmsg':'appid appkey '}";
}
//token im_cloud_sv001-appid-ticks
long timeTk = DateTime.Now.Ticks; // :633603924670937500
//DateTime dt = new DateTime(timeTk);//
string plToken = "im_cloud1-" + appID + "-" + timeTk;
tmpToken = OCrypto.AES16Encrypt(plToken, appKey); // APPKEY
tmpToken = System.Net.WebUtility.UrlEncode(tmpToken);
// Token( += , )
tmpToken = "{'access_token':'" + tmpToken + "','expires_in':7200}";
return tmpToken;
}
catch (Exception ex)
{
return "{'errcode':10001,'errmsg':'" + ex.Message +"'}";
}
}
}
GetAccessTokenController.cs
6.이렇게 해서 우리 가 통제 해 야 하 는 곳 에[TerminalApp()]을 추가 하면 된다.그러면 모든 권한 을 수 여 받 은 App 이 방문 할 수 있다.물론[TerminalApp('app 01')]을 사용 하여 특정한 ID 를 app 01 로 제한 하 는 응용 프로그램 방문 도 할 수 있다.
[Area("SYS")] // : api/sys/user
[Produces("application/json")]
[TerminalApp()]
public class UserController : Controller
{
//
}
7.CS 클 라 이언 트 가 웹 API 를 통 해 데이터 호출 예 시 를 업로드 합 니 다.
string postURL = "http://sv12.ato.com/api/sys/user/postnew";
Dictionary<string, string> headerDic2 = new Dictionary<string, string>
{
{ "appid", MainFramework.CloudAppID },
{ "access_token", accessToken }
};
string pushRst = OPWeb.Post(postURL, headerDic2, "POST", sYS_Users);
if (string.IsNullOrEmpty(pushRst))
{
MyMsg.Information(" !");
}
else
{
MyMsg.Information(" !", pushRst);
}
string accessToken = MainFramework.CloudAccessToken;
if (accessToken.IndexOf("ERROR:") >= 0)
{
MyMsg.Information(" Token :" + accessToken);
return;
}
총결산이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Tailwind를 ASP.NET Core 프로젝트에 통합우리는 을 사용합니다. 에서 코드를 찾을 수 있습니다. 면도기 페이지 구조를 추가합니다. "node_modules"가 설치되었습니다. "tailwind.config.js"파일이 생성되었습니다. 모든 .razor 및 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.