Reputation: 5897
I would like to validate the token generated from IdentityServer in Web API(.Net Framework 4.7.1).
Here is what I've done so far in Startup.cs
in Web API
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
RequireHttpsMetadata = false,
SignInAsAuthenticationType = "Cookies",
Authority = "https://localhost:44380/",
RedirectUri = "http://localhost:4200/auth-callback",
ClientId = "angular",
Scope = "api1",
ResponseType = "code"
});
}
It throws code challenge required
error.
Due to the design constraint, I will not be able to use the IdentityServer/IdentityServer3.AccessTokenValidation
and I should use UseOpenIdConnectAuthentication
to validate the token.
Edit
I was able to get this working in Web API Core. Here is my Startup.cs of Web API Core. But not sure how to do this in Web API .Net Framework. I also tried with IdentityServer/IdentityServer3.AccessTokenValidation
with below configuration but it throws 401 error
public void Configuration(IAppBuilder app)
{
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://localhost:44380",
RequiredScopes = new[] { "api1" }
});
}
Upvotes: 2
Views: 4702
Reputation: 19
I have used .NET framework 4.6.1 for creating Web API, For Identity Provider, I am using Identity Server 4 (Earlier I used Identity Server 3). Initially I did face a problem, but I came up with this workaround which worked perfectly to me. Note that I am using ClientCredentials grantflow.
I am using the same IdentityServer3.AccessTokenValidation library for token validation. The trick is to target to Introspection end point. Below is my configuration which worked.
Here is the configuration for Web API, Note that setting setting ValidationMode property is crucial.
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = ConfigurationManager.AppSettings["AuthServerURI"],
RequiredScopes = new[] { "comp-read", "stats-read" },
ClientId = "apiname",
ClientSecret = "apisecret",
ValidationMode = ValidationMode.ValidationEndpoint,
EnableValidationResultCache = true
});
This is how the APIResource and Client is configured in my IDP.
new ApiResource
{
Name = "apiname",
DisplayName = "Web API",
Description = "Access to Web API Services",
ApiSecrets = new List<Secret> {new Secret("apisecret".Sha256())},
Scopes = new List<Scope> {
new Scope("comp-read", "Read access to Comp Db API"),
new Scope("stats-read", "Read access to Stats API")
}
This is how one of the client is configured.
new Client
{
ClientName = "name of the client",
ClientId = "clientname",
Enabled = true,
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = new List<Secret> {
new Secret("secretforclient".Sha256())
},
AllowedScopes = new List<string>
{
"stats-read"
},
AccessTokenLifetime = 1000
}
Hopefully this helps. Thanks.
Upvotes: 1
Reputation: 4869
Due to the design constraint, I will not be able to use the IdentityServer/IdentityServer3.AccessTokenValidation and I should use UseOpenIdConnectAuthentication to validate the token.
The conclusion is totally wrong. OpenIdConnectAuthentication is for interactive sign-in, not for bearer token validation. You can use IdentityServer3.Contrib.AccessTokenValidation instead.
I have prepared a working repo, for you and more for myself. It targets 4.7.2. Everything's hardcoded, but the only configuration block is in the startup.cs
public void Configuration(IAppBuilder app)
{
app.UseIdentityServerBearerTokenAuthentication(new
IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://demo.identityserver.io/",
RequiredScopes = new[] { "api" }
});
}
As you can see, I utilized the public Identityserver instance.
I used curl To get the token:
curl -d "grant_type=client_credentials&client_id=client&client_secret=secret" https://demo.identityserver.io//connect/token
And to call my API:
curl -v -H "Accept: application/json" -H "Authorization: Bearer <The token is here>" http://localhost/MVCBearerNuget/api/TestApi
The answer was:
< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Type: application/json; charset=utf-8
< Expires: -1
< Server: Microsoft-IIS/10.0
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Tue, 10 Sep 2019 17:37:08 GMT
< Content-Length: 19
<
["value1","value2"]* Connection #0 to host localhost left intact
An alternative is to build the middleware yourself, but the one I targeted is up to date, easy to use and it definitely works.
Upvotes: 4