IdentityServer4 소스 분석 _1_ 프로젝트 구조

디렉토리

간략한 소개

보안 소스 분석 시리즈는 OpenIdConnect가 발행 토큰 소위 원격 인증 수단은 다른 사이트에 의해 달성 원격 인증 프레임 워크에 속하는 OAuth2.0에 마이크로 소프트가 제공하는 다양한 인증 프레임 워크를 설명합니다.

IdentityServer4가 인증 기관 프레임 워크 OpenIdConnect 계약을 기반으로, 우리는 중앙 집중식 인증 서비스를 구축 할 수 있습니다.

OpenIdConnect 프로토콜 요구 사항 문서에 바로 이해할 수있다, 그것은 수요 이벤트에 API의 범위를 기반 idsv4.

idsv 또한 정보가 아래에 볼 수 있습니다 모르는 경우,이 시리즈는 주로 이해를 심화 할 수있는 계약과 함께, 애타게 idsv 소스에 배우고있다.

샤오 첸 자매 시리즈

https://www.cnblogs.com/stulzq/p/8119928.html

공식 문서

https://identityserver4.readthedocs.io/en/latest/

프로젝트 구조

다음 주소에서 프로젝트

https://github.com/IdentityServer/IdentityServer4

도면에 도시 된 로컬 프로젝트 구조로 클로닝

영상

핵심 프로젝트는 IdentityServer4, 나머지뿐만 아니라 프로젝트의 지속성을 처리 한, 마이크로 소프트 프레임 워크에 통합되어있다.
프로젝트 구조가 표시됩니다. 인터페이스 파일 폴더 끝점, 우리는 의존성 주입, 미들웨어 코드를 보면 다음 각 인터페이스 봐.
영상

의존성 삽입 (Dependency Injection)

public static IIdentityServerBuilder AddIdentityServer(this IServiceCollection services)
{
    var builder = services.AddIdentityServerBuilder();

    builder
        .AddRequiredPlatformServices()
        .AddCookieAuthentication()
        .AddCoreServices()
        .AddDefaultEndpoints()
        .AddPluggableServices()
        .AddValidators()
        .AddResponseGenerators()
        .AddDefaultSecretParsers()
        .AddDefaultSecretValidators();

    // provide default in-memory implementation, not suitable for most production scenarios
    builder.AddInMemoryPersistedGrants();

    return builder;
}
  • AddRequiredPlatformServices - 사출 플랫폼 서비스
    • IHttpContextAccessor : HttpContext를 접근
    • IdentityServerOptions : 구성 클래스
 public static IIdentityServerBuilder AddRequiredPlatformServices(this IIdentityServerBuilder builder)
{
    builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();            
    builder.Services.AddOptions();
    builder.Services.AddSingleton(
        resolver => resolver.GetRequiredService<IOptions<IdentityServerOptions>>().Value);
    builder.Services.AddHttpClient();

    return builder;
}
  • AddCookieAuthentication - 주입 쿠키 서비스
    • 쿠키 인증 아키텍처 idsrv 사출 이름
    • 사출 IAuthenticationService 구현 IdentityServerAuthenticationService
    • 사출 IAuthenticationHandlerProvider 구현 FederatedSignoutAuthenticationHandlerProvider
public static IIdentityServerBuilder AddCookieAuthentication(this IIdentityServerBuilder builder)
{
    builder.Services.AddAuthentication(IdentityServerConstants.DefaultCookieAuthenticationScheme)
        .AddCookie(IdentityServerConstants.DefaultCookieAuthenticationScheme)
        .AddCookie(IdentityServerConstants.ExternalCookieAuthenticationScheme);

    builder.Services.AddSingleton<IConfigureOptions<CookieAuthenticationOptions>, ConfigureInternalCookieOptions>();
    builder.Services.AddSingleton<IPostConfigureOptions<CookieAuthenticationOptions>, PostConfigureInternalCookieOptions>();
    builder.Services.AddTransientDecorator<IAuthenticationService, IdentityServerAuthenticationService>();
    builder.Services.AddTransientDecorator<IAuthenticationHandlerProvider, FederatedSignoutAuthenticationHandlerProvider>();

    return builder;
}
  • AddCoreServices - 사출 핵심 서비스
