通过ASP .NET Core连接到Google API会导致无休止的授权循环 [英] Connect to Google api via asp .net core causes endless authorization loop

查看:65
本文介绍了通过ASP .NET Core连接到Google API会导致无休止的授权循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试建立一个Asp .net core 3 Web项目,以连接到Google日历并在用户登录后请求用户数据.

I am currently trying to set up an Asp .net core 3 web project to connect to Google calendar and request user data after the user has logged in.

用户登录,应用程序请求访问其数据的权限.从那以后问题开始了.

The user logs in and the application requests permission to access their data. The problems start after that.

   // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlite(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();
        services.AddControllersWithViews();
        services.AddRazorPages();

        services
            .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie()
            .AddGoogleOpenIdConnect(options =>
            {
                IConfigurationSection googleAuthSection = Configuration.GetSection("Authentication:Google");
                options.ClientId = googleAuthSection["ClientId"];
                options.ClientSecret = googleAuthSection["ClientSecret"];
                options.Scope.Add(Google.Apis.Calendar.v3.CalendarService.Scope.Calendar);
            });
    }

控制器

public class CalController : Controller
{
    private readonly ILogger<CalController> _logger;

    public CalController(ILogger<CalController> logger)
    {
        _logger = logger;
    }

    [Authorize]
    public async Task<IActionResult> Index([FromServices] IGoogleAuthProvider auth)
    {
        var cred = await auth.GetCredentialAsync();
        var service = new CalendarService(new BaseClientService.Initializer
        {
            HttpClientInitializer = cred
        });
        var calendar = await service.Calendars.Get("primary").ExecuteAsync();

        return View();
    }
   
}

问题

当前系统正在循环运行.当我导航到日历控制器时,它会出现以下错误.

Issue

Currently the system is looping on me. When i navigate to the calendar controller It comes with the following error.

因此,我通过以下操作创建了一个帐户控制器.

So i created an account controller with the following action.

 public IActionResult Logins([FromQuery] string returnURL)
    {
        return RedirectToAction("Index", "Cal");           
        
    }

这只是导致整个循环.为什么authorize属性没有检测到已登录并已通过身份验证?

Which now just causes the whole thing to loop. Why isn't the authorize attribute detecting that it is logged in and authenticated?

如果我删除授权属性.登录用户并直接转到cal控制器,我可以访问他们的数据,并且一切正常.

If I remove the authorize attribute. Login the user and go directly to the cal controller i have access to their data and it all works.

但是,一旦我添加了authorize属性,它就无法检测到它已通过身份验证.

But as soon as i add the authorize attributed it cant detect that it is authenticated.

我最初将此内容发布到Google .net客户端库 1584 不幸的是,即使应该工作,团队也无法协助它与asp .net core一起工作.

I originally posted this over on the Google .net client libary 1584 unfortunately the team was not able to assist in getting this to work with asp .net core even though it is supposed to work.

我怀疑我的设置有问题,但是我很茫然地想知道问题可能出在哪里.

I suspect there is something wrong with my setup but i am at a lost to figure out what the issue could be.

推荐答案

我终于可以正常工作了.

I finally got this working.

public class Client
    {
        public class Web
        {
            public string client_id { get; set; }
            public string client_secret { get; set; }
        }

        public Web web { get; set; }
    }



    public class ClientInfo
    {
        public Client Client { get; set;  }

        private readonly IConfiguration _configuration;

        public ClientInfo(IConfiguration configuration)
        {
            _configuration = configuration;
            Client = Load();
        }

        private Client Load()
        {
            var filePath = _configuration["TEST_WEB_CLIENT_SECRET_FILENAME"];
            if (string.IsNullOrEmpty(filePath))
            {
                throw new InvalidOperationException(
                    $"Please set the TEST_WEB_CLIENT_SECRET_FILENAME environment variable before running tests.");
            }

            if (!File.Exists(filePath))
            {
                throw new InvalidOperationException(
                    $"Please set the TEST_WEB_CLIENT_SECRET_FILENAME environment variable before running tests.");
            }

            var x = File.ReadAllText(filePath);

            return JsonConvert.DeserializeObject<Client>(File.ReadAllText(filePath));
        }
    }

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<ClientInfo>();

            services.AddControllers();

            services.AddAuthentication(o =>
                {
                    // This is for challenges to go directly to the Google OpenID Handler, so there's no
                    // need to add an AccountController that emits challenges for Login.
                    o.DefaultChallengeScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
                    // This is for forbids to go directly to the Google OpenID Handler, which checks if
                    // extra scopes are required and does automatic incremental auth.
                    o.DefaultForbidScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
                    o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                })
                .AddCookie()
                .AddGoogleOpenIdConnect(options =>
                {
                    var clientInfo = new ClientInfo(Configuration);
                    options.ClientId = clientInfo.Client.web.client_id;
                    options.ClientSecret = clientInfo.Client.web.client_secret;
                });
            services.AddMvc();
        }


        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();
            
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        }
    }

具有身份验证的控制器

[ApiController]
[Route("[controller]")]
public class GAAnalyticsController : ControllerBase
{
    
    private readonly ILogger<WeatherForecastController> _logger;

    public GAAnalyticsController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    // Test showing use of incremental auth.
    // This attribute states that the listed scope(s) must be authorized in the handler.
    [GoogleScopedAuthorize(AnalyticsReportingService.ScopeConstants.AnalyticsReadonly)]
    public async Task<GetReportsResponse> Get([FromServices] IGoogleAuthProvider auth, [FromServices] ClientInfo clientInfo)
    {
        var GoogleAnalyticsViewId = "78110423";

        var cred = await auth.GetCredentialAsync();
        var service = new  AnalyticsReportingService(new BaseClientService.Initializer
        {
            HttpClientInitializer = cred
        });
        
        var dateRange = new DateRange
        {
            StartDate = "2015-06-15",
            EndDate = "2015-06-30"
        };

        // Create the Metrics object.
        var sessions = new Metric
        {
            Expression = "ga:sessions",
            Alias = "Sessions"
        };

        //Create the Dimensions object.
        var browser = new Dimension
        {
            Name = "ga:browser"
        };

        // Create the ReportRequest object.
        var reportRequest = new ReportRequest
        {
            ViewId = GoogleAnalyticsViewId,
            DateRanges = new List<DateRange> {dateRange},
            Dimensions = new List<Dimension> {browser},
            Metrics = new List<Metric> {sessions}
        };

        var requests = new List<ReportRequest> {reportRequest};

        // Create the GetReportsRequest object.
        var getReport = new GetReportsRequest {ReportRequests = requests};

        // Make the request.
        var response = service.Reports.BatchGet(getReport).Execute();
        return response;
    }
}

这篇关于通过ASP .NET Core连接到Google API会导致无休止的授权循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