OAuth Authorization Service in ASP.NET Core - asp.net

In Web API 2, you used to be able to create an endpoint to issue a token by setting up an OAuth Authorization Server via middleware like below:
//Set up our auth server options.
var OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider()
};
// Sets up the token issue endpoint using the options above
app.UseOAuthAuthorizationServer(OAuthServerOptions);
Perhaps I'm missing it, but I'm trying to figure out how to do this in ASP.NET Core. I've looked through the source (https://github.com/aspnet/Security) but I don't really see anything analogous. Is there a new way to accomplish this? Do I need to just create a controller and do it myself?
I see how OAuth Authentication can be set up via Middleware, but this regards the authorization portion where I issue claims from my API.

EDIT (01/28/2021): AspNet.Security.OpenIdConnect.Server has been merged into OpenIddict as part of the 3.0 update. To get started with OpenIddict, visit documentation.openiddict.com.
Don't waste your time looking for an OAuthAuthorizationServerMiddleware alternative in ASP.NET Core, the ASP.NET team simply decided not to port it: https://github.com/aspnet/Security/issues/83
I suggest having a look to AspNet.Security.OpenIdConnect.Server, an advanced fork of the OAuth2 authorization server middleware that comes with Katana 3: there's an OWIN/Katana 3 version, and an ASP.NET Core version that supports both the full .NET framework and .NET Core.
https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server
ASP.NET Core 1.x:
app.UseOpenIdConnectServer(options =>
{
options.AllowInsecureHttp = true;
options.TokenEndpointPath = new PathString("/token");
options.AccessTokenLifetime = TimeSpan.FromDays(1);
options.TokenEndpointPath = "/token";
options.Provider = new SimpleAuthorizationServerProvider();
});
ASP.NET Core 2.x:
services.AddAuthentication().AddOpenIdConnectServer(options =>
{
options.AllowInsecureHttp = true;
options.TokenEndpointPath = new PathString("/token");
options.AccessTokenLifetime = TimeSpan.FromDays(1);
options.TokenEndpointPath = "/token";
options.Provider = new SimpleAuthorizationServerProvider();
});
To learn more about this project, I'd recommend reading http://kevinchalet.com/2016/07/13/creating-your-own-openid-connect-server-with-asos-introduction/.
Good luck!

For anyone still looking for the original OAuth Authorization Server in ASP.NET 5, I have ported the code and the original sample here:
https://github.com/XacronDevelopment/oauth-aspnet
The port includes backwards compatibility to allow ASP.NET 4.x resource servers to read the access tokens created by the authorization server.
The nuget packages are here:
https://www.nuget.org/packages/OAuth.AspNet.AuthServer
https://www.nuget.org/packages/OAuth.AspNet.Tokens
https://www.nuget.org/packages/OAuth.Owin.Tokens

Related

Using an asp web api in wpf

So i have got a simple question, when using our cms we can attach a driver as an executable.
The driver we want to make is an httpreceiver or just an api endpoint. SO i tought lets use asp.net web api for it -> using version .net 4.6.1. altough asp.net application requires a webserver and is not an executable, But i read on google you can use it inside a wpf application since our cms is wpf in the first place.
So my question is is there a way i can use my mvc web api project inside a wpf application? and if not what would be the best bet to have an httpreceiver or httppost receiver into an executable?
Main reason is we want to send httppost requests to the server as a desktop application. I know it's complicated but thats how it needs to be as far as I know.
In the case where asp is not an option, what the best way to make a postreqst/ httpreceiver as a desktop application?
EDit:
the resource guide from microsoft beneath was perfectly however i still have a question:
string baseAddress = "http://localhost:9000/";
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpClient and make a request to api/values
HttpClient client = new HttpClient();
string username = "test".ToUpper().Trim();
string password = "test123";
//Mock data
var body = new PostTemplate1();
body.Description = "test";
body.StateDesc = "httpdriver/username";
body.TimeStamp = DateTime.Now;
body.Message = "This is a post test";
var json = JsonConvert.SerializeObject(body);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var authToken = Encoding.ASCII.GetBytes($"{username}:{password}");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authToken));
var response = await client.PostAsync(baseAddress + #"api/Post", data);
var result = response.StatusCode;
}
As the guide says you post to url with port 9000
is there a possibility to use another port and use https?
if yes where to manage certificates for handling https?

Default Proxy in .NET Core 3.1

