Should Identity Server 4 OpenID Connect Discovery be public? - c#

Identity Server 4 exposes OpenID Connect Discovery via .well-known/openid-configuration url. Now I'm not fully clear why this is here or who should have access to it. The way I understand this, all this page does is gives out information about the endpoints.
The applications that will have access to my IS4 server will have the endpoints pre-configured as they are all internal so I see no reason to have this page exposed, I see it more secure not to give out this information out.
As such, My question is should I restrict access to this page and if so how? And if not, why?

The main benefit for keeping that endpoint is automatic client configuration. From the MVC sample on the AspNet.Security.OpenIdConnect.Samples GitHub page:
// Note: setting the Authority allows the OIDC client middleware to automatically
// retrieve the identity provider's configuration and spare you from setting
// the different endpoints URIs or the token validation parameters explicitly.
Authority = "http://localhost:54540/"
The server library has the ability to change any of the endpoint paths during startup, like the endpoint for obtaining a token. By using automatic configuration, your applications can automatically pick up on that change without you needing to update all your client applications manually.
This functionality is only offered as a convenience, should you want to use it.
If this application is only exposed to your internal network (or just within your own computer or Docker network), there is absolutely no harm in leaving this be.
If this application is exposed to the public network, then you need to start asking yourself if you want an attacker to know the information that the configuration endpoint provides.
All an attacker would know is the application is an Auth server, the paths to your various endpoints, what types of OAuth2 flows you support, and maybe a few other small details. If you have publicly facing documentation, this would just be a machine-readable version of that.
Rather than focusing on preventing access to the configuration endpoint, make sure that your Auth server endpoints are authenticated. You should be checking that the Client Id and Client Secret are present and correct before giving out tokens.
From oauth.com (this is about the introspection endpoint but really the principle applies to all endpoints):
If the introspection endpoint is left open and un-throttled, it presents a means for an attacker to poll the endpoint fishing for a valid token. To prevent this, the server must either require authentication of the clients using the endpoint, or only make the endpoint available to internal servers through other means such as a firewall.

Related

Get unique identifier of client in Asp.Net WebApi Core 2.0?

I'm looking for an unique identifier of clients in WebApi Core 2.0
I tested HttpContext.Connection.Id, it's the same for all browsers!
[HttpGet]
public IActionResult GetConnectionId()
{
return Ok(new
{
ConnectionId = HttpContext.Connection.Id
});
}
Also I test it with a virtual machine, it was the same for all clients
How to get unique identifier of clients in Asp.Net WebApi Core 2?
There is no such thing as a "unique identifier for a client". HTTP is stateless. The HTTP protocol is actually designed in such a way on purpose. Any client should be able to communicate with any server, regardless of past communication. This enables concepts like load-balancing, failover, etc.
Things like sessions, cookies, etc., have been layered on top of the HTTP protocol to enable a form of state, but rather than being a true feature of the protocol, they are a cooperative effort between servers and clients. Both the client and server must participate in the process to enable state to be achieved. Cookies, in particular, are what enables companies like Google, Facebook, et al., to track a user from site to site. However, as you've correctly indicated, cookies are incompatible with REST-based APIs.
Therefore, your only option is authentication. By forcing the client to authenticate, you can then know exactly the identity of the client and track that client's activities. Nothing else will suffice. There is no way to access client details such as a MAC address, because you can only access what the client chooses to share, and that is not one of those things. Even if it was, it could be manipulated. IP addresses once were somewhat identifying, but in this age of WAPs, proxies, VPNs and such, a single IP could be used by any number of unique clients. Also, again, the IP address can be spoofed as well, so even if you could identify a client by IP, it wouldn't ensure that you were truly dealing with that client.
There's various forms of authentication you can choose from. JWT (JavaScript Web Tokens) are popular nowadays, but you can just as easily use client authentication, certificate authentication, OAuth, OpenID, etc. The main point is to simply force the client to authenticate, in some form. Only then can you identity the client.

What are the ways to secure Azure functions

