Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用asp.net core 2.2授予外部验证且未在my WebApp中注册的用户访问权限?_C#_Asp.net Core_Identity_Claims Based Identity_Asp.net Core 2.2 - Fatal编程技术网

C# 如何使用asp.net core 2.2授予外部验证且未在my WebApp中注册的用户访问权限?

C# 如何使用asp.net core 2.2授予外部验证且未在my WebApp中注册的用户访问权限?,c#,asp.net-core,identity,claims-based-identity,asp.net-core-2.2,C#,Asp.net Core,Identity,Claims Based Identity,Asp.net Core 2.2,摘要 这是我第一次尝试OAuth2和外部登录机制 我正在创建一个WebApp,它将通过一个用户友好的UI公开API特性 为了进行API调用,我需要从QBO接收一个访问令牌,该令牌授予对资源的访问权 所以,我的WebApp有一个外部登录选项,我用它来对QBO进行身份验证,然后授权我的应用 一切正常,直到 服务配置 基于GitHub身份验证教程,我提出了这个 services.AddAuthentication(o => { o.DefaultAuth

摘要

这是我第一次尝试OAuth2和外部登录机制

我正在创建一个WebApp,它将通过一个用户友好的UI公开API特性

为了进行API调用,我需要从QBO接收一个访问令牌,该令牌授予对资源的访问权

所以,我的WebApp有一个外部登录选项,我用它来对QBO进行身份验证,然后授权我的应用

一切正常,直到

服务配置

基于GitHub身份验证教程,我提出了这个

        services.AddAuthentication(o => {
            o.DefaultAuthenticateScheme = IdentityConstants.ExternalScheme;
            o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
            o.DefaultChallengeScheme = IdentityConstants.ExternalScheme;
        })
            .AddOAuth("qbo", "qbo", o => {
                o.CallbackPath = new PathString("/signin-qbo");
                o.ClientId = Configuration["ecm.qbo.client-id"];
                o.ClientSecret = Configuration["ecm.qbo.client-secret"];
                o.SaveTokens = true;
                o.Scope.Add("openid");
                o.Scope.Add("profile");
                o.Scope.Add("email");
                o.Scope.Add("com.intuit.quickbooks.accounting");

                o.AuthorizationEndpoint = Configuration["ecm.qbo.authorization-endpoint"];
                o.TokenEndpoint = Configuration["ecm.qbo.token-endpoint"];
                o.UserInformationEndpoint = Configuration["ecm.qbo.user-info-endpoint"];

                o.Events.OnCreatingTicket = async context => {
                    var companyId = context.Request.Query["realmid"].FirstOrDefault() ?? throw new ArgumentNullException("realmId");
                    var accessToken = context.AccessToken;
                    var refreshToken = context.RefreshToken;

                    Configuration["ecm.qbo.access-token"] = accessToken;
                    Configuration["ecm.qbo.refresh-token"] = refreshToken;
                    Configuration["ecm.qbo.realm-id"] = companyId;

                    context.Backchannel.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
                    context.Backchannel.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    var response = await context.Backchannel.GetStringAsync(context.Options.UserInformationEndpoint);

                    var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);

                    var user = (ClaimsIdentity)context.Principal.Identity;
                    user.AddClaims(new Claim[] {
                        new Claim("access_token", accessToken),
                        new Claim("refresh_token", refreshToken),
                        new Claim(ClaimTypes.GivenName, result["givenName"]),
                        new Claim(ClaimTypes.Surname, result["familyName"]),
                        new Claim(ClaimTypes.Email, result["email"]),
                        new Claim(ClaimTypes.Name, result["givenName"]+" "+result["familyName"])
                    });
                };
            });
services.AddAuthentication(o=>{
o、 DefaultAuthenticateScheme=IdentityConstants.ExternalScheme;
o、 DefaultSignInScheme=IdentityConstants.ExternalScheme;
o、 DefaultChallengeScheme=IdentityConstants.ExternalScheme;
})
.AddOAuth(“qbo”,“qbo”,o=>{
o、 回调路径=新路径字符串(“/signin qbo”);
o、 ClientId=配置[“ecm.qbo.client id”];
o、 ClientSecret=Configuration[“ecm.qbo.client secret”];
o、 SaveTokens=true;
o、 范围。添加(“openid”);
o、 范围。添加(“简介”);
o、 范围。添加(“电子邮件”);
o、 Scope.Add(“com.intuit.quickbooks.accounting”);
o、 AuthorizationEndpoint=配置[“ecm.qbo.authorization endpoint”];
o、 TokenEndpoint=配置[“ecm.qbo.TokenEndpoint”];
o、 UserInformationEndpoint=配置[“ecm.qbo.user info endpoint”];
o、 Events.OnCreatingTicket=异步上下文=>{
var companyId=context.Request.Query[“realmid”].FirstOrDefault()??抛出新的ArgumentNullException(“realmid”);
var accessToken=context.accessToken;
var refreshttoken=context.refreshttoken;
配置[“ecm.qbo.access token”]=accessToken;
配置[“ecm.qbo.refreshToken”]=refreshToken;
配置[“ecm.qbo.realm id”]=公司id;
context.Backchannel.DefaultRequestHeaders.Authorization=新的AuthenticationHeaderValue(“承载者”,context.AccessToken);
context.Backchannel.DefaultRequestHeaders.Accept.Add(新的MediaTypeWithQualityHeaderValue(“应用程序/json”);
var response=wait context.Backchannel.GetStringAsync(context.Options.UserInformationEndpoint);
var result=JsonConvert.DeserializeObject(响应);
var user=(ClaimsIdentity)context.Principal.Identity;
user.AddClaims(新索赔[]{
新声明(“访问令牌”,accessToken),
新索赔(“刷新令牌”,刷新令牌),
新索赔(ClaimTypes.GivenName,结果[“GivenName]”),
新索赔(索赔类型.姓氏,结果[“familyName”]),
新索赔(ClaimTypes.Email,结果[“Email”]),
新索赔(ClaimTypes.Name,结果[“givenName”]+“”+结果[“familyName”])
});
};
});
这很有效。我可以根据用户信息添加声明,context.Principal.Identity表示它已通过身份验证

出于某些原因,它似乎试图重定向到`/Identity/Account/Login?returnUrl=%2F。为什么呢

登录页面重定向

在这里,我不明白为什么我得到重定向,这让我很困惑。因此,我添加AccountController只是为了尝试关闭它

namespace ecm.backoffice.Controllers {
    [Authorize]
    [Route("[controller]/[action]")]
    public class AccountController : Controller {
        [AllowAnonymous]
        [HttpGet]
        public IActionResult Login(string returnUrl = "/") {
            return Challenge(new AuthenticationProperties { RedirectUri = returnUrl });
        }

        [Authorize]
        [HttpGet]
        public async Task<IActionResult> Logout(string returnUrl = "/") {
            await Request.HttpContext.SignOutAsync("qbo");
            return Redirect(returnUrl);
       }
    }
}
名称空间ecm.backoffice.Controllers{
[授权]
[路由(“[控制器]/[操作]”)]
公共类AccountController:控制器{
[异名]
[HttpGet]
public IActionResult登录(字符串returnUrl=“/”){
返回质询(新的AuthenticationProperties{RedirectUri=returnUrl});
}
[授权]
[HttpGet]
公共异步任务注销(字符串returnUrl=“/”){
wait Request.HttpContext.SignOutAsync(“qbo”);
返回重定向(returnUrl);
}
}
}
事实上,这造成了比解决问题更多的困惑。我在这里迷路了

应用迁移

这个个人用户身份验证WebApp似乎使用了Identity,这似乎创建了很多幕后机制。我首先尝试注册到我的应用程序,并且不得不“应用迁移”,我完全理解了这一点,因为数据模型没有初始化

因此,我单击了应用迁移按钮。我以为我可以接受这个

实体框架核心

我知道该应用程序正在使用Entity Framework Core作为其持久性机制,因此需要注册过程等。要对其进行配置,我需要将这些行添加到服务配置中

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>()
            .AddDefaultUI(UIFramework.Bootstrap4)
            .AddEntityFrameworkStores<ApplicationDbContext>();
services.AddDbContext

还有更多