IdentityServer3 PublicOrigin and IssuerUri Difference and Usage in IdentityServerOptions - identityserver3

I got some issue when deploying to IIS. Apparently the client uses reverse proxy and all of the OpenId configuration disco showing IP address instead of their domain name. PublicOrigin solves my problem. However, I still don't understand the different between,
PublicOrigin
and
IssuerUri
Example in:
var options = new IdentityServerOptions
{
PublicOrigin = "https://myids/project1/",
IssuerUri = "https://myids/project1/",
...
}
I can see from the disco showing changes as well if both value updated respectively, i.e.;
{
"issuer": "https://myids/project1/",
"jwks_uri": "https://myids/project1/.well-known/jwks",
"authorization_endpoint": "https://myids/project1/connect/authorize",
"token_endpoint": "https://myids/project1/connect/token",
"userinfo_endpoint": "https://myids/project1/connect/userinfo",
"end_session_endpoint": "https://myids/project1/connect/endsession",
"check_session_iframe": "https://myids/project1/connect/checksession",
"revocation_endpoint": "https://myids/project1/connect/revocation",
"introspection_endpoint": "https://myids/project1/connect/introspect",
...
}
and why not just make it the same as IssuerUri. I have read the documentation on this. Technically is just a description of the properties. I would like to understand more.
Many thanks.

IssuerUri is unique identifier of the authorization server. Value of this property is embedded into ID tokens in the iss property and it is during token validation.
On the other side, PublicOrigin is just a public URI of the server. If the server is behind reverse proxy, then without this hint it would advertise private URI in OpenID Connect metadata (.well-known/openid-configuration).
Why not have just single property? OpenID Connect specification (ยง 16.15. Issuer Identifier) supports multiple issuers residing on the same host and port. However the same section in specification recommends to host only a single issuer per host and port (i.e. single-tenant).
When would you use multi-tenant architecture? Suppose you want to build and sell your own Authentication-as-a-Service. Now you have two options - assign dedicated URI (PublicOrigin) to each of your customers or use single PublicOrigin with dedicated IssuerUri for each customer.

Related

dynamicaly parameterized FeignClients

I need to access different instances of a server sharing the same REST interface.
for one server, or different instances of the same server, I would use Ribbon and a feignClient, but the servers are not interchangeable.
I've got a list of server adresses in my application.yml file, likewise:
servers:
- id: A
url: http://url.a
- id: B
url: http://url.b
I'd like to be able to request a server regarding input parameter, for example:
ClientA -> /rest/api/request/A/get -> http://url.a/get
ClientB -> /rest/api/request/B/get -> http://url.b/get
The middleware is agnostic regarding the clients, but the backend server is bound to the clients.
many clients -> one middleware -> some clients
Who would you achieve that using Feign? is it even possible?
The simplest way is to create two Feign targets using the reusing the interface and builder.
Client clientA = Feign.builder()
.target(Client.class, "https://url.a");
Client clientB = Feign.builder()
.target(Client.class, "https://url.b");
This will create a new Client for each target url, however, by ensuring that the supporting components such as the Encoder, Decoder, Client, and ErrorDecoder are singleton instances and thread-safe, the cost of the client will be minimal.
If you don't want to create multiple clients, the alternative is to include a URI as a method parameter.
#RequestLine("POST /repos/{owner}/{repo}/issues")
void createIssue(URI host, Issue issue, #Param("owner") String owner, #Param("repo") String repo);
The value host in the example above will replace the base uri provided in the builder. The drawback to this approach you will need to modify your interface to add this URI to the appropriate methods and adjust the callers to supply the target.

Getting error while accessing rally using rally-rest-api-2.1.2.jar

I am getting an authentication error for API key in rally. Even api key is given full access.
java.io.IOException: HTTP/1.1 401 Full authentication is required to access this resource
at com.rallydev.rest.client.HttpClient.executeRequest(HttpClient.java:163)
at com.rallydev.rest.client.HttpClient.doRequest(HttpClient.java:145)
at com.rallydev.rest.client.ApiKeyClient.doRequest(ApiKeyClient.java:37)
at com.rallydev.rest.client.HttpClient.doGet(HttpClient.java:221)
at com.rallydev.rest.RallyRestApi.query(RallyRestApi.java:168)
This is The code :
String wsapiVersion = "v2.0";
restApi.setWsapiVersion(wsapiVersion);
restApi.setApplicationName(projectname);
QueryRequest testCaseRequest = new QueryRequest("Testsets");
if(null !=workspace && ""!=workspace)
testCaseRequest.setWorkspace(workspace);
QueryResponse testCaseQueryResponse = restApi.query(testCaseRequest);
What is wrong here ?
One of the things I would check for is whether you are inside a corporate network that uses authenticated proxy servers. Unless you configure the connection correctly, the proxy will reject your request before it even gets to Rally.
Second thing I just thought of is, whether you are setting the right field in the header to enable the use of an APIKey. The Rally servers expect the ZSESSIONID to be set to the APIKey, I believe.

IdentityServer3 idsrv.partial cookie gets too big

After login when redirecting the user using context.AuthenticateResult = new AuthenticateResult(<destination>, subject, name, claims) the partial cookie gets so big that it contains up to 4 chunks and ends up causing "request too big" error.
The number of claims is not outrageous (in the 100 range) and I haven't been able to consistently reproduce this on other environments, even with larger number of claims. What else might be affecting the size of this cookie payload?
Running IdSrv3 2.6.1
I assume that you are using some .NET Framework clients, because all of these problems are usually connected with the Microsoft.Owin middleware, that has some encryption that causes the cookie to get this big.
The solution for you is again part of this middleware. All of your clients (using the Identity Server as authority) need to have a custom IAuthenticationSessionStore imlpementation.
This is an interface, part of Microsoft.Owin.Security.Cookies.
You need to implement it according to whatever store you want to use for it, but basically it has the following structure:
public interface IAuthenticationSessionStore
{
Task RemoveAsync(string key);
Task RenewAsync(string key, AuthenticationTicket ticket);
Task<AuthenticationTicket> RetrieveAsync(string key);
Task<string> StoreAsync(AuthenticationTicket ticket);
}
We ended up implementing a SQL Server store, for the cookies. Here is some example for Redis Implementation, and here is some other with EF DbContext, but don't feel forced to use any of those.
Lets say that you implement MyAuthenticationSessionStore : IAuthenticationSessionStore with all the values that it needs.
Then in your Owin Startup.cs when calling:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
SessionStore = new MyAuthenticationSessionStore()
CookieName = cookieName
});
By this, as the documentation for the IAuthenticationSessionStore SessionStore property says:
// An optional container in which to store the identity across requests. When used,
// only a session identifier is sent to the client. This can be used to mitigate
// potential problems with very large identities.
In your header you will have only the session identifier, and the identity itself, will be read from the Store that you have implemented

