Authenticating WEB API 2 .net framework 4.x in identity server 4 using OIDC
I know there are similar questions out there, but still it's not very clear,
after reading a bunch of posts related to the subject, this how i "understood" the code should look like, i am still dealing with all the concepts involved in oauth/openid/owin/katana/identityserver etc...
Big picture is: i have an angular application,
where the user register and log in, no consent is needed, once the user is logged in, the SPA will start comunicating with all the api's in the back and the api's should be able to authenticate against the auth server.
So basically,i need my web api to be able to authenticate in identity server 4, through client credentials grant type, with the issued token by the authentication server.
I got this client(web api 2 .net framework 4.5) defined in identiy server 4:
public static IEnumerable<Client> GetClients()
{
//client credentials client
return new List<Client>
new Client
ClientId = "client2",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
new Secret("secret".Sha256())
,
AllowedScopes = "api2"
,
In the .net Api side i have this:
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType =
CookieAuthenticationDefaults.AuthenticationType
);
app.UseOpenIdConnectAuthentication(new
OpenIdConnectAuthenticationOptions
ClientId = "client2",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ResponseType = "id_token",
Scope = "api2",
SignInAsAuthenticationType =
CookieAuthenticationDefaults.AuthenticationType,
);
And the controllers are decorated with the Autorize decorator.
These are the versions of the packages im using
id="Microsoft.Owin.Security.OpenIdConnect" version="4.0.0"
id="Microsoft.Owin.Security.OAuth" version="4.0.0"
id="Microsoft.Owin.Security" version="4.0.0"
id="Microsoft.Owin" version="4.0.0"
By the moment i am using one of the demo projects from the offical project site(https://github.com/IdentityServer/IdentityServer4.Samples), i added an extra call in the MVC demo app to call my api.
public async Task<IActionResult> CallApiUsingUserAccessToken2()
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await
client.GetStringAsync("http://localhost:17307/api
/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
According to the working demo, there are two ways to do this, but none have worked to me.
public async Task<IActionResult> CallApiUsingClientCredentials2()
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);
var content = await client.GetStringAsync("http://localhost:17307/api/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
This is part of the response with the error, i am getting in both scenarios:
<div class="row">
<div class="col-sm-6">
<div class="alert alert-danger">
Sorry, there was an error
<strong>
<em>
: invalid_request
</em>
</strong>
<div>Invalid redirect_uri</div>
</div>
<div class="request-id">Request Id: 0HLIALF7L4N8J:00000001</div>
</div>
</div>
What is missing here or what is wrong, is the redirect_uri mandatory, why is not present in the configuration section for the .net core ?
This is how configuration of the api looks like in .net core and works fine.
public void ConfigureServices(IServiceCollection services)
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
);
Thanks in advance.
Update
After some experimenting, i comfirming the issue i am having is in the api validating the access token using owin middleware.
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType = "Cookies",
);
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string,
string>
();
app.UseIdentityServerBearerTokenAuthentication
(new IdentityServerBearerTokenAuthenticationOptions
Authority = "http://localhost:5000",
RequiredScopes = new "api2" ,
);
I am using identityserver3.accesstokenvalidation to perform the validation, as it is recomended, but after getting the access token in the client application and pass it to the api request, i am getting a 401 unauthorized error, is this because it is expecting to operate under secure HTTPS ?, i notice for accesstokenvalidation v4 you can set "RequireHttpsMetadata = false" but i dont see this in v3, could be this the reason i am not getting the token validating ?
identityserver4 openid-connect
add a comment |
I know there are similar questions out there, but still it's not very clear,
after reading a bunch of posts related to the subject, this how i "understood" the code should look like, i am still dealing with all the concepts involved in oauth/openid/owin/katana/identityserver etc...
Big picture is: i have an angular application,
where the user register and log in, no consent is needed, once the user is logged in, the SPA will start comunicating with all the api's in the back and the api's should be able to authenticate against the auth server.
So basically,i need my web api to be able to authenticate in identity server 4, through client credentials grant type, with the issued token by the authentication server.
I got this client(web api 2 .net framework 4.5) defined in identiy server 4:
public static IEnumerable<Client> GetClients()
{
//client credentials client
return new List<Client>
new Client
ClientId = "client2",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
new Secret("secret".Sha256())
,
AllowedScopes = "api2"
,
In the .net Api side i have this:
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType =
CookieAuthenticationDefaults.AuthenticationType
);
app.UseOpenIdConnectAuthentication(new
OpenIdConnectAuthenticationOptions
ClientId = "client2",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ResponseType = "id_token",
Scope = "api2",
SignInAsAuthenticationType =
CookieAuthenticationDefaults.AuthenticationType,
);
And the controllers are decorated with the Autorize decorator.
These are the versions of the packages im using
id="Microsoft.Owin.Security.OpenIdConnect" version="4.0.0"
id="Microsoft.Owin.Security.OAuth" version="4.0.0"
id="Microsoft.Owin.Security" version="4.0.0"
id="Microsoft.Owin" version="4.0.0"
By the moment i am using one of the demo projects from the offical project site(https://github.com/IdentityServer/IdentityServer4.Samples), i added an extra call in the MVC demo app to call my api.
public async Task<IActionResult> CallApiUsingUserAccessToken2()
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await
client.GetStringAsync("http://localhost:17307/api
/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
According to the working demo, there are two ways to do this, but none have worked to me.
public async Task<IActionResult> CallApiUsingClientCredentials2()
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);
var content = await client.GetStringAsync("http://localhost:17307/api/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
This is part of the response with the error, i am getting in both scenarios:
<div class="row">
<div class="col-sm-6">
<div class="alert alert-danger">
Sorry, there was an error
<strong>
<em>
: invalid_request
</em>
</strong>
<div>Invalid redirect_uri</div>
</div>
<div class="request-id">Request Id: 0HLIALF7L4N8J:00000001</div>
</div>
</div>
What is missing here or what is wrong, is the redirect_uri mandatory, why is not present in the configuration section for the .net core ?
This is how configuration of the api looks like in .net core and works fine.
public void ConfigureServices(IServiceCollection services)
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
);
Thanks in advance.
Update
After some experimenting, i comfirming the issue i am having is in the api validating the access token using owin middleware.
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType = "Cookies",
);
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string,
string>
();
app.UseIdentityServerBearerTokenAuthentication
(new IdentityServerBearerTokenAuthenticationOptions
Authority = "http://localhost:5000",
RequiredScopes = new "api2" ,
);
I am using identityserver3.accesstokenvalidation to perform the validation, as it is recomended, but after getting the access token in the client application and pass it to the api request, i am getting a 401 unauthorized error, is this because it is expecting to operate under secure HTTPS ?, i notice for accesstokenvalidation v4 you can set "RequireHttpsMetadata = false" but i dont see this in v3, could be this the reason i am not getting the token validating ?
identityserver4 openid-connect
add a comment |
I know there are similar questions out there, but still it's not very clear,
after reading a bunch of posts related to the subject, this how i "understood" the code should look like, i am still dealing with all the concepts involved in oauth/openid/owin/katana/identityserver etc...
Big picture is: i have an angular application,
where the user register and log in, no consent is needed, once the user is logged in, the SPA will start comunicating with all the api's in the back and the api's should be able to authenticate against the auth server.
So basically,i need my web api to be able to authenticate in identity server 4, through client credentials grant type, with the issued token by the authentication server.
I got this client(web api 2 .net framework 4.5) defined in identiy server 4:
public static IEnumerable<Client> GetClients()
{
//client credentials client
return new List<Client>
new Client
ClientId = "client2",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
new Secret("secret".Sha256())
,
AllowedScopes = "api2"
,
In the .net Api side i have this:
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType =
CookieAuthenticationDefaults.AuthenticationType
);
app.UseOpenIdConnectAuthentication(new
OpenIdConnectAuthenticationOptions
ClientId = "client2",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ResponseType = "id_token",
Scope = "api2",
SignInAsAuthenticationType =
CookieAuthenticationDefaults.AuthenticationType,
);
And the controllers are decorated with the Autorize decorator.
These are the versions of the packages im using
id="Microsoft.Owin.Security.OpenIdConnect" version="4.0.0"
id="Microsoft.Owin.Security.OAuth" version="4.0.0"
id="Microsoft.Owin.Security" version="4.0.0"
id="Microsoft.Owin" version="4.0.0"
By the moment i am using one of the demo projects from the offical project site(https://github.com/IdentityServer/IdentityServer4.Samples), i added an extra call in the MVC demo app to call my api.
public async Task<IActionResult> CallApiUsingUserAccessToken2()
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await
client.GetStringAsync("http://localhost:17307/api
/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
According to the working demo, there are two ways to do this, but none have worked to me.
public async Task<IActionResult> CallApiUsingClientCredentials2()
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);
var content = await client.GetStringAsync("http://localhost:17307/api/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
This is part of the response with the error, i am getting in both scenarios:
<div class="row">
<div class="col-sm-6">
<div class="alert alert-danger">
Sorry, there was an error
<strong>
<em>
: invalid_request
</em>
</strong>
<div>Invalid redirect_uri</div>
</div>
<div class="request-id">Request Id: 0HLIALF7L4N8J:00000001</div>
</div>
</div>
What is missing here or what is wrong, is the redirect_uri mandatory, why is not present in the configuration section for the .net core ?
This is how configuration of the api looks like in .net core and works fine.
public void ConfigureServices(IServiceCollection services)
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
);
Thanks in advance.
Update
After some experimenting, i comfirming the issue i am having is in the api validating the access token using owin middleware.
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType = "Cookies",
);
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string,
string>
();
app.UseIdentityServerBearerTokenAuthentication
(new IdentityServerBearerTokenAuthenticationOptions
Authority = "http://localhost:5000",
RequiredScopes = new "api2" ,
);
I am using identityserver3.accesstokenvalidation to perform the validation, as it is recomended, but after getting the access token in the client application and pass it to the api request, i am getting a 401 unauthorized error, is this because it is expecting to operate under secure HTTPS ?, i notice for accesstokenvalidation v4 you can set "RequireHttpsMetadata = false" but i dont see this in v3, could be this the reason i am not getting the token validating ?
identityserver4 openid-connect
I know there are similar questions out there, but still it's not very clear,
after reading a bunch of posts related to the subject, this how i "understood" the code should look like, i am still dealing with all the concepts involved in oauth/openid/owin/katana/identityserver etc...
Big picture is: i have an angular application,
where the user register and log in, no consent is needed, once the user is logged in, the SPA will start comunicating with all the api's in the back and the api's should be able to authenticate against the auth server.
So basically,i need my web api to be able to authenticate in identity server 4, through client credentials grant type, with the issued token by the authentication server.
I got this client(web api 2 .net framework 4.5) defined in identiy server 4:
public static IEnumerable<Client> GetClients()
{
//client credentials client
return new List<Client>
new Client
ClientId = "client2",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
new Secret("secret".Sha256())
,
AllowedScopes = "api2"
,
In the .net Api side i have this:
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType =
CookieAuthenticationDefaults.AuthenticationType
);
app.UseOpenIdConnectAuthentication(new
OpenIdConnectAuthenticationOptions
ClientId = "client2",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ResponseType = "id_token",
Scope = "api2",
SignInAsAuthenticationType =
CookieAuthenticationDefaults.AuthenticationType,
);
And the controllers are decorated with the Autorize decorator.
These are the versions of the packages im using
id="Microsoft.Owin.Security.OpenIdConnect" version="4.0.0"
id="Microsoft.Owin.Security.OAuth" version="4.0.0"
id="Microsoft.Owin.Security" version="4.0.0"
id="Microsoft.Owin" version="4.0.0"
By the moment i am using one of the demo projects from the offical project site(https://github.com/IdentityServer/IdentityServer4.Samples), i added an extra call in the MVC demo app to call my api.
public async Task<IActionResult> CallApiUsingUserAccessToken2()
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await
client.GetStringAsync("http://localhost:17307/api
/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
According to the working demo, there are two ways to do this, but none have worked to me.
public async Task<IActionResult> CallApiUsingClientCredentials2()
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);
var content = await client.GetStringAsync("http://localhost:17307/api/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
This is part of the response with the error, i am getting in both scenarios:
<div class="row">
<div class="col-sm-6">
<div class="alert alert-danger">
Sorry, there was an error
<strong>
<em>
: invalid_request
</em>
</strong>
<div>Invalid redirect_uri</div>
</div>
<div class="request-id">Request Id: 0HLIALF7L4N8J:00000001</div>
</div>
</div>
What is missing here or what is wrong, is the redirect_uri mandatory, why is not present in the configuration section for the .net core ?
This is how configuration of the api looks like in .net core and works fine.
public void ConfigureServices(IServiceCollection services)
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
);
Thanks in advance.
Update
After some experimenting, i comfirming the issue i am having is in the api validating the access token using owin middleware.
public void ConfigureAuth(IAppBuilder app)
app.UseCookieAuthentication(new CookieAuthenticationOptions
AuthenticationType = "Cookies",
);
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string,
string>
();
app.UseIdentityServerBearerTokenAuthentication
(new IdentityServerBearerTokenAuthenticationOptions
Authority = "http://localhost:5000",
RequiredScopes = new "api2" ,
);
I am using identityserver3.accesstokenvalidation to perform the validation, as it is recomended, but after getting the access token in the client application and pass it to the api request, i am getting a 401 unauthorized error, is this because it is expecting to operate under secure HTTPS ?, i notice for accesstokenvalidation v4 you can set "RequireHttpsMetadata = false" but i dont see this in v3, could be this the reason i am not getting the token validating ?
identityserver4 openid-connect
identityserver4 openid-connect
edited Nov 17 '18 at 14:48
Jonnathan Molina Prada
asked Nov 15 '18 at 5:31
Jonnathan Molina PradaJonnathan Molina Prada
23115
23115
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Try using the correct client_id first on this line from "mvc" to "client2"
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
you are right, this is part of the issue, now i have a litle bit more understanding, i realized im not having problems issuing the access token, my problem is in the api tyring to validate the token. please see my update. Thanks
– Jonnathan Molina Prada
Nov 17 '18 at 14:26
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53313001%2fauthenticating-web-api-2-net-framework-4-x-in-identity-server-4-using-oidc%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Try using the correct client_id first on this line from "mvc" to "client2"
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
you are right, this is part of the issue, now i have a litle bit more understanding, i realized im not having problems issuing the access token, my problem is in the api tyring to validate the token. please see my update. Thanks
– Jonnathan Molina Prada
Nov 17 '18 at 14:26
add a comment |
Try using the correct client_id first on this line from "mvc" to "client2"
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
you are right, this is part of the issue, now i have a litle bit more understanding, i realized im not having problems issuing the access token, my problem is in the api tyring to validate the token. please see my update. Thanks
– Jonnathan Molina Prada
Nov 17 '18 at 14:26
add a comment |
Try using the correct client_id first on this line from "mvc" to "client2"
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
Try using the correct client_id first on this line from "mvc" to "client2"
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
answered Nov 16 '18 at 14:55
Ashish YengkhomAshish Yengkhom
114
114
you are right, this is part of the issue, now i have a litle bit more understanding, i realized im not having problems issuing the access token, my problem is in the api tyring to validate the token. please see my update. Thanks
– Jonnathan Molina Prada
Nov 17 '18 at 14:26
add a comment |
you are right, this is part of the issue, now i have a litle bit more understanding, i realized im not having problems issuing the access token, my problem is in the api tyring to validate the token. please see my update. Thanks
– Jonnathan Molina Prada
Nov 17 '18 at 14:26
you are right, this is part of the issue, now i have a litle bit more understanding, i realized im not having problems issuing the access token, my problem is in the api tyring to validate the token. please see my update. Thanks
– Jonnathan Molina Prada
Nov 17 '18 at 14:26
you are right, this is part of the issue, now i have a litle bit more understanding, i realized im not having problems issuing the access token, my problem is in the api tyring to validate the token. please see my update. Thanks
– Jonnathan Molina Prada
Nov 17 '18 at 14:26
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53313001%2fauthenticating-web-api-2-net-framework-4-x-in-identity-server-4-using-oidc%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown