C# 在mvc5应用程序中运行时更新OWIN AuthenticationOptions

C# 在mvc5应用程序中运行时更新OWIN AuthenticationOptions,c#,oauth-2.0,asp.net-identity-2,C#,Oauth 2.0,Asp.net Identity 2,嗨 情况如下: 我在iis7上有一个标识为2的MVC5应用程序,它服务于多个网站。 主机名是特定网站的密钥。 site.com, anothersite.com 等等 我已经决定在我所有的网站上使用谷歌外部登录,每个网站都应该是带有个人clientid和clientsecret的谷歌客户端。 例如: site.com-clientid=123123,clientsecret=xxxaaabbb anothersite.com-clientid=890890,clientsecret=zzzqqe

情况如下:
我在iis7上有一个标识为2的MVC5应用程序,它服务于多个网站。 主机名是特定网站的密钥。
site.com, anothersite.com 等等

我已经决定在我所有的网站上使用谷歌外部登录,每个网站都应该是带有个人clientid和clientsecret的谷歌客户端。
例如:
site.com-clientid=123123,clientsecret=xxxaaabbb
anothersite.com-clientid=890890,clientsecret=zzzqqeee

但是有一个小问题--
AuthenticationOptions
是在应用程序启动时设置的,我没有找到任何方法在运行时替换它

那么,看完以后, 及 我已经意识到我应该重写AuthenticationHandler.ApplyResponseChallengeAsync() 将这段代码放在这个方法的开头:

Options.ClientId=OAuth2Helper.GetProviderAppId(“谷歌”);
Options.ClientSecret=OAuth2Helper.GetProviderAppSecret(“谷歌”);
我决定只使用google,所以我们将讨论google中间件

  • AuthenticationHandler
    AuthenticationMiddleWare.CreateHandler()
    返回,在我的例子中,它们是
    GoogleOAuth2AuthenticationHandler
    GoogleOAuth2AuthenticationMiddleware

    我在 然后像这样把它带到我的项目中

    公共类GoogleAuthenticationMiddleWare扩展:GoogleOAuth2AuthenticationMiddleware
    {
    专用只读ILogger\u记录器;
    私有只读HttpClientu HttpClient;
    公共GoogleAuthenticationMiddleWare扩展(
    接下来呢,,
    IAppBuilder应用程序,
    GoogleOAuth2AuthenticationOptions)
    :base(下一步、应用程序、选项)
    {
    _logger=app.CreateLogger();
    _httpClient=新的httpClient(ResolveHttpMessageHandler(选项));
    _httpClient.Timeout=Options.BackchannelTimeout;
    _httpClient.MaxResponseContentBufferSize=1024*1024*10;//10 MB
    }
    受保护的重写AuthenticationHandler CreateHandler()
    {
    返回新的GoogleOAuth2AuthenticationHandlerExtended(\u httpClient,\u logger);
    }
    私有静态HttpMessageHandler ResolveHttpMessageHandler(GoogleOAuth2AuthenticationOptions选项)
    {
    HttpMessageHandler=options.BackchannelHttpHandler??新建WebRequestHandler();
    //如果他们提供了验证器,则应用它或失败。
    if(options.BackchannelCertificateValidator!=null)
    {
    //设置证书验证回调
    var webRequestHandler=作为webRequestHandler的处理程序;
    if(webRequestHandler==null)
    {
    抛出新的InvalidOperationException(“Exception_ValidatorHandlerMismatch”);
    }
    webRequestHandler.ServerCertificateValidationCallback=options.BackchannelCertificateValidator.Validate;
    }
    返回处理程序;
    }
    }
    
  • 然后,我用修改后的ApplyResponseChallengeAsync创建了自己的处理程序。现在我有一个坏消息-
    GoogleOAuth2AuthenticationHandler
    是内部的,我不得不完全接受它,然后像这样(再次)投入到我的项目中

    公共类GoogleOAuth2AuthenticationHandlerExtended:AuthenticationHandler
    {
    私有常量字符串标记端点=”https://accounts.google.com/o/oauth2/token";
    私有常量字符串UserInfoEndpoint=”https://www.googleapis.com/oauth2/v3/userinfo?access_token=";
    私有常量字符串授权端点=”https://accounts.google.com/o/oauth2/auth";
    专用只读ILogger\u记录器;
    私有只读HttpClientu HttpClient;
    公共GoogleOAuth2AuthenticationHandlerExtended(HttpClient HttpClient,ILogger记录器)
    {
    _httpClient=httpClient;
    _记录器=记录器;
    }
    //我这里有些惊喜
    受保护的覆盖异步任务AuthenticateCoreAsync()
    {
    AuthenticationProperties=null;
    尝试
    {
    字符串代码=null;
    字符串状态=null;
    IReadableStringCollection query=Request.query;
    IList values=query.GetValues(“代码”);
    if(值!=null&&values.Count==1)
    {
    代码=值[0];
    }
    values=query.GetValues(“状态”);
    if(值!=null&&values.Count==1)
    {
    状态=值[0];
    }
    properties=Options.StateDataFormat.Unprotect(状态);
    如果(属性==null)
    {
    返回null;
    }
    //OAuth210.12CSRF
    如果(!ValidateCorrelationId(属性,_logger))
    {
    返回新的AuthenticationTicket(空,属性);
    }
    字符串requestPrefix=Request.Scheme+“:/”+Request.Host;
    字符串重定向URI=requestPrefix+Request.PathBase+Options.CallbackPath;
    //构建令牌请求的主体
    var body=新列表();
    添加(新的KeyValuePair(“授权类型”、“授权代码”);
    添加(新的KeyValuePair(“code”,code));
    添加(新的KeyValuePair(“redirect_uri”,redirectUri));
    添加(新的KeyValuePair(“client_id”,Options.ClientId));
    添加(新的KeyValuePair(“client_secret”,Options.ClientSecret));
    //请求令牌
    HttpResponseMessage令牌响应=
    wait_httpClient.PostAsync(TokenEndpoint,newformurlencodedcontent(body));
    tokenResponse.EnsureSuccessStatusCode();
    string text=wait tokenResponse.Content.ReadAsStringAsync();
    //反序列化令牌响应
    JObject-response=JObject.Parse(文本);
    string accessToken=response.Value(“access_token”);
    
    //Provider #1
    app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions
    {
        AuthenticationType = "Google-Site.Com",
        ClientId = "abcdef...",
        ClientSecret = "zyxwv....",
        CallbackPath = new PathString("/sitecom-signin-google")
    });
    
    //Provider #2
    app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions
    {
        AuthenticationType = "Google-AnotherSite.com",
        ClientId = "abcdef...",
        ClientSecret = "zyxwv....",
        CallbackPath = new PathString("/anothersitecom-signin-google")
    });