I am able to generate SecurityToken but I am unable to pass it when creating channel.
In .NET Framework 4.8 I could do,
var proxy = factory.CreateChannelWithIssuedToken(securityToken);
But I am unable to find alternative in .Net Core, I looked at decompiled source,
I tried this by creating a poco "FederatedClientCredentialsParameters" but this didn't work either.
var proxy = factory.CreateChannel();
IClientChannel clientChannel = (IClientChannel) proxy;
clientChannel.GetProperty<ChannelParameterCollection>().Add(new FederatedClientCredentialsParameters()
{
IssuedSecurityToken = token
});
I have tried looking into setting factory.endpointbehavior but can't find an avenue where I can insert security token. Most answers seems to be around client credential for username and password but not related WS Trust based security token.
I ended up creating my custom credential, custom credential token manager & custom token provider.
Then before creating proxy, I configured my custom credential code.
factory.Endpoint.EndpointBehaviors.Clear();
factory.Endpoint.EndpointBehaviors.Add(new CustomCredentials()
This allowed my custom credential code to return token at run time and it finally worked!
For detailed implementation see post by Joe at the bottom of following thread,
How can I pass a username/password in the header to a SOAP WCF Service
At present, core's support for wcf is very limited. In order to use WCF in core, core provides the following packages to support WCF:
The functions provided by these packages are also very limited. Many WCF functions cannot be used in core. You can pass security tokens in the .net framework, but core does not support you to do so.
My suggestion is to use the .net framework, you can also consider using custom binding and custom credentials. For more information about core's support for WCF, please refer to this link:
https://github.com/dotnet/wcf/tree/master/src
Feel free to let me know if the problem persists.
Related
I'm trying to obtain a Azure Maps Token using a Azure Function based on the following documentation.
How to secure a single-page web application with non-interactive sign-in
Does anyone know how to create a Azure Maps Client using .NET similar to this?
AzureMapsManagement client library for JavaScript
They just released a .NET client library yesterday. You can find it here: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/maps
For example, if you wanted to use the search API, you would authenticate
in a similar manner to the JavaScript client library:
AzureKeyCredential credential = new AzureKeyCredential("<My Subscription Key>");
MapsSearchClient client = new MapsSearchClient(credential);
Here is some documentation on this client library: https://learn.microsoft.com/en-us/azure/azure-maps/how-to-dev-guide-csharp-sdk
For token base authentication you can use the Azure.Core.TokenCredential class. A good article on the different ways to do this can be found here: https://www.rahulpnath.com/blog/defaultazurecredential-from-azure-sdk/ (not putting code in stackoverflow as there are a lot of different ways depending on your scenario).
I have a test project based on the .Net 5 ServiceStack mvcidentity sample. For web-based access, the authentication works as expected.
Accessing the API directly from another app for the hello sample works as no authentication is required. However, if I try to connect to one of the API Methods that requires Authentication, I receive an error message that no auth providers are defined.
Based on this sample, what is the correct way to access one of the authentication required methods from an application on another computer, where there would not be a user to login? I presume we would need to add a basic authentication or something similar in the authentication pipeline?
If you're using the mvcidenity project template you're using ASP .NET Core Identity for authentication (as opposed to ServiceStack Auth) which you'll need to use for any authorization, e.g. you can use a IAuthorizationFilter to implement HTTP Basic Auth.
Setting up a simple out-of-the-box ASP.NET Core MVC app in Visual Studio 2019 with authentication enabled against an Azure Active Directory will result in implicit OAuth2 flow while using OpenID-Connect.
This is illustrated here.
I just tested this and I did not have to deal with a client secret which would be mandatory for authorization code flow, so I presume above is true.
On the other hand in the documentation the use of the implicit flow is discouraged:
The implicit grant presents more risks than other grants, [...] If you
are developing a Web application that includes a backend, and
consuming an API from its backend code, the implicit flow is also not
a good fit.
To further confuse things, there is this documentation where it is stated that web apps are using the authorisation code flow:
The OAuth 2.0 authorization code flow is described in section 4.1 of
the OAuth 2.0 specification. It's used to perform authentication and
authorization in the majority of app types, including web apps and
natively installed apps.
The questions that arise are
If the implicit flow is considered a bad choice, why is it used by the ASP.NET Core MVC middleware?
Can I change the behaviour?
If yes, where and how would I be able to obtain the client secret from Azure AD's app registration?
Your observations are, unfortunatelly valid.
The samples provided use implicit flow. I would guess for simplicity. This can be seen from the configuration script for the latest sample.
All the statements regarding implicit flow are correct. Including the one from the comment.
However, we have to pay attention, that the default scaffolding of ASP.NET Core project that uses OpenID Connect, actually only performs authentication and not authorization. It also does not perform a calls to external APIs. In that sense, the implicit flow is used to only obtain an id_token, but not access_token. The former contains user profile information and does not pose security risk. Whereas the latter contains authorization data for accessing specific resource. So the id_token itself does not impose a security risk when leaked. Yes it imposes data leak if leaked, but not a security one.
There is more complete sample here. Which uses ob-behalf-of flow to get an access_token to call external service. It is still not the full authorization code grand flow, but the on-behalf-of flow. The latter is even more secure.
Generally speaking OpenIDConnect implementation in .NET Core does have implementation for handling authorization code, which can be seen from the AuthorizationCodeRecieved event. Which can be used when constructing OpenIdConnectOptions object by defining the OpenIDConnectEvents property.
Frankly, to ask why project scaffolds are so designed will not bring a lot of attention, neither will it change it something. I am pretty sure the older implementations (.net 4.5 or so) were using AuthZ Code by default. Not sure why this has changed - probably to lower the friction of implementation and understanding of samples ....
But hey, IMO using Authorization Code grand to just get an ID token is a bit of an overkill, isn't it?
Addressing the comments
1) Agree it is a mess. Authorize attribute does nothing but checking for authenticated user. It may also be configured to check for a specific role. But even then, that role will be extracted from the id_token. Because you do not have access_token in case of a web app. My point is, thet when you deal with a simple web app (front end, backend - Controllers or ASPX pages) you only deal with id_tokens and no access tokens. In that context having implicit flow significantly reduces the code complexity.
The documentation is open sourced on GitHub and any responsible programmer has the freedom (and is more then welcome) to suggest improvements or indicate problems. While StackOverflow is for technical questions and answers, not complaints about software documentation.
What I'm hoping to accomplish is a connection to Visual Studio Team Services through the Microsoft Account authentication provider. I've been following the documentation here (https://github.com/Azure/azure-content/blob/master/articles/app-service-api/app-service-api-dotnet-connect-to-saas.md) and have a couple problems with the implementation.
They use the Microsoft.Azure.AppService.ApiApps.Service package to get to the token from the api gateway
// Retrieve the token from the gateway
var runtime = Runtime.FromAppSettings(Request);
var dropboxTokenResult = await runtime.CurrentUser.GetRawTokenAsync("dropbox");
But when I publish my webapp I get a 500 error when trying to create the Runtime object, the remote Debugger literally just dies on the line below and I don't even see any logs in the api's streaming logs interface to give more info on the error.
var runtime = Runtime.FromAppSettings(Request);
Any idea on how to get to the token?
Documenation for implementing microsoftaccount authentication with a web api is kinda scarce, any links to examples or documentation that was helpful to you guys out there?
Also, is the apiapp.json file really even necessary? They create one in the example but authentication setup Via the Azure blades seems to work ok and leaving the apiapp.json file out of the api doesn't seem to matter either way. In the end I'd like my web api to maintain authentication via microsoft account no matter where it's moved to, so I figured there would be settings somewhere I would need to specify but can't really put that piece together either.
It looks like you're using the old model for building API apps (which involves a gateway) which has been deprecated. I believe its still supported, but the official way to build API apps has since changed, and you might find it a bit simpler to work with. More information can be found here: https://azure.microsoft.com/en-us/documentation/articles/app-service-api-whats-changed/
Documentation for leveraging Microsoft Account authentication is here: https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-how-to-configure-microsoft-authentication/
Once you're all set up, there are a few different ways you can obtain the token. You can find it as an inbound HTTP header (x-ms-token-microsoftaccount-access-token) or you can use the App Service Server SDK to obtain it: something alongs the lines of:
var creds = await this.User.GetAppServiceIdentityAsync<MicrosoftAccountCredentials>(this.Request);
string accessToken = creds.AccessToken;
How can I be confident that only our silverlight applications are calling our azure services?
The silverlight client will need to have a user authenticated and have the correct permissions to perform an action but I did not know how application authenticity is commonly implemented on these azure service calls. I know you can sign the application (required for client updates). Is this combined with ssl connections enough? Should I be using a cert at the client?
What are some common approaches to this problem?
You can put data inside your message headers. You can do it in the SOAP header when using SOAP or in the HTTP header when using REST. Then when you've done this you can use a secure SSL channel to communicate so people can't sniff out your packages.
http://blogs.msdn.com/b/nathana/archive/2007/05/29/custom-soap-headers-wcf-and-asmx.aspx
When you're using RIA service and you want to add data in the HTTP header then see my blog:
http://strugglesofacoder.blogspot.com/2011/02/normal-0-21-false-false-false-nl-be-x.html
Silverlight does not have a way of identifying itself to the service, and even if it does, a little tool called Fiddler will expose all that information for anyone to exploit your services.
You should assume nothing about the client. Your services should perform validation on the incoming requests without trying to determine who/what the client is.
I do hope someone has a solution because I haven't found one yet, and I'd love to secure my services so that only Silverlight can make requests.
You could do this using the Access Control Service, there is a nice example on codeplex written by someone of the ACS team:
http://acs.codeplex.com/wikipage?title=ACS%20Windows%20Phone%20Sample&referringTitle=Samples
although it is a windows phone 7 client (which is also silverligh), i think you can distill what you need from it.
Silverlight is a tricky beast when it comes to integrating with ACS, it seems that writing to the headers from Silverlight to pass authentication information along is very tricky - there isn't an easy way to intercept the calls to wrap them with the auth header in Silverlight, like you could do in an ASP.NET application.
You can use ACS to get your identifying information to Silverlight by using an approach like this example: http://channel9.msdn.com/Events/MIX/MIX10/SVC01
What I ended up doing is wrapping some unique identifier claim in a SWT token, signed with a key that's known by both Silverlight and the web service, and having the web service verify that that user has access. By placing the unique identifier in a signed SWT token (with an expiration time of a very short amount - to help reduce attacks where folks copy a valid request and send it again at a later time), I could more comfortably believe that the request was truly coming from my Silverlight app.
To pass the token, I just made a class that contains all the parameters I want to pass (that way I didn't have to keep rewriting the function definitions), including the SWT token.
Hope this helps.