我尝试使用IdentityServer3和Client Credential流程设置一个简单示例。该示例包含一个控制台客户端,该客户端使用从IdentityServer接收的令牌调用Web API资源。 Web API和IdentityServer托管在IIS中。
我设法使用以下方式从IdentityServer获取令牌:
var client = new TokenClient(
"https://machine+domain/WebHostedId3/connect/token",
"client",
"secret");
但是当我尝试使用以下方法调用Web API时
var client = new HttpClient();
client.SetBearerToken(token);
var response = client.GetStringAsync("http://localhost/WebHostedApi/api/products").Result;
我接收到401(响应状态代码并不表示成功:401(未经授权)。
IdentityServer的设置如下:
public class Clients
{
public static List<Client> Get()
{
return new List<Client>
{
new Client
{
ClientName = "Client Credentials Flow Client",
Enabled = true,
ClientId = "client",
AccessTokenType = AccessTokenType.Reference,
ClientSecrets = new List<Secret>
{
new Secret("secret".Sha256())
},
Flow = Flows.ClientCredentials,
AllowedScopes = new List<string>
{
"api"
}
}
};
}
}
public class Scopes
{
public static IEnumerable<Scope> Get()
{
return new[]
{
new Scope
{
Name = "api",
DisplayName = "API Scope",
Type = ScopeType.Resource,
Emphasize = false
}
};
}
}
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Trace(outputTemplate: "{Timestamp} [{Level}] ({Name}){NewLine} {Message}{NewLine}{Exception}")
.CreateLogger();
var factory = new IdentityServerServiceFactory()
.UseInMemoryUsers(new System.Collections.Generic.List<InMemoryUser>())
.UseInMemoryClients(Clients.Get())
.UseInMemoryScopes(Scopes.Get());
var options = new IdentityServerOptions
{
Factory = factory,
};
appBuilder.UseIdentityServer(options);
}
}
Web API:
public static class WebApiConfig
{
public static HttpConfiguration Register()
{
var config = new HttpConfiguration();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultRouting",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// require authentication for all controllers
config.Filters.Add(new AuthorizeAttribute());
return config;
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Trace(outputTemplate: "{Timestamp} [{Level}] ({Name}){NewLine} {Message}{NewLine}{Exception}")
.CreateLogger();
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "machine+domain:443",
ValidationMode = ValidationMode.ValidationEndpoint,
RequiredScopes = new[] { "api" }
});
app.UseWebApi(WebApiConfig.Register());
}
}
用于SSL的证书是使用IIS创建自签名证书功能创建的,并连接到IdentityServer的https绑定。除了&#34;响应状态代码不表示成功:401(未授权)&#34;例外我无法找到更多细节。 IdentityServer的日志看起来不错。非常感谢帮助。
答案 0 :(得分:0)
我知道答复很晚。尝试更新所有nugets,尤其是Newtonsoft.Json到8.0.3
答案 1 :(得分:0)
对于非常晚的响应感到抱歉,但如果您在IdentityServer中启用完整日志记录,它几乎会告诉您问题所在。
更改
var options = new IdentityServerOptions
{
Factory = factory,
};
到
var options = new IdentityServerOptions
{
Factory = factory,
LoggingOptions = new LoggingOptions
{
EnableWebApiDiagnostics = true,
WebApiDiagnosticsIsVerbose = true,
EnableHttpLogging = true,
EnableKatanaLogging = true
}
}
然后你会看到很多很好的调试信息,告诉你出了什么问题。
答案 2 :(得分:0)
在您的WebAPI配置中,IdentityServerBearerTokenAuthenticationOptions
中的属性Authority
的值不正确。它必须是IdentityServer实例的基URI,即https://localhost/WebHostedId3
,而不仅仅是localhost
,localhost:443
。
考虑到IdentityServer3默认需要TLS,那么您需要指定https
方案,而不仅仅是http
。
因此,只要您的IdentityServer基本URI为https://localhost/WebHostedId3
,那么正确的设置将如下所示
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://localhost/WebHostedId3",
ValidationMode = ValidationMode.ValidationEndpoint,
RequiredScopes = new[] { "api" }
});