We are considering using IdentityServer3 to provide federated authentication / authorisation using oAuth2 and OpenID. Our prototypes are promising and we have a basic framework up and running.
However, we have hit a problem...
After the user is authenticated the framework returns the Identity and Access tokens back to the client application as parameters of the redirect URI. Due to the nature of the application(s) we are looking to secure there is a need to have quite complex claims/roles. This results in fairly large tokens*. So large that they go beyond the maximum URI length that browsers support and therefore breaks.
So my question is, does anybody know if is possible to configure Identity Server to POST the tokens back rather than GET? Or is there another solution that does not deviate away from standards/specification?
*The claims we are talking about here are not actually that large. As an example here is a claim from the IdentityServer3 code samples
Claims = new Claim[]
{
new Claim(Constants.ClaimTypes.Name, "Alice Smith"),
new Claim(Constants.ClaimTypes.GivenName, "Alice"),
new Claim(Constants.ClaimTypes.FamilyName, "Smith"),
new Claim(Constants.ClaimTypes.Email, "AliceSmith@email.com"),
new Claim(Constants.ClaimTypes.Role, "Admin"),
new Claim(Constants.ClaimTypes.Role, "Geek"),
new Claim(Constants.ClaimTypes.WebSite, "http://alice.com"),
new Claim(Constants.ClaimTypes.Address, "{ \"street_address\": \"One Hacker Way\", \"locality\": \"Heidelberg\", \"postal_code\": 69118, \"country\": \"Germany\" }")
}
If we add another claim to this, of the same size as the address claim, then we hit the URI length issue.
That's not quite correct. It's the responseMode
that needs to be changed to form_post
.
var authorizationUri = new Uri(
client.CreateAuthorizeUrl(
clientId: "myclient",
responseType: "code id_token token",
scope: "openid Resource roles",
redirectUri: "oob://application/tokens",
responseMode: "form_post"));
IdentityServer will then encode the response parameters as HTML form values and POST
these back to your client.
<form method="post" action="oob://application/tokens">
<input type="hidden" name="code" value="aca7b48d8a944ae6a9b91283e26b1740" />
<input type="hidden" name="id_token" value="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" />
<input type="hidden" name="access_token" value="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" />
<input type="hidden" name="token_type" value="Bearer" />
<input type="hidden" name="expires_in" value="3600" />
<input type="hidden" name="scope" value="openid Resource roles" />
<input type="hidden" name="session_state" value="AHzV1QYcGi-W95OYJAganx0piP5y_km_4q9qsuvAacg.e8ca5c9876007e40bf3cc89314c86c0f" />
</form>