Happy new year to everyone...
I configured an IdentityServer4, and I can make successful ASP.net Core web api calls. But for asp.net framework 4.5.2 web apis, I got {"Response status code does not indicate success: 401 (Unauthorized)."} error from a .NET framework web api. I want to ask your help and opinion.
I seached the topic with IS4, and found some entries about IdentityServer3.AccessTokenValidation compatibility. And according to the replies, I loaded a signing cert and called AddSigningCredential instead of AddTemporarySigninCredential. x509certificate is a local created cert. and I updated IdentityServer3.AccessTokenValidation version to v2.13.0.
Still I got the error. Any help is appreciated.
Regards and thanks for your great effort.
IdentityServer 4 side: Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services
.AddIdentityServer()
//.AddTemporarySigningCredential()
.AddSigningCredential(x509Certificate)
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddAspNetIdentity<ApplicationUser>();
}
Config.cs
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("AuthorizationWebApi","Authorization Web API .NET Core"),
new ApiResource("AuthorizationWebApiNetFramework","Authorization Web API NET Framework"),
new ApiResource("api1", "Empty Test Api")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client> {
new Client {
ClientId = "silicon",
ClientName = "console app",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = { new Secret("abcdef".Sha256())},
AllowedScopes = new List<string>{
"AuthorizationWebApiNetFramework"
}
},
new Client
{
ClientId = "MYUX",
ClientName = "MYUX MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false,
ClientSecrets= {new Secret("abcdef".Sha256()) },
RedirectUris = { "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = {"http://localhost:5002"},
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"custom.profile",
"AuthorizationWebApi",
"AuthorizationWebApiNetFramework"
},
AllowOfflineAccess = true
}
};
}
.NET Framework APİ Side
public void Configuration(IAppBuilder app)
{
//ConfigureAuth(app);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://www.abcdefgh.com:5000",
ValidationMode = ValidationMode.ValidationEndpoint,
RequiredScopes = new[] { "AuthorizationWebApiNETFramework" }
});
//configure web api
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
//require authentication for all controllers
config.Filters.Add(new AuthorizeAttribute());
app.UseWebApi(config);
}
Calling side:
try
{
ViewData["Message"] = "Authorization Test.";
var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");
var authorizationApiClient = new HttpClient();
authorizationApiClient.SetBearerToken(accessToken);
var content = await authorizationApiClient.GetStringAsync("http://localhost:13243/values");
return View();
}
catch (Exception ex)
{
throw;
}
or by a console app...
try
{
// discover endpoints from metadata
var disco = await DiscoveryClient.GetAsync("http://www.abcdefgh.com:5000");
var tokenClient = new TokenClient(disco.TokenEndpoint, "silicon", "abcdef");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("AuthorizationWebApiNetFramework");
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.Json);
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);
var response = await client.GetAsync("http://localhost:13243/values");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}
}
catch (Exception)
{
throw;
}
EDIT: On 4.5.2 Api side: I commented out the line ValidationMode = ValidationMode.ValidationEndpoint. I added this line by following IS3 documentation. Thanks everyone.
IdentityServer3. IdentityServer is a framework and a hostable component that allows implementing single sign-on and access control for modern web applications and APIs using protocols like OpenID Connect and OAuth2.
About IdentityServer4IdentityServer is a free, open source OpenID Connect and OAuth 2.0 framework for ASP.NET Core.
To get a new access token, you send the refresh token to the token endpoint. This will result in a new token response containing a new access token and its expiration and potentially also a new refresh token depending on the client configuration (see above).
Remove the following line in the WebAPI accesstoken validation middleware.
ValidationMode = ValidationMode.ValidationEndpoint
The result should look like this:
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://www.abcdefgh.com:5000",
RequiredScopes = new[] { "AuthorizationWebApiNETFramework" }
});
In my case, I enabled the log following this: https://identityserver.github.io/Documentation/docsv2/consuming/diagnostics.html
By default Katana uses the TraceSource mechanism in .NET for logging. Add the following snippet to your config file to enable logging to a file:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="Microsoft.Owin">
<listeners>
<add name="KatanaListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="KatanaListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="katana.trace.log"
traceOutputOptions="ProcessId, DateTime" />
</sharedListeners>
<switches>
<add name="Microsoft.Owin"
value="Verbose" />
</switches>
</system.diagnostics>
Then I saw the root cause in WebAPI folder log file "katana.trace.log":
Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed
System.IO.FileLoadException: Could not load file or assembly 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'
at IdentityServer3.AccessTokenValidation.ValidationEndpointTokenProvider.<ReceiveAsync>d__1.MoveNext()
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
at IdentityServer3.AccessTokenValidation.ValidationEndpointTokenProvider.ReceiveAsync(AuthenticationTokenReceiveContext context)
at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()
After I upgraded the Newtonsoft.Json from 6.0 to 9.01, it worked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With