Cannot Validate AccessToken with IdentityServer

We are using IdentityServer for authentication and we are validating the access token using JwtSecurityTokenHandler ValidateToken. This used to work fine, but after we upgraded our client application to ASP.NET Core 1.0 RTM (from RC1), the validation fails. The received error is:
IDX10501: Signature validation failed. Unable to match 'kid'
When I look at the KeyID of the used certificate and the kid of the token, I can see that they are different. I checked the IdentityServer jwks-endpoint to check that I had the correct certificate and noticed that the kid and certificate key id are different from that endpoint too. From what I've understood, they are supposed to be the same?
Any ideas why the code broke during the upgrade since the certificate, token and IdentityServer are still the same and only the client app core was upgraded.
EDIT (More information)
I suspect that ValidateIssuerSigningKey is false by default and the key has not even been validated before (thus it was working). Now it seems that the ValidateIssuerSigningKey is being ignored (as bad practice?) and thus the validation fails.
Workaround/Fix
By setting the IssuerSigningKeyResolver manually and giving the key to use in validation explicitly, fixes the issue and validation passes. Not sure how good the workaround is and why the default doesn't work, but at least I can move on for now.
simplified code...
new JwtSecurityTokenHandler().ValidateToken(authTokens.AccessToken,
new TokenValidationParameters()
{
IssuerSigningKeys = keys,
ValidAudience = audience,
ValidIssuer = issuer,
IssuerSigningKeyResolver = (arbitrarily, declaring, these, parameters) => new List<X509SecurityKey> { securityKey }
}, out securityToken);
The Client and API should refer to the same instance of IdentityServer. We are running IdentityServerHost in Azure, which has different slots (main and staging) and two applications inconsistently referred to different slots. The Client received access token issued by IdSrv-main provider and passed it to API, that expected it from different provider IdSrv-staging. API validated it and returned error.
The problem is that the errror doesn't give a hint to the actual cause of the issue. MS should provide much more detailed error message to help debugging.
The current error message is not sufficient to identify the cause.

Programmatically get user identity from Azure ACS

This question is a bit noobie, but i can't find the information over the internet (perhaps i'm search wrongly?)
We have an Azure ACS configured and we using it as auth service for our website.
But now we need to build an application, which, by known username and password, will receive users claims from ACS. Is this possible?
Yes, it's possible.
One thing to note - Using ACS, you can choose a variety of different token providers to allow (aka STS-es). Each of those provide a different set of claims to you as a default, so you might need to enrich these.
Here's a snippet of code that you can try to see what claims are coming back from ACS in your code already:
// NOTE: This code makes the assumption that you have .NET 4.5 on the machine. It relies on
// the new System.Security.Claims.ClaimsPrincipal and System.Security.Claims.ClaimsIdentity
// classes.
// Cast the Thread.CurrentPrincipal and Identity
System.Security.Claims.ClaimsPrincipal icp = Thread.CurrentPrincipal as System.Security.Claims.ClaimsPrincipal;
System.Security.Claims.ClaimsIdentity claimsIdentity = icp.Identity as System.Security.Claims.ClaimsIdentity;
// Access claims
foreach (System.Security.Claims.Claim claim in claimsIdentity.Claims)
{
Response.Write("Type : " + claim.Type + "- Value: " + claim.Value + "<br/>");
}
Adam Hoffman
Windows Azure Blog - http://stratospher.es
Twitter - http://twitter.com/stratospher_es