WPF to authenticate against ASP.NET MVC Rest Service using basic authentication - wpf

I'm working on a WPF application which is consuming an ASP.NET MVC (Restful Behavior). MVC application is using Basic Authentication. So, how can I authenticate my WPF application to access MVC Url? Please suggest.
Thanks

You could use an HttpClient:
using (var client = new HttpClient())
{
var username = "john";
var password = "secret";
var buffer = Encoding.ASCII.GetBytes(string.Concat(username, ":", password));
var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(buffer));
client.DefaultRequestHeaders.Authorization = authHeader;
var task = client.GetAsync("https://example.com/somemethod");
if (task.Result.StatusCode == HttpStatusCode.Unauthorized)
{
Console.WriteLine("wrong credentials");
}
else
{
task.Result.EnsureSuccessStatusCode();
Console.WriteLine(task.Result.Content.ReadAsAsync<string>().Result);
}
}

Related

Why do accessing Client certs for AAD Auth require console Apps to Run as Administrator? Does it have too?

I have a basic console app that I want to access Azure Key Vault for a connection string. Been told over and over to use client certs in production environment for AAD Authentication. Problem is doing so seems to force the console app to be "Run as Administrator" triggering the UAC, making it impossible to be scheduled unattended.
Relevant code:
using Azure.Extensions.AspNetCore.Configuration.Secrets;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using System.Security.Cryptography.X509Certificates;
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
...
.
})
.UseSerilog()
.ConfigureAppConfiguration(config =>
{
...
var credential = new ClientCertificateCredential(tenantId, clientID, GetCertificate(thumbPrint));
var client = new SecretClient(kvUri, credential);
config.AddAzureKeyVault(client, new AzureKeyVaultConfigurationOptions());
})
.Build();
static X509Certificate2 GetCertificate(string thumbprint)
{
var store = new X509Store(StoreName.Root);
try
{
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
var collection = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
if (collection.Count == 0) throw new System.Exception("Certificate is not installed.");
return collection[0];
}
finally
{
store.Close();
}
}
At this point I'm down to making it a Windows Background Service...

Correct Flow for Google OAuth2 with PKCE through Client App to SAAS API Server

So we are working on a client application in Windows WPF. We want to include Google as a login option and intend to go straight to the current most secure method. At the moment we have spawned a web browser with the following methods to obtain a Authorization Code
private async void HandleGoogleLogin() {
State.Token = null;
var scopes = new string[] { "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "openid" };
var request = GoogleOAuthRequest.BuildLoopbackRequest(scopes);
var listener = new HttpListener();
listener.Prefixes.Add(request.RedirectUri);
listener.Start();
// note: add a reference to System.Windows.Presentation and a 'using System.Windows.Threading' for this to compile
await Dispatcher.Invoke(async () => {
googleLoginBrowser.Address = request.AuthorizationRequestUri;
});
// here, we'll wait for redirection from our hosted webbrowser
var context = await listener.GetContextAsync();
// browser has navigated to our small http servern answer anything here
string html = string.Format("<html><body></body></html>");
var buffer = Encoding.UTF8.GetBytes(html);
context.Response.ContentLength64 = buffer.Length;
var stream = context.Response.OutputStream;
var responseTask = stream.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
{
stream.Close();
listener.Stop();
});
string error = context.Request.QueryString["error"];
if (error != null)
return;
string state = context.Request.QueryString["state"];
if (state != request.State)
return;
string code = context.Request.QueryString["code"];
await APIController.GoogleLogin(request, code, (success, resultObject) => {
if (!success) {
//Handle all request errors (username already exists, email already exists, etc)
} else {
((App)Application.Current).UserSettings.Email = resultObject["email"].ToString();
((App)Application.Current).SaveSettings();
}
attemptingLogin = false;
});
}
and
public static GoogleOAuthRequest BuildLoopbackRequest(params string[] scopes) {
var request = new GoogleOAuthRequest {
CodeVerifier = RandomDataBase64Url(32),
Scopes = scopes
};
string codeChallenge = Base64UrlEncodeNoPadding(Sha256(request.CodeVerifier));
const string codeChallengeMethod = "S256";
string scope = BuildScopes(scopes);
request.RedirectUri = string.Format("http://{0}:{1}/", IPAddress.Loopback, GetRandomUnusedPort());
request.State = RandomDataBase64Url(32);
request.AuthorizationRequestUri = string.Format("{0}?response_type=code&scope=openid%20profile{6}&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}",
AuthorizationEndpoint,
Uri.EscapeDataString(request.RedirectUri),
ClientId,
request.State,
codeChallenge,
codeChallengeMethod,
scope);
return request;
}
To my understanding, from this point the client app has completed the required portion to have the user login to their google account and approve any additional privileges.
Our API/App server is in GoLang.
APIController.GoogleLogin
from above sends the CodeVerifier and AuthorizationCode to the GoLang application server to then finish off the OAuth2 Flow.
Is this the correct flow given our client-server setup?
If so, what is the best practice for the Go Server to retrieve a Access Token/Refresh Token and get user information? Should the client app be performing a looping check-in to the app server as the app server will not immediately have the required information to login?
Thanks for the help!

How to redirect to login page on JWT authentication failed for .net core 3.1 web API

I am new to .net core 3.1 and currently working on JWT authentication for web API using .net core and its client side developed using ReactJS. If authenctation fails, how to redirect to my login page or any way to return from custom authorize attribute with unauthorized code(401) for checking at client side. What i tried,
public void OnAuthorization(AuthorizationFilterContext context)
{
ApiResult result = new ApiResult();
var IsAuthenticated = context.HttpContext.User.Identity.IsAuthenticated;
var claimsIndentity = context.HttpContext.User.Identity as ClaimsIdentity;
if (IsAuthenticated)
{
//set custom code
}
else if (!IsAuthenticated) {
Exception ex = new Exception();
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
//need to redirect to Reactjs login page or return from here with unauthorized code
}
return ;
}
Also tried using startup.cs configure:
app.UseStatusCodePages(async context => {
var request = context.HttpContext.Request;
var response = context.HttpContext.Response;
if (response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
response.Redirect("*****"); //my login page is Reactjs page (login.js) or any way to
return the status code to client
}
});

AspNet.Core Identity Authentification from WPF client

I've implemented asp.net core Identity authentifaiction and it's working fine with my web application. In the startup.cs file, I have the following:
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
And in the Login.chtml.cs, I've the the login method:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
//...
}
else
{
//....
}
}
return Page();
}
Now I'm putting in place a WPF client in which I want to authenticate my users using the AspNetCore.Identity login procedure. Any suggestion about how to proceed will be highly appreciated.
Finally, I decided to go with IdentityServer4 in order to have a centralized login and workflow for the WPF client and other clients that I may need later.

How to Consume Secured Web Api from C# MVC and AngularJS

How to Consume Secured Web Api from other application C# MVC and AngularJS .
[Authorize(Users = "Steve,Mike")]
public class EmployeeController : ApiController
{
MyDB db = new MyDB();
public IEnumerable<EmployeeViewModel> GetAllEmployee()
{
return db.Employee.Select(item => new EmployeeViewModel { EmpID = item.EmpID, Name = item.Name, Region = item.Region }).ToList();
}
}
The following code I can get without Secure WebApi from AngularJS
var ft = searchText.toLowerCase();
$http.get('/api/Employee/GetAllEmployee').success(function (largeLoad) {
data = largeLoad.filter(function (item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data, page, pageSize);
});
Your help is highly appreciated...
what kind of Secured Web Api do you want to consume?
you may think about oAuth

Resources