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;
}
返回处理程序;
}
}
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")
});