/// <summary>
/// Adds the core services.
/// </summary>
/// <param name="builder">The builder.</param>
/// <returns></returns>
public static IIdentityServerBuilder AddCoreServices(this IIdentityServerBuilder builder)
{
    builder.Services.AddTransient<SecretParser>();
    builder.Services.AddTransient<SecretValidator>();
    builder.Services.AddTransient<ScopeValidator>();
    builder.Services.AddTransient<ExtensionGrantValidator>();
    builder.Services.AddTransient<BearerTokenUsageValidator>();
    builder.Services.AddTransient<JwtRequestValidator>();

    // todo: remove in 3.0
#pragma warning disable CS0618 // Type or member is obsolete
    builder.Services.AddTransient<BackChannelHttpClient>();
#pragma warning restore CS0618 // Type or member is obsolete

    builder.Services.AddTransient<ReturnUrlParser>();
    builder.Services.AddTransient<IdentityServerTools>();

    builder.Services.AddTransient<IReturnUrlParser, OidcReturnUrlParser>();
    builder.Services.AddScoped<IUserSession, DefaultUserSession>();
    builder.Services.AddTransient(typeof(MessageCookie<>));

    builder.Services.AddCors();
    builder.Services.AddTransientDecorator<ICorsPolicyProvider, CorsPolicyProvider>();

    return builder;
}
  • AddDefaultEndpoints - 인터페이스 주입
    • AuthorizeCallbackEndpoint : 인증 콜백 인터페이스
    • AuthorizeEndpoint : 인증 인터페이스
    • CheckSessionEndpoint는 : 대화 형 인터페이스를 확인
    • DeviceAuthorizationEndpoint : 인증 디바이스 인터페이스
    • DiscoveryEndpoint : 메타 데이터 키 인터페이스
    • DiscoveryEndpoint : 메타 데이터 인터페이스
    • EndSessionCallbackEndpoint : 세션 콜백 인터페이스를 종료
    • EndSessionEndpoint : 인터페이스 세션이 종료를
    • IntrospectionEndpoint : 인터페이스 토큰 쿼리
    • TokenRevocationEndpoint : REVOKE 토큰 인터페이스
    • TokenEndpoint : 지불 토큰 인터페이스
    • UserInfoEndpoint : 쿼리 사용자 인터페이스 정보
 public static IIdentityServerBuilder AddDefaultEndpoints(this IIdentityServerBuilder builder)
{
    builder.Services.AddTransient<IEndpointRouter, EndpointRouter>();

    builder.AddEndpoint<AuthorizeCallbackEndpoint>(EndpointNames.Authorize, ProtocolRoutePaths.AuthorizeCallback.EnsureLeadingSlash());
    builder.AddEndpoint<AuthorizeEndpoint>(EndpointNames.Authorize, ProtocolRoutePaths.Authorize.EnsureLeadingSlash());
    builder.AddEndpoint<CheckSessionEndpoint>(EndpointNames.CheckSession, ProtocolRoutePaths.CheckSession.EnsureLeadingSlash());
    builder.AddEndpoint<DeviceAuthorizationEndpoint>(EndpointNames.DeviceAuthorization, ProtocolRoutePaths.DeviceAuthorization.EnsureLeadingSlash());
    builder.AddEndpoint<DiscoveryKeyEndpoint>(EndpointNames.Discovery, ProtocolRoutePaths.DiscoveryWebKeys.EnsureLeadingSlash());
    builder.AddEndpoint<DiscoveryEndpoint>(EndpointNames.Discovery, ProtocolRoutePaths.DiscoveryConfiguration.EnsureLeadingSlash());
    builder.AddEndpoint<EndSessionCallbackEndpoint>(EndpointNames.EndSession, ProtocolRoutePaths.EndSessionCallback.EnsureLeadingSlash());
    builder.AddEndpoint<EndSessionEndpoint>(EndpointNames.EndSession, ProtocolRoutePaths.EndSession.EnsureLeadingSlash());
    builder.AddEndpoint<IntrospectionEndpoint>(EndpointNames.Introspection, ProtocolRoutePaths.Introspection.EnsureLeadingSlash());
    builder.AddEndpoint<TokenRevocationEndpoint>(EndpointNames.Revocation, ProtocolRoutePaths.Revocation.EnsureLeadingSlash());
    builder.AddEndpoint<TokenEndpoint>(EndpointNames.Token, ProtocolRoutePaths.Token.EnsureLeadingSlash());
    builder.AddEndpoint<UserInfoEndpoint>(EndpointNames.UserInfo, ProtocolRoutePaths.UserInfo.EnsureLeadingSlash());

    return builder;
}
  • AddPluggableServices는 - 플러그 서비스를 주입
