我试图让这个工作,但到目前为止没有运气。我的Authorize属性可以自行运行,但是一旦我声明了一个用户必须分开的角色,那么我从webapi返回以下消息
{"message":"Authorization has been denied for this request."}
Startup.cs
public void Configuration(IAppBuilder app)
{
//HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app);
// simple injector
SimpleInjectorConfig.Register();
AutoMapperConfig.RegisterMappings();
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
}
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider(new AccountService(new DataContext()))
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
SimpleAuthorizationServerProvider.cs
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
private AccountService _service;
public SimpleAuthorizationServerProvider(AccountService service)
{
_service = service;
}
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
User user = await _service.FindUserAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
//identity.AddClaim(new Claim("role", "user"));
context.Validated(identity);
}
}
装饰控制器方法,我使用
[Authorize(Roles="CanViewCompany")]
如果我只使用它,它可以工作并返回我期望的数据
[Authorize]
我的基本用户类
public class User : IdentityUser<long, UserLogin, UserRole, UserClaim>, IUser<long>
{
public User()
: base()
{
this.Groups = new HashSet<UserGroup>();
}
public virtual ICollection<UserGroup> Groups { get; set; }
}
我确信我错过了一些东西,但我不确定是什么。任何帮助非常感谢
答案 0 :(得分:3)
似乎这个函数导致了错误。我没有设置用户名(它没有让它中断,但是User属性没有一个,我相信将来我还需要它。)
此外,我没有添加任何角色。我不确定这是否是解决此问题的正确方法,但它确实有效。
如果有人知道更好/正确的方法,请告诉我。
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
User user = await _service.FindUserAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim(ClaimTypes.Role, "CanViewCompany"));
identity.AddClaim(new Claim(ClaimTypes.Role, "CanAddCompany"));
identity.AddClaim(new Claim(ClaimTypes.Role, "CanEditCompany"));
identity.AddClaim(new Claim(ClaimTypes.Role, "CanDeleteCompany"));
context.Validated(identity);
}
答案 1 :(得分:1)
如果您有更新的角色,则无法扩展,您需要动态创建此角色,请检查my answer此SO问题,该问题与您的案例非常相似,但请检查您如何从DB获取用户角色对它们进行硬编码,您目前正在做的是为所有经过身份验证的用户分配相同的角色,这是没有意义的。
我想这段代码来自http://bitoftech.net有关授权的帖子,如果是这种情况,那么请删除下面的LOC,这对您的情况也没有意义。
identity.AddClaim(new Claim("sub", context.UserName));
答案 2 :(得分:0)
我认为你的aproach有点问题。任何用户都将拥有所有角色......
我的解决方案如下:
1)通过CreateIdentityAsync函数获取声明数组:
var claims = await _service.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
2)将claim数组添加到标识对象:
identity.AddClaims(claims.Claims);
一起显示代码......
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
User user = await _service.FindUserAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var claims = await _service.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaims(claims);
context.Validated(identity);
}
这就是全部。