Hi
I've added Authorize attribute,but not working
I think web app controller reads certificates installed only on server machine(GetUserCertificate function) not on client.
thanks
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Hi
I have an working C# winforms app that uses a usb signature to get oAuth2 bearer token,uses Client ID(edClientID.Text),Client Secret(edSecret.Text),Callback URL(uCalback),asks for usb signature password then returns access_token and refresh_token
string code;
readonly string URL_auth = "https://site1.com/authorize";
readonly string URL_getToken = "https://site1.com/token";
readonly char lfeed = (char)13;
Token token = null;
try
{
string uCalback = HttpUtility.UrlEncode("https://www.site1.com");
string url = string.Format("{0}?response_type=code&client_id={1}&redirect_uri={2}", URL_auth, edClientID.Text, uCalback);
var handler = new WebRequestHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual
};
var cert = GetUserCertificate();
handler.ClientCertificates.Add(cert);
handler.UseProxy = false;
HttpClient client = new HttpClient(handler);
string resultString;
HttpResponseMessage result;
try
{
result = client.GetAsync(url).GetAwaiter().GetResult();
}
...
if (result.RequestMessage.RequestUri.Query.Contains("code="))
{
code = result.RequestMessage.RequestUri.Query.Replace("?code=", "");
var par = string.Format("grant_type=authorization_code&code={0}&client_id={1}&client_secret={2}&redirect_uri={3}",
code, edClientID.Text, edSecret.Text, uCalback);
try
{
result = client.PostAsync(URL_getToken, new StringContent(par)).GetAwaiter().GetResult();
resultString = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
if (resultString.Contains("access_token"))
{
var js = new JavaScriptSerializer();
token = js.Deserialize<Token>(resultString);
....
}
}
.....
}
}
}
public class Token
{
public string access_token { get; set; }
public string refresh_token { get; set; }
}
public static X509Certificate2 GetUserCertificate()
{
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = store.Certificates;
X509Certificate2Collection fcollection = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection HardCollection = new X509Certificate2Collection();
string sn = "";
foreach (var x5 in fcollection)
{
if (string.IsNullOrEmpty(sn) || (x5.SerialNumber == sn))
HardCollection.Add(x5);
}
if (HardCollection.Count > 1)
{
X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(HardCollection, "", "Select certificate", X509SelectionFlag.SingleSelection);
store.Close();
return scollection[0];
}
else
{
if (HardCollection.Count == 1)
{
store.Close();
return HardCollection[0];
}
else
{
store.Close();
return null;
}
}
}
I want to replace my winforms app with a web app(mywebapp.com),I've create a controller,but in this case,on the same computer If I go to mywebapp.com/cert/xxxxx/yyyy it doesn't ask for usb signature, If I put in browser the first GET request from the code https://site1/authorize?response_type=code&client_id=xxxxx&redirect_uri=https%3a%2f%2fwww.site1.com it asks for usb signature
[ApiController]
[Route("[controller]")]
public class CertController : ControllerBase
{
[HttpGet]
[Route("/cert/{pClientID}/{pClientSecret}")]
public IActionResult GetCert(string pClientID, string pClientSecret)
{
string code, uCalback, resultString;
const char lfeed = (char)13;
HttpResponseMessage result;
try
{
uCalback = HttpUtility.UrlEncode("https://www.site1.com");
const string URL_auth = "https://site1.com/authorize";
const string URL_getToken = "https://site1.com/token";
var cert = GetUserCertificate();
var handler = new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
UseProxy = false
};
handler.ClientCertificates.Add(cert);
HttpClient client = new HttpClient(handler);
try
{
result = client.GetAsync(string.Format("{0}?response_type=code&client_id={1}&redirect_uri={2}",
URL_auth, pClientID, uCalback)).GetAwaiter().GetResult();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
if (result.RequestMessage.RequestUri.Query.Contains("code="))
{
code = result.RequestMessage.RequestUri.Query.Replace("?code=", "");
var par = string.Format("grant_type=authorization_code&code={0}&client_id={1}&client_secret={2}&redirect_uri={3}",
code, pClientID, pClientSecret, uCalback);
try
{
result = client.PostAsync(URL_getToken, new StringContent(par)).GetAwaiter().GetResult();
resultString = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
if (resultString.Contains("access_token"))
{
Token o = JsonConvert.DeserializeObject<Token>(resultString);
return Ok($"access_token={o.access_token};refresh_token={o.refresh_token}");
}
}
.....
}
}
catch (Exception ex)
{
...
}
}
thanks for any help
Hi
I've added Authorize attribute,but not working
I think web app controller reads certificates installed only on server machine(GetUserCertificate function) not on client.
thanks
As the cert access code is in the controller, it run on the computer hosting the website, and will access the hosting computers certificate store.
in this case how can I get client certificate?
thanks