I need some help with .NET Core 3.1 for code that needs to get out of the corporate proxy. The code works in .NET 4.7.2 by putting the following in the app.config. This, I learned on this site (Thank you!), allows one to get through the corporate proxy server.
<system.net>
<defaultProxy useDefaultCredentials="true">
</defaultProxy>
</system.net>
The following code snippet works in .NET 4.7.2, and can get out past the proxy. The proxy is stored as an env variable named ALL_PROXY with a value of http:// our internal proxy:port (see [https://github.com/dotnet/corefx/pull/37238/commits/9ba8879ea104afac9dea9a78d3009b5bc700b7c3][1]). This is an Azure Cognitive service, so you will need a key vault, and a Cognitive Service.
var keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");
var kvUri = string.Format("{0}{1}{2}",
"https://",
keyVaultName,
".vault.azure.net");
var secretClient = new SecretClient(new Uri(kvUri),
new DefaultAzureCredential());
KeyVaultSecret secret = secretClient.GetSecret("FacesSubscription");
var subscriptionKey = secret.Value;
var credentials = new ApiKeyServiceClientCredentials(subscriptionKey);
var textClient = new TextAnalyticsClient(credentials)
{
Endpoint = endpoint
};
On .Net core, I get an http 407 exception.
Azure.RequestFailedException: 'Service request failed.
Status: 407 (ADAuth-AuthenticationFailed)
This exception occurs on the KeyVaultSecret line.
I have researched the issue #
[https://github.com/dotnet/corefx/pull/37238/commits/9ba8879ea104afac9dea9a78d3009b5bc700b7c3][1]
https://github.com/dotnet/corefx/pull/37238
https://github.com/dotnet/corefx/pull/37333
https://github.com/dotnet/runtime/issues/29147
and tried adding code such as
var handler = new HttpClientHandler();
handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
var httpClient = new HttpClient(handler);
I looked through the unit tests for the check-ins, but they all seemed to be about web proxies. The links above provide details of how the proxy is implemented.
Does anyone have idea around getting through a work proxy in NET Core with Azure services?
I have had a similar issue and this fixed it:
IWebProxy proxy = WebRequest.GetSystemWebProxy();
proxy.Credentials = CredentialCache.DefaultCredentials;
HttpClient.DefaultProxy = proxy;

How to get external login profile picture from Microsoft account in asp.net core

how can I get profile picture from Microsoft account using Microsoft.AspNetCore.Authentication.Facebook library? I tried using Claims, but they don't have profile picture value... I also tried looking in account's source control by checking image url, but I noticed that the url is made of some parameters that I can't get with claims, so I can't construct url like I can with facebook... Can someone can help me?
You can obtain the profile picture from Microsoft accounts by using Microsoft Graph:
https://developer.microsoft.com/en-us/graph/quick-start
Specific instructions on how to request the profile picture:
https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/profilephoto_get
If you follow the quick start (select asp.net, click "Get an app ID and secret" and download the sample code), it's easy to obtain the data like so:
GraphServiceClient graphClient = SDKHelper.GetAuthenticatedClient();
var photoStream = await graphService.GetCurrentUserPhotoStreamAsync(graphClient);
EDIT: Sorry, forgot the asp.net core part (it doesn't seem that Microsoft.Identity.Client is available for asp.net core).
In ExternalLoginCallback you can obtain the access token from the ExternalLoginInfo object returned by var info = await _signInManager.GetExternalLoginInfoAsync();
Remember to set SaveTokens to true when configuring authentication (otherwise the access token won't be available):
services.AddAuthentication()
.AddMicrosoftAccount(options =>
{
options.ClientId = Configuration["ExternalProviders:Microsoft:ClientId"];
options.ClientSecret = Configuration["ExternalProviders:Microsoft:ClientSecret"];
options.SaveTokens = true;
...
Then it's just a matter of making a http request - something like this:
var httpClient = new HttpClient();
httpClient.SetBearerToken(info.AuthenticationTokens.Where(t => t.Name.Equals("access_token")).First().Value);
var pictureResult = httpClient.GetAsync("https://graph.microsoft.com/v1.0/me/photo/$value").Result;

Publishing with Core Service and Impersonation

I have a Tridion Core Service Web Application to publish pages. When logged into the server and running it from there via a browser client calling a web service with ajax it works fine. However, when I run the application from my desktop it does nothing, and also throws no error messages.
*Edit:
The Web App hosting the web service is running as an 'Application' under the Tridion 2011 CMS website. This is done to avoid cross-domain ajax issues/
Update: The code below is working fine - both with the impersonate and also with Nick's solution. My issue was actually in how I was calling the web service from jQuery and using the appropriate URL. I am leaving the code and question so maybe it will help others.
My code is:
string binding = "wsHttp_2011";
using (var client = new SessionAwareCoreServiceClient(binding))
{
client.Impersonate("company\\cms_svc");
// ** Get Items to Publish
List<string> itemsToPublish = GetItemsToPublish(publishItem.TcmUri, client);
PublishInstructionData instruction = new PublishInstructionData
{
ResolveInstruction = new ResolveInstructionData() { IncludeChildPublications = false },
RenderInstruction = new RenderInstructionData()
};
PublicationTargetData pubtarget = (PublicationTargetData)client.Read(publishItem.PubTargetUri, readoptions);
List<string> target = new List<string>();
target.Add(pubtarget.Id);
client.Publish(itemsToPublish.ToArray(), instruction, target.ToArray(), GetPublishPriority(publishItem.Priority), readoptions);
}
Have at look at this page on SDL Live Content, which explains various types of scenarios for connecting as different users:
http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2011_SPONE/task_87284697A4BB423AAD5387BBD6884735
As per the docs, instead of impersonation you may want to establish your Core Service connection as follows using NetworkCredential:
using (ChannelFactory<ISessionAwareCoreService> factory =
new ChannelFactory<ISessionAwareCoreService>("netTcp_2011"))
{
NetworkCredential networkCredential =
new NetworkCredential("username", "password", "domain");
factory.Credentials.Windows.ClientCredential = networkCredential;
ISessionAwareCoreService client = factory.CreateChannel();
Console.WriteLine(client.GetCurrentUser().Title);
}

Authentication problem between ASP.Net Webforms app and a ASP.Net webservice

I got a ASP.Net webforms app which is using Forms authentication. It needs to authenticate against a webservice which uses windows authentication (+ impersonation).
I've tried (amongst other things) to supply credentials by using:
service.Credentials = new NetworkCredential(myUserName, thePassword, theDomain)
The problem is that I get 401 from the webservice no matter what I try.
I am doing exactly the same as this (by the sounds of it) and here is the way I construct the credentials.
var service = new MyService();
var netCredential = new NetworkCredential("user", "pwd", "domain");
var credentialCache = new CredentialCache
{
{new Uri(service.Url), "Basic", netCredential}
};
service.Credentials = credentialCache;
The problem was that identity that the Application Pool that the Web service run on wasn't allowed to impersonate.

Resources