IdentityServer4学习笔记

Posted webassembly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IdentityServer4学习笔记相关的知识,希望对你有一定的参考价值。

本人学习笔记,理解的可能不对,请前辈们指教。

1、 Endpoint 和 EndpointHandler 
Endpoint代表一个 url地址,EndpointHandler是这个 Endpoint对应的 处理器。当 请求这个url时,相应的EndpointHandler生成响应流。
具体实现思路是,EndpointHandler(或者说IEndpointHandler接口)的 ProcessAsync(感觉方法名应该叫ProcessRequestAsync)方法返回一个IEndpointResult对象,
IEndpointResult对象的ExecuteAsync方法执行时,向 响应上下文中写入响应流,即context.Response.WriteXXXX
 
context.Response.WritehtmlAsync(html);
context.Response.WriteHtmlAsync(GetFormPostHtml());
context.Response.WriteJsonAsync(ObjectSerializer.ToJObject(this.Entries));
context.Response.WriteJsonAsync(jobject);
context.Response.Redirect(BuildRedirectUri());
context.Response.RedirectToAbsoluteUrl(url);
 
IEndpointHandler接口:
Task<IEndpointResult> ProcessAsync(HttpContext context);
 
IEndpointResult接口:
Task ExecuteAsync(HttpContext context);
 
2、在 Startup 中 ConfigureServices 注册所有的 Endpoint 和 EndpointHandler 
 
这些 EndpointHandler有
AuthorizeEndpoint、 
AuthorizeCallbackEndpoint、 
TokenEndpoint、 
DiscoveryEndpoint、 
CheckSessionEndpoint、
EndSessionEndpoint、
UserInfoEndpoint
 
EndpointRouter 实现 IEndpointRouter接口,该接口的 Find(HttpContext context)方法根据 url地址返回一个 IEndpointHandler对象。
是通过 AddDefaultEndpoints 方法注册的这些 IEndpointHandler。
 
3、在 Startup 中 Configure方法中加入一个 IdentityServerMiddleware 中介件,用于处理 相关url请求。
 
IdentityServerMiddleware的Invoke方法中 根据请求上下文,利用EndpointRouter得到一个IEndpointHandler,调用其ProcessAsync得到一个IEndpointResult对象,
再调用IEndpointResult对象的ExecuteAsync方法生成响应流。
 
IEndpointResult对象有:
AuthorizeResult
CheckSessionResult
EndSessionResult
TokenResult
UserInfoResult
ConsentPageResult 
LoginPageResult
DiscoveryDocumentResult
StatusCodeResult
CustomRedirectResult

 看看下面这些很熟悉的 url片段:

 

public const string Authorize = "connect/authorize";
public const string AuthorizeCallback = Authorize + "/callback";
public const string DiscoveryConfiguration = ".well-known/openid-configuration";
public const string DiscoveryWebKeys = DiscoveryConfiguration + "/jwks";
public const string Token = "connect/token";
public const string Revocation = "connect/revocation";
public const string UserInfo = "connect/userinfo";
public const string Introspection = "connect/introspect";
public const string EndSession = "connect/endsession";
public const string EndSessionCallback = EndSession + "/callback";
public const string CheckSession = "connect/checksession";

 

看看下面代码,一目了然:
internal class TokenEndpoint : IEndpointHandler
{
    private readonly IClientSecretValidator _clientValidator;
    private readonly ITokenRequestValidator _requestValidator;
    private readonly ITokenResponseGenerator _responseGenerator;

    public async Task<IEndpointResult> ProcessAsync(HttpContext context)
    {
        return await ProcessTokenRequestAsync(context);
    }

    private async Task<IEndpointResult> ProcessTokenRequestAsync(HttpContext context)
    {
        var clientResult = await _clientValidator.ValidateAsync(context); 
        var requestResult = await _requestValidator.ValidateRequestAsync(form, clientResult);
        var response = await _responseGenerator.ProcessAsync(requestResult);
        return new TokenResult(response);
    }
}
internal class AuthorizeEndpoint : AuthorizeEndpointBase
{
    public override async Task<IEndpointResult> ProcessAsync(HttpContext context)
    {
        
        var user = await UserSession.GetUserAsync();
        var result = await ProcessAuthorizeRequestAsync(values, user, null);
        return result;
    }
}

internal abstract class AuthorizeEndpointBase : IEndpointHandler
{
    private readonly IAuthorizeRequestValidator _validator;
    private readonly IAuthorizeInteractionResponseGenerator _interactionGenerator;
    private readonly IAuthorizeResponseGenerator _authorizeResponseGenerator;
    
    internal async Task<IEndpointResult> ProcessAuthorizeRequestAsync(NameValueCollection parameters, ClaimsPrincipal user, ConsentResponse consent)
    {
        var result = await _validator.ValidateAsync(parameters, user);
        var request = result.ValidatedRequest;
        var interactionResult = await _interactionGenerator.ProcessInteractionAsync(request, consent);
        if (interactionResult.IsLogin) { return new LoginPageResult(request); }
        if (interactionResult.IsConsent) { return new ConsentPageResult(request);}
        if (interactionResult.IsRedirect){ return new CustomRedirectResult(request, interactionResult.RedirectUrl); }
        var response = await _authorizeResponseGenerator.CreateResponseAsync(request);
        return new AuthorizeResult(response);
    }
}

public class TokenResponseGenerator : ITokenResponseGenerator
{
    public virtual async Task<TokenResponse> ProcessAsync(TokenRequestValidationResult request)
        {
            switch (request.ValidatedRequest.GrantType)
            {
                case OidcConstants.GrantTypes.ClientCredentials:
                    return await ProcessClientCredentialsRequestAsync(request);
                case OidcConstants.GrantTypes.Password:
                    return await ProcessPasswordRequestAsync(request);
                case OidcConstants.GrantTypes.AuthorizationCode:
                    return await ProcessAuthorizationCodeRequestAsync(request);
                case OidcConstants.GrantTypes.RefreshToken:
                    return await ProcessRefreshTokenRequestAsync(request);
                default:
                    return await ProcessExtensionGrantRequestAsync(request);// 这是扩展点
            }
        }
}

public class AuthorizeResponseGenerator : IAuthorizeResponseGenerator
{
    public virtual async Task<AuthorizeResponse> CreateResponseAsync(ValidatedAuthorizeRequest request)
        {
            if (request.GrantType == GrantType.AuthorizationCode)
            {
                return await CreateCodeFlowResponseAsync(request);
            }
            if (request.GrantType == GrantType.Implicit)
            {
                return await CreateImplicitFlowResponseAsync(request);
            }
            if (request.GrantType == GrantType.Hybrid)
            {
                return await CreateHybridFlowResponseAsync(request);
            }
        // 这里就没扩展点了,如果真要扩展AuthorizeResult,可以在这里加代码
Logger.LogError(
"Unsupported grant type: " + request.GrantType); throw new InvalidOperationException("invalid grant type: " + request.GrantType); } }
4、验证过程与结果
改天有空再写

以上是关于IdentityServer4学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段

DOM探索之基础详解——学习笔记

IdentityServer4学习记录

学习 skoruba/ IdentityServer4.Admin 完整版

学习笔记 链接

ReactJs学习笔记01