OpenIdDict-禁用XHR请求的“连接/授权”重定向

时间:2018-08-06 16:46:19

标签: google-oauth google-oauth2 openiddict

我正在使用openIdDict的示例MVC应用程序来实现授权代码流。但是,我有一个我要用于用户授权请求的登录页面的angular 6应用程序。我已经完成了所有的工作,但是当我提交“连接/授权”请求时,它会生成302。浏览器捕获了302,并且发生了重定向,但是我不希望这样。我希望请求为200,然后angular应用程序可以从那里控制重定向。

我要这样做的原因: 1.我要集成的系统需要在重定向中填充其他查询字符串参数(状态*其他)。我希望我的角度应用程序填充这些内容,而不连接/授权。 2.在允许授权之后但在重定向发生之前,角度应用程序将为用户提供其他说明/信息。

我的问题是这样: 1.是否可以更改openiddict生成的响应代码? 2.我在这里偏离了轨道,使它变得比应有的难吗?

Startup.cs配置

            services.AddOpenIddict()
            .AddCore(coreOptions =>
            {
                coreOptions.UseEntityFrameworkCore().UseDbContext<ApplicationDbContext>();
            })
            .AddServer(serverOptions =>
            {
                serverOptions.UseMvc();

                serverOptions.EnableAuthorizationEndpoint(oauthOptions.AuthorizePath)
                .EnableTokenEndpoint(oauthOptions.TokenPath)
                       .EnableLogoutEndpoint(oauthOptions.LogoutPath);

                serverOptions.AllowAuthorizationCodeFlow()
                       .AllowPasswordFlow()
                       .AllowRefreshTokenFlow();

                serverOptions.SetAccessTokenLifetime(new TimeSpan(0, oauthOptions.AccessTokenLifetimeMinutes, 0));
                serverOptions.SetRefreshTokenLifetime(new TimeSpan(0, oauthOptions.RefreshTokenLifetimeMinutes, 0));

                if (!oauthOptions.RequireSSL)
                {
                    serverOptions.DisableHttpsRequirement();
                }

            });

2 个答案:

答案 0 :(得分:0)

在只有一种情况下,OpenIddict会透明地执行此操作:这是在您明确启用请求缓存时:

services.AddOpenIddict()
    .AddCore(options =>
    {
        // ...
    })

    .AddServer(options =>
    {
        // ...
        options.EnableRequestCaching();
    });

启用此功能后,此功能会将授权请求存储在IDistributedCache中,并用单个request_id参数代替授权请求参数,该参数用于表示请求。为此,它确实使用了302重定向。

如果您不喜欢这种行为,只需不要在OpenIddict服务器选项中调用options.EnableRequestCaching()

答案 1 :(得分:0)

我决定编写自己的中间件,该中间件将拦截Identity生成的302请求,并将其替换为带有JSON正文的200请求。我敢肯定,这可以简化,也许我只是想念一些大事,而我却偏离了方向。最重要的是,该解决方案允许某人使用ajax实现授权代码流。

Startup.cs

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        //put this before any other middleware runs
        app.UseMiddleware<AuthorizeRequestMiddleware>();
        ...
    }

AuthorizeRequestMiddleware

public class AuthorizeRequestMiddleware
{
    private readonly RequestDelegate _next;

    public AuthorizeRequestMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        context.Response.OnStarting(AuthorizeStartingHandler, state: context);

        // Let the middleware pipeline run
        await _next(context);
    }

    private Task AuthorizeStartingHandler(object context)
    {

        HttpContext httpContext = (HttpContext)context;
        if (httpContext.Request.Path.HasValue && httpContext.Request.Path.Value == "/connect/authorize")
        {
            httpContext.Response.StatusCode = (int)HttpStatusCode.OK;
            AuthorizationCodeResponse responseBody = new AuthorizationCodeResponse(httpContext.Response.Headers["Location"][0]);
            httpContext.Response.WriteAsync(JsonConvert.SerializeObject(responseBody));
        }

        return Task.CompletedTask;
    }
}

AuthorizationCodeResponse 这是我自己的课。您可以根据需要使响应看起来像

public class AuthorizationCodeResponse
{
    public AuthorizationCodeResponse(string redirectUri)
    {
        this.RedirectUri = redirectUri;
    }

    public string RedirectUri { get; set; }
}