I have written 5 Azure functions in Azure Portal using c#.
Below are the steps to install my application:-
Copy deployment scripts to the Edge node of the cluster
Deployment
scripts to do the following
Call Azure functions to do get my application builds from WASB.
Install my application on Edge node
Call Azure functions to do some updation.
Above process will be executed on the Customer Edge node.
The authorization using “keys” described here is just to provide another layer of API key authorization and is not applicable when my script needs to be called by a public client (like edge node) since it is discover-able there.
What are the best ways to secure the Azure Functions in my scenario?
By default azure functions are public . So you deploy them and the endpoint is available publicly via the address on the function. As you mentioned , you can set function level access, which means you need to pass an access key. So they are kind if protected.
There are some other options though:
You can build functions inside a vnet using the azure environment service. But for this you pay good money and you have to use the service plan version of azure functions.
I have combined API Management with functions. API Management is a way to expose your apis to consumers but maintain lots of control over the usage. The Api Management component does not prevent the public azure address being available but I have implemented pattern in code which checks for a special token which is appended to a http request as part of the app management pass-through. Or alternatively you can set IP restrictions on the Function app to allow traffic only from the API Management endpoint. (IP Address) So effectively you can only go to the function via the app management.
Just a note on the above, Azure portal has removed the ability to set IP restrictions via the standard functions network tab. So you need to go into the resource explorer and set the IP restrictions manually in the web config section.
Lastly , you could set up an oauth server and validate the token in the function or in an api management component or both.
AZURE ASE (App Service Environment) is way too expensive for only 5 functions. You can secure the functions by adding application gateway and whitelist the IP address of the Application gateway in the function. You can find more details here:
Whitelisting in Azure Functions
This is all in addition to having token based or AAD based authentication and authorization (like 'Noel' mentioned in the previous reply).
The best way to protect your Azure Functions is by AAD or authentication server you trust.
If that is not feasible, probably because you are consuming these functions from Console or App does not support the authorization code flow, or used by users who do not exist in your AAD, then use APIM.
The technique provided by #Noel below is powerful and it is needed to restrict access to your functions only from APIM.(Functions should not be anonymous, and there is no need to have any authorization code aside from the APIM code)
Now think how to protect the APIM.
You have multiple options, but probably you can consider the client certificate as means of proper authentication.
At the end, consumers need to have something to authenticate them (password, certificate, device, or anything) .. So setting a policy to check and existence of a certificate and finding a way to validate that certificate can help protecting your APIM.
The question now becomes about protecting the APIM and here you have many policy-based options.
Hope that helps. (Also don't forget to consider other solutions provided by Noel above)

Is is possible to apply custom encryption to Microsoft Web API?

We are using Web API 2.0 to serve clients in a context where SSL can't be used (no public internet access, clients can't be expected to trust a self-signed certificate). To secure content moving between the client and server, we'd like to be able to encrypt it. We're OK with un-encrypted HTTP headers (only need to encrypt payload). The question is: is there a way to insert a custom handler into both the request and response message pipelines so that we can apply a decryption as a request pre-processing step and an encryption as a response post-processing step?
We are using the built-in features of Web API to serialize/de-serialize between JSON and model classes, and don't want to have to refactor any of that existing code. So an encryption handler would have to be inserted at the very start/end of the request/response pipeline. Is this possible, and if so, what is the technique to insert custom request/response content pre/post processing?
The network is "public" in that users bring their own devices, but the network is isolated from the public internet. Clients will only use a custom application we are developing to consume our Web API service, so we can address implementation issues of a custom encryption scheme on both client and server side.
If you control the client application, you can hard-code the SSL certificate that the server is expected to return, which means that it doesn't have to validate through the normal PKI means (sometimes called certificate pinning). Most other approach will result in you attempting to re-invent SSL, but with some fatal flaw.
To be explicit, I think you are seeing a conflict between "a context where SSL can't be used (no public internet access, clients can't be expected to trust a self-signed certificate)" and "Clients will only use a custom application we are developing" where one doesn't necessarily exist. The user doesn't have to know that the certificate is self-signed, and self-signed does not always imply untrusted.

Securing WCF Service Call Between Server Applications with Federated Security