public static IIdentityServerBuilder AddPluggableServices(this IIdentityServerBuilder builder)
{
    builder.Services.TryAddTransient<IPersistedGrantService, DefaultPersistedGrantService>();
    builder.Services.TryAddTransient<IKeyMaterialService, DefaultKeyMaterialService>();
    builder.Services.TryAddTransient<ITokenService, DefaultTokenService>();
    builder.Services.TryAddTransient<ITokenCreationService, DefaultTokenCreationService>();
    builder.Services.TryAddTransient<IClaimsService, DefaultClaimsService>();
    builder.Services.TryAddTransient<IRefreshTokenService, DefaultRefreshTokenService>();
    builder.Services.TryAddTransient<IDeviceFlowCodeService, DefaultDeviceFlowCodeService>();
    builder.Services.TryAddTransient<IConsentService, DefaultConsentService>();
    builder.Services.TryAddTransient<ICorsPolicyService, DefaultCorsPolicyService>();
    builder.Services.TryAddTransient<IProfileService, DefaultProfileService>();
    builder.Services.TryAddTransient<IConsentMessageStore, ConsentMessageStore>();
    builder.Services.TryAddTransient<IMessageStore<LogoutMessage>, ProtectedDataMessageStore<LogoutMessage>>();
    builder.Services.TryAddTransient<IMessageStore<EndSession>, ProtectedDataMessageStore<EndSession>>();
    builder.Services.TryAddTransient<IMessageStore<ErrorMessage>, ProtectedDataMessageStore<ErrorMessage>>();
    builder.Services.TryAddTransient<IIdentityServerInteractionService, DefaultIdentityServerInteractionService>();
    builder.Services.TryAddTransient<IDeviceFlowInteractionService, DefaultDeviceFlowInteractionService>();
    builder.Services.TryAddTransient<IAuthorizationCodeStore, DefaultAuthorizationCodeStore>();
    builder.Services.TryAddTransient<IRefreshTokenStore, DefaultRefreshTokenStore>();
    builder.Services.TryAddTransient<IReferenceTokenStore, DefaultReferenceTokenStore>();
    builder.Services.TryAddTransient<IUserConsentStore, DefaultUserConsentStore>();
    builder.Services.TryAddTransient<IHandleGenerationService, DefaultHandleGenerationService>();
    builder.Services.TryAddTransient<IPersistentGrantSerializer, PersistentGrantSerializer>();
    builder.Services.TryAddTransient<IEventService, DefaultEventService>();
    builder.Services.TryAddTransient<IEventSink, DefaultEventSink>();
    builder.Services.TryAddTransient<IUserCodeService, DefaultUserCodeService>();
    builder.Services.TryAddTransient<IUserCodeGenerator, NumericUserCodeGenerator>();
    builder.Services.TryAddTransient<IBackChannelLogoutService, DefaultBackChannelLogoutService>();

    builder.AddJwtRequestUriHttpClient();
    builder.AddBackChannelLogoutHttpClient();
    //builder.Services.AddHttpClient<BackChannelLogoutHttpClient>();
    //builder.Services.AddHttpClient<JwtRequestUriHttpClient>();

    builder.Services.AddTransient<IClientSecretValidator, ClientSecretValidator>();
    builder.Services.AddTransient<IApiSecretValidator, ApiSecretValidator>();

    builder.Services.TryAddTransient<IDeviceFlowThrottlingService, DistributedDeviceFlowThrottlingService>();
    builder.Services.AddDistributedMemoryCache();

    return builder;
}
  • AddValidators - 사출 검증 클래스
