예를 들어, AuthorizationClient
내 API와 Azure 간의 인증 토큰에 대한 클라이언트 중재자 역할을하는 애플리케이션 구성에 임시 서비스로 등록되어 있습니다. 내부에는 IConfidentialClientApplication
객체 속성이 있습니다.
public class AuthorizationClient : IAuthorizationClient
{
private readonly string[] _resourceIds;
private IConfidentialClientApplication App;
public AuthorizationClient(IAuthenticationConfig AuthenticationConfig, IConfiguration configuration)
{
var scope = "/.default";
var resourceId = "api://" + configuration[AuthenticationConfig.ResourceID] + scope;
var clientId = configuration[AuthenticationConfig.ClientID];
var clientSecret = configuration[AuthenticationConfig.ClientSecret];
var instance = AuthenticationConfig.Instance;
var tenant = configuration[AuthenticationConfig.AzureTenantId];
var authority = string.Format(CultureInfo.InvariantCulture, instance, tenant);
_resourceIds = new string[] { resourceId };
try
{
App = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri(authority))
.Build();
}
catch(Exception ex)
{
//TODO logger
}
}
...
}
이 클래스의 다른 곳에서는 토큰을 성공적으로 가져오고 토큰 캐시를 확인하는 등의 메서드가 있습니다.
그러나 IConfidentialClientApplication
사용중인 문서 나 리포지토리를 보았을 때 항상 다른 개체 내부가 아닌 애플리케이션 수준에서 서비스로 추가됩니다. 내가이 일을 한 방식에 잠재적 인 함정이 있습니까?
은 IConfidentialClientApplication
새가 모든 클라이언트 요청에 따라 인스턴스화 경우 오히려 / 무거운 큰 것 같다,하지만 응용 프로그램 수준의 서비스를 인 객체의 내부를 인스턴스화 한 바와 같이, 하나의 수명주기에 따라 생성 될 것으로 보인다.
대상 클래스 내에서 종속성을 인스턴스화하는 것은 코드 냄새입니다.
함정 : 구현 세부 사항에 대한 긴밀한 결합 및 명시 적 종속성 원칙 위반.
이로 인해 격리 된 상태에서 클래스를 유지하고 테스트하기가 어렵습니다.
이러한 디자인 문제는 단일 책임 원칙 / 우려 사항 분리 및 명시 적 종속성 원칙을 적용하여 코드를 더욱 견고하게 만들 수 있도록 수정할 수 있습니다.
클라이언트 옵션을 저장할 클래스를 만듭니다. 제공된 예제에 따라 다음과 같이 보일 수 있습니다.
public class AuthorizationClientOptions {
public string[] ResourceIds { get; set; }
}
기능을 수행하는 데 실제로 필요한 사항에 명시 적으로 의존하도록 클래스를 리팩터링합니다.
public class AuthorizationClient : IAuthorizationClient {
private readonly string[] _resourceIds;
private readonly IConfidentialClientApplication app;
public AuthorizationClient(IConfidentialClientApplication app, IOptions<AuthorizationClientOptions> options) {
this.app = app;
_resourceIds = options.Value.ResourceIds;
}
// ...
}
컴포지션 루트 (시작)에서 필요한 구현 세부 정보를 구성합니다.
//...
IConfiguration Configuration; //Populated either via constructor injection or manually
public void ConfigureServices(IServiceCollection services) {
//...
//Configure options
services.AddOptions<AuthorizationClientOptions>()
.Configure<IAuthenticationConfig,IConfiguration>(
(o, authConfig, config) => {
var scope = "/.default";
var resourceId = "api://" + config[authConfig.ResourceID] + scope;
o.ResourceIds = new string[] { resourceId };
});
//Configure dependency using factory delegate
services.AddSingleton<IConfidentialClientApplication>(sp => {
IAuthenticationConfig AuthenticationConfig = sp.GetRequiredService<IAuthenticationConfig>();
var instance = Configuration.Instance;
var tenant = Configuration[AuthenticationConfig.AzureTenantId];
var authority = string.Format(CultureInfo.InvariantCulture, instance, tenant);
var clientId = Configuration[AuthenticationConfig.ClientID];
var clientSecret = Configuration[AuthenticationConfig.ClientSecret];
return ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri(authority))
.Build();
});
services.AddScoped<IAuthorizationClient, AuthorizationClient>();
//...
}
은
IConfidentialClientApplication
새가 모든 클라이언트 요청에 따라 인스턴스화 경우 오히려 / 무거운 큰 것 같다
IConfidentialClientApplication
인스턴스화 할 때 일회성 비용이 있도록 위의 예는, 싱글로 만들어집니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다