禁止使用OpenIdConnect和angularjs:Bear进行基于Asp.net核心令牌的声明身份验证
我将Asp.net core rc2与OpenIdConnectServer一起使用。我在augular-oauth2中使用angular 1.x。过了几天,我的错误已经偏离了主题禁止使用OpenIdConnect和angularjs:Bear进行基于Asp.net核心令牌的声明身份验证,angularjs,oauth-2.0,asp.net-core,openid-connect,aspnet-contrib,Angularjs,Oauth 2.0,Asp.net Core,Openid Connect,Aspnet Contrib,我将Asp.net core rc2与OpenIdConnectServer一起使用。我在augular-oauth2中使用angular 1.x。过了几天,我的错误已经偏离了主题 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:54275/api/Account/Username Microsoft.AspNetCore.Aut
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:54275/api/Account/Username
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: Successfully validated the token.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Bearer.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: AuthenticationScheme: Bearer was successfully authenticated.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: .
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Warning: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (Bearer).
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: AuthenticationScheme: Bearer was forbidden.
我的配置服务包括
services.AddAuthorization(options =>
{
options.AddPolicy("UsersOnly", policy =>
{
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
policy.RequireClaim("role");
});
});
我的配置有
app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch =>
{
branch.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
RequireHttpsMetadata = false,
Audience = "http://localhost:54275/",
Authority = "http://localhost:54275/",
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = "client1",
//ValidAudiences = new List<string> { "", "empty", "null"}
}
});
});
app.UseOpenIdConnectServer(options =>
{
options.AuthenticationScheme = OpenIdConnectServerDefaults.AuthenticationScheme;
options.Provider = new SimpleAuthorizationServerProvider();
options.AccessTokenHandler = new JwtSecurityTokenHandler();
options.ApplicationCanDisplayErrors = true;
options.AllowInsecureHttp = true;
options.TokenEndpointPath = new PathString("/oauth2/token");
options.LogoutEndpointPath = new PathString("/oauth2/logout");
options.RevocationEndpointPath = new PathString("/oauth2/revoke");
options.UseJwtTokens();
//options.AccessTokenLifetime = TimeSpan.FromHours(1);
});
我将令牌存储为cookie,并使用http拦截器将其附加到请求中
我使用
public override async Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context)
{
// validate user credentials (demo mode)
// should be stored securely (salted, hashed, iterated)
using (var con = new SqlConnection(ConnectionManager.GetDefaultConnectionString()))
{
if (!Hashing.ValidatePassword(context.Password, await con.ExecuteScalarAsync<string>("SELECT PassHash FROM dbo.Users WHERE Username = @UserName", new { context.UserName })))
{
context.Reject(
error: "bad_userpass",
description: "UserName/Password combination was invalid."
);
return;
}
// create identity
var id = new ClaimsIdentity(context.Options.AuthenticationScheme);
id.AddClaim(new Claim("sub", context.UserName));
id.AddClaim(new Claim("role", "user"));
// create metadata to pass on to refresh token provider
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{"as:client_id", context.ClientId}
});
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id), props,
context.Options.AuthenticationScheme);
ticket.SetAudiences("client1");
//ticket.SetScopes(OpenIdConnectConstants.Scopes.OpenId, OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile, "api-resource-controller");
context.Validate(ticket);
}
}
public override异步任务GrantResourceOwnerCredentials(GrantResourceOwnerCredentials上下文)
{
//验证用户凭据(演示模式)
//应安全存储(盐渍、哈希、迭代)
使用(var con=new SqlConnection(ConnectionManager.GetDefaultConnectionString())
{
if(!Hashing.ValidatePassword(context.Password,wait con.ExecuteScalarAsync(“从dbo.Users中选择PassHash,其中Username=@Username”,new{context.Username})))
{
上下文。拒绝(
错误:“错误的用户通行证”,
描述:“用户名/密码组合无效。”
);
返回;
}
//创造身份
var id=新的ClaimsIdentity(context.Options.AuthenticationScheme);
id.AddClaim(新索赔(“sub”,context.UserName));
id.AddClaim(新声明(“角色”、“用户”));
//创建要传递给刷新令牌提供程序的元数据
var props=新的AuthenticationProperties(新字典
{
{“as:client_id”,context.ClientId}
});
var票证=新身份验证票证(新身份证、道具、,
context.Options.AuthenticationScheme);
票证。设置观众(“客户1”);
//ticket.SetScopes(OpenIdConnectConstants.Scopes.OpenId、OpenIdConnectConstants.Scopes.Email、OpenIdConnectConstants.Scopes.Profile,“api资源控制器”);
验证(票证);
}
}
我花了三天时间研究这个问题,我意识到在这一点上,我可能因为缺乏睡眠而错过了一些明显的东西。任何帮助都将不胜感激。您看到的错误可能是由两个因素造成的:
- 您没有将显式目标附加到自定义
声明,因此它永远不会在访问令牌中序列化。您可以找到有关此安全功能的更多信息角色
policy.require(“角色”)代码>可能不适用于OTB,因为IdentityModel使用内部映射将著名的JWT声明转换为其
等价物:此处,索赔类型
可能会被角色
(http://schemas.microsoft.com/ws/2008/06/identity/claims/role
)。我建议改用ClaimTypes.Role
policy.RequireRole(“用户”)
客户端id
是不必要的,因为OpenID Connect服务器中间件已经为您完成了这项工作
您可以使用
ticket.GetPresenters()
检索它,它返回授权演示者的列表(这里是客户端标识符)。请注意,它还自动确保发给客户端a的刷新令牌不能被客户端B使用,因此您不必在自己的代码中执行此检查。哪个dotnet core程序集包含扩展方法UseOpenIdConnectServer
public override async Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context)
{
// validate user credentials (demo mode)
// should be stored securely (salted, hashed, iterated)
using (var con = new SqlConnection(ConnectionManager.GetDefaultConnectionString()))
{
if (!Hashing.ValidatePassword(context.Password, await con.ExecuteScalarAsync<string>("SELECT PassHash FROM dbo.Users WHERE Username = @UserName", new { context.UserName })))
{
context.Reject(
error: "bad_userpass",
description: "UserName/Password combination was invalid."
);
return;
}
// create identity
var id = new ClaimsIdentity(context.Options.AuthenticationScheme);
id.AddClaim(new Claim("sub", context.UserName));
id.AddClaim(new Claim("role", "user"));
// create metadata to pass on to refresh token provider
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{"as:client_id", context.ClientId}
});
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id), props,
context.Options.AuthenticationScheme);
ticket.SetAudiences("client1");
//ticket.SetScopes(OpenIdConnectConstants.Scopes.OpenId, OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile, "api-resource-controller");
context.Validate(ticket);
}
}