public static IIdentityServerBuilder AddValidators(this IIdentityServerBuilder builder)
{
    // core
    builder.Services.TryAddTransient<IEndSessionRequestValidator, EndSessionRequestValidator>();
    builder.Services.TryAddTransient<ITokenRevocationRequestValidator, TokenRevocationRequestValidator>();
    builder.Services.TryAddTransient<IAuthorizeRequestValidator, AuthorizeRequestValidator>();
    builder.Services.TryAddTransient<ITokenRequestValidator, TokenRequestValidator>();
    builder.Services.TryAddTransient<IRedirectUriValidator, StrictRedirectUriValidator>();
    builder.Services.TryAddTransient<ITokenValidator, TokenValidator>();
    builder.Services.TryAddTransient<IIntrospectionRequestValidator, IntrospectionRequestValidator>();
    builder.Services.TryAddTransient<IResourceOwnerPasswordValidator, NotSupportedResourceOwnerPasswordValidator>();
    builder.Services.TryAddTransient<ICustomTokenRequestValidator, DefaultCustomTokenRequestValidator>();
    builder.Services.TryAddTransient<IUserInfoRequestValidator, UserInfoRequestValidator>();
    builder.Services.TryAddTransient<IClientConfigurationValidator, DefaultClientConfigurationValidator>();
    builder.Services.TryAddTransient<IDeviceAuthorizationRequestValidator, DeviceAuthorizationRequestValidator>();
    builder.Services.TryAddTransient<IDeviceCodeValidator, DeviceCodeValidator>();

    // optional
    builder.Services.TryAddTransient<ICustomTokenValidator, DefaultCustomTokenValidator>();
    builder.Services.TryAddTransient<ICustomAuthorizeRequestValidator, DefaultCustomAuthorizeRequestValidator>();
    
    return builder;
}
  • AddResponseGenerators - 생성 된 클래스 주입에 응답
public static IIdentityServerBuilder AddResponseGenerators(this IIdentityServerBuilder builder)
{
    builder.Services.TryAddTransient<ITokenResponseGenerator, TokenResponseGenerator>();
    builder.Services.TryAddTransient<IUserInfoResponseGenerator, UserInfoResponseGenerator>();
    builder.Services.TryAddTransient<IIntrospectionResponseGenerator, IntrospectionResponseGenerator>();
    builder.Services.TryAddTransient<IAuthorizeInteractionResponseGenerator, AuthorizeInteractionResponseGenerator>();
    builder.Services.TryAddTransient<IAuthorizeResponseGenerator, AuthorizeResponseGenerator>();
    builder.Services.TryAddTransient<IDiscoveryResponseGenerator, DiscoveryResponseGenerator>();
    builder.Services.TryAddTransient<ITokenRevocationResponseGenerator, TokenRevocationResponseGenerator>();
    builder.Services.TryAddTransient<IDeviceAuthorizationResponseGenerator, DeviceAuthorizationResponseGenerator>();

    return builder;
}
  • AddDefaultSecretParsers & AddDefaultSecretValidators
/// <summary>
/// Adds the default secret parsers.
/// </summary>
/// <param name="builder">The builder.</param>
/// <returns></returns>
public static IIdentityServerBuilder AddDefaultSecretParsers(this IIdentityServerBuilder builder)
{
    builder.Services.AddTransient<ISecretParser, BasicAuthenticationSecretParser>();
    builder.Services.AddTransient<ISecretParser, PostBodySecretParser>();

    return builder;
}

/// <summary>
/// Adds the default secret validators.
/// </summary>
/// <param name="builder">The builder.</param>
/// <returns></returns>
public static IIdentityServerBuilder AddDefaultSecretValidators(this IIdentityServerBuilder builder)
{
    builder.Services.AddTransient<ISecretValidator, HashedSharedSecretValidator>();

    return builder;
}

IdentityServerOptions - 클래스 구성

 /// <summary>
/// The IdentityServerOptions class is the top level container for all configuration settings of IdentityServer.
/// </summary>
public class IdentityServerOptions
{
    /// <summary>
    /// Gets or sets the unique name of this server instance, e.g. https://myissuer.com.
    /// If not set, the issuer name is inferred from the request
    /// </summary>
    /// <value>
    /// Unique name of this server instance, e.g. https://myissuer.com
    /// </value>
    public string IssuerUri { get; set; }

    /// <summary>
    /// Gets or sets the origin of this server instance, e.g. https://myorigin.com.
    /// If not set, the origin name is inferred from the request
    /// Note: Do not set a URL or include a path.
    /// </summary>
    /// <value>
    /// Origin of this server instance, e.g. https://myorigin.com
    /// </value>
    public string PublicOrigin { get; set; }

    /// <summary>
    /// Gets or sets the value for the JWT typ header for access tokens.
    /// </summary>
    /// <value>
    /// The JWT typ value.
    /// </value>
    public string AccessTokenJwtType { get; set; } = "at+jwt";

    /// <summary>
    /// Emits an aud claim with the format issuer/resources. That's needed for some older access token validation plumbing. Defaults to false.
    /// </summary>
    public bool EmitLegacyResourceAudienceClaim { get; set; } = false;

    /// <summary>
    /// Gets or sets the endpoint configuration.
    /// </summary>
    /// <value>
    /// The endpoints configuration.
    /// </value>
    public EndpointsOptions Endpoints { get; set; } = new EndpointsOptions();

    /// <summary>
    /// Gets or sets the discovery endpoint configuration.
    /// </summary>
    /// <value>
    /// The discovery endpoint configuration.
    /// </value>
    public DiscoveryOptions Discovery { get; set; } = new DiscoveryOptions();

    /// <summary>
    /// Gets or sets the authentication options.
    /// </summary>
    /// <value>
    /// The authentication options.
    /// </value>
    public AuthenticationOptions Authentication { get; set; } = new AuthenticationOptions();

    /// <summary>
    /// Gets or sets the events options.
    /// </summary>
    /// <value>
    /// The events options.
    /// </value>
    public EventsOptions Events { get; set; } = new EventsOptions();

    /// <summary>
    /// Gets or sets the max input length restrictions.
    /// </summary>
    /// <value>
    /// The length restrictions.
    /// </value>
    public InputLengthRestrictions InputLengthRestrictions { get; set; } = new InputLengthRestrictions();

    /// <summary>
    /// Gets or sets the options for the user interaction.
    /// </summary>
    /// <value>
    /// The user interaction options.
    /// </value>
    public UserInteractionOptions UserInteraction { get; set; } = new UserInteractionOptions();

    /// <summary>
    /// Gets or sets the caching options.
    /// </summary>
    /// <value>
    /// The caching options.
    /// </value>
    public CachingOptions Caching { get; set; } = new CachingOptions();

    /// <summary>
    /// Gets or sets the cors options.
    /// </summary>
    /// <value>
    /// The cors options.
    /// </value>
    public CorsOptions Cors { get; set; } = new CorsOptions();

    /// <summary>
    /// Gets or sets the Content Security Policy options.
    /// </summary>
    public CspOptions Csp { get; set; } = new CspOptions();

    /// <summary>
    /// Gets or sets the validation options.
    /// </summary>
    public ValidationOptions Validation { get; set; } = new ValidationOptions();

    /// <summary>
    /// Gets or sets the device flow options.
    /// </summary>
    public DeviceFlowOptions DeviceFlow { get; set; } = new DeviceFlowOptions();

    /// <summary>
    /// Gets or sets the mutual TLS options.
    /// </summary>
    public MutualTlsOptions MutualTls { get; set; } = new MutualTlsOptions();
}

UserIdentityServer - 미들웨어 논리

  • 체크섬을 수행
  • BaseUrlMiddleware 미들웨어 : 설정 base을
  • CORS는 크로스 도메인을 구성 : CorsPolicyProvider 클라이언트 정보를 기반으로 동적 전략을 생성
  • 당신이 IdentityServer를 사용하는 경우 IdentityServerMiddlewareOptions 기본 통화 UseAuthentication, 그렇게하지 등록 인증 미들웨어를 반복
  • 사용 MutualTlsTokenEndpointMiddleware 미들웨어 : 클라이언트 요구 사항, 서버가 HTTPS를 사용은 기본이 열려 있지 않습니다
  • 사용 IdentityServerMiddleware 미들웨어 : IEndpointRouter이 EndPointHandler 과정 요청에 의해 발견하는 경우, 요청에 따라 IEndpointHandler 일치 찾을 수 있습니다.
public static IApplicationBuilder UseIdentityServer(this IApplicationBuilder app, IdentityServerMiddlewareOptions options = null)
{
    app.Validate();

    app.UseMiddleware<BaseUrlMiddleware>();

    app.ConfigureCors();

    // it seems ok if we have UseAuthentication more than once in the pipeline --
    // this will just re-run the various callback handlers and the default authN 
    // handler, which just re-assigns the user on the context. claims transformation
    // will run twice, since that's not cached (whereas the authN handler result is)
    // related: https://github.com/aspnet/Security/issues/1399
    if (options == null) options = new IdentityServerMiddlewareOptions();
    options.AuthenticationMiddleware(app);

    app.UseMiddleware<MutualTlsTokenEndpointMiddleware>();
    app.UseMiddleware<IdentityServerMiddleware>();

    return app;
}

발문

idsv 코드의 양이 클래스의 번호로, 매우 큽니다. 그러나 매우 표준 코딩 스타일, 상황은 매우 분명하다.

추천

출처www.cnblogs.com/holdengong/p/12578558.html