I've got two MVC sites that use the same STS for authentication. I need to create a WCF service as part of one of the sites that allows the other site to retrieve data.
These sites could be on different machines accessible over the internet (although currently they're on the same machine) and the WCF service should only be able to be accessed from the client site. The authentication token used to log into the client site should be passed through to the WCF service.
I've been looking at the different WS-Security options available (Transport, Message etc) and it's not quite sinking in 100%, and I feel like I'd end up implementing something that seemed secure but wasn't actually secure due to a lack of understanding. Any help much appreciated.
Edit:
My first attempt was with transport layer security and setting the WCF service virtual directory with require SSL in IIS. However that left me with an error of:
"The remote certificate is invalid according to the validation procedure."
And I had no way of ensuring that a specific client was connecting to the service, only that a client had a certificate from a trusted CA. At least as far as I know. I'm probably missing something vital here.
The authentication token used to log into the client site should be
passed through to the WCF service.
In this case you should be requesting an "ActAs" token from the STS:
The WCF service should be configured as a Relying Party of the STS.
The MVC site should call back to the STS and request an ActAs token specific to the WCF service.
The MVC site uses the ActAs token to call the service.
The motivation for the complexity: Delegation, or traversing multilayer architectures
Since you mentioned WS standards:
Requesting Delegation (ActAs) Tokens using WSTrustChannel (as opposed to Configuration Madness)
Not knowing your STS its hard to say more, but Googling "ActAs token" will probably give you what you need.

WCF User Authentication & Authorization

I need to find a way to authenticate/authorize users in a WCF-service. I'm using an external authentication service which stores the credentials of the users.
Eg. "Bob uses our loginmethod, we send the credentials to the authentication service, the service lets us know if these credentials are correct."
If Bob sends another request, we need to know if Bob is already authenticated.
Now a session is being created on the client, but it needs to move to the server-side. We can not rely on clients for security.
Can this be solved by using security cookies or do any of you have a better suggestion?
EDIT! I can only use the authentication server and do not have access to it
The problem you are describing is a well-known one that had (at least) two standardized solutions.
Federation using WS-Trust
The first option is a SOAP based one that uses active federation based on WS-Trust. In this solution:
Your client provides credentials to the authentication service
If the credentials are valid, the authentication service returns a signed (and encrypted) token to the client. It is encrypted so that any information contained in the token remains confidential - even the client cannot read it. It is encrypted with a public key belonging to the your WCF service. It is signed with a private key belonging to the authentication service.
The client submits the signed/encrypted token to your WCF service. The service can decrypt it because it holds the private key for decryption. It can trust it because it is signed by the authentication service.
Based on the content of the decrypted token, the service can establish the client identity and make an authorization decision.
In this model, the usual terminology is:
Your authentication service the Security Token Service
Your WCF service is the Relying Party
your client is the Client
This sounds complex, but it is very well supported in .Net and WCF using Windows Identity Foundation. There are many samples available much of it (maybe all) can be done via WCF configuration rather than code.
This is well suited to scenarios where the clients are crypto-capable (like your .Net clients) and where good frameworks exist (like WIF). It is not so good for low spec clients such as browsers and some phones, or where you are not in control of the clients.
It is commonly used in enterprise scenarios, including enterprise-to-enterprise federation. It is used less often in internet scenarios.
the strengths of it are
It is standardised and therefore generally well supported by frameworks
It means that your WCF service never has to handle the client credentials (= more secure)
It makes it pretty easy to switch to different authentication services (because it is standardised). For example, on-premise AD and Windows Azure AD both support this, as do other independent identity services
An overview can be found here:
http://msdn.microsoft.com/en-us/magazine/ee335707.aspx
And Google will show you lots more walkthroughs and examples.
Federation using OAUth 2
In this solution:
The client displays some UI provided by the authentication service (generally a web page)
The user enters their credentials in that UI and the authentication service authenticates and eventually returns a token to the client. The nature of the token is not standardised, nor is whether it is encrypted. Generally it will be at least signed.
The client submits the token with each request to the WCF service
The WCF service authenticates the token as in the previous solution
In the OAuth terminology:
Your authentication service is the Authorization Server
Your WCF service is the Resource Owner
Your client is the Client
Again, this sounds complex, but it is reasonably well supported in .Net. Probably not as well as the WS-Trust approach though at the moment. It is supported by Windows Azure AD and on the client side, using the Windows Azure Authentication Library. May other services use this approach - e.g. Facebook.
This works well where
Your client is low spec or not crypto-capable (e.g. a browser or some phones)
You do not control the client (e.g. a third party application is accessing your service)
It is very commonly used in internet application where you as an owner of the WCF service don't necessarily know the users or the clients. It is a less complete standard in some ways (e.g. it does not define exactly how the authentication happens) and as a result, it is less easy to switch to alternative authorisation servers.
The strengths of it are:
It is simpler and therefore has wider platform support
It is growing in popularity and therefore the library support is getting better all the time
The user never enters their credentials into your UI, only into the auth server, so it is more likely to be trusted (in internet scenarios)
It has a built in way of controlling the scope of the permissions granted to the client, and revoking those permissions, so again it is more trusted in an internet scenario
The official .Net support for this is in the Windows Azure AD Authentication library
http://msdn.microsoft.com/en-us/library/windowsazure/jj573266.aspx
There are other, open source components too, such as DotNetOpenAuth
http://dotnetopenauth.net/
Which solution would be best for you depends mainly on the nature of your authentication service I would say. And on whether you are in an enterprise or internet scenario. If the auth. service could be easily adapted to be a WS-Trust Secure Token Service (STS), then that would be a good route. If adding some web UI to the auth. service is feasible, the OAuth might be better.
Or, if neither option is feasible, you could just borrow the patterns form one approach and use that without going for the full standard.
Good luck!

Categories