2014-11-10 2 views
2

Я пытаюсь получить эту работу, но пока не повезло. Мой атрибут Авторизоваться работает сама по себе, но как только я сформулирую роль, которую пользователь должен быть отделено, то я получаю следующее сообщение вернулся из 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; } 

} 

Я уверен, что я что-то не хватает, но я просто AINT уверен какие. Любая помощь очень ценится

+1

Отладка вашего веб-API и просмотр объекта пользователя. Удостоверьтесь, что это 1) пользователь, которого вы считаете нужным, и 2) что он действительно имеет ту роль, какую вы думаете. Одно из них не так. –

+0

Знаете ли вы, какой класс/метод/функция вызывается, где токен преобразуется и извлекается личность? – Gillardo

+0

Вы не сможете в это поделать. Просто проверьте значение внутри вашего действия. –

ответ

2

кажется, что эта функция вызывала ошибку. Я не устанавливал имя пользователя (которое не заставляло его ломаться, но у свойства 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); 

    } 
+0

У меня была такая же проблема, и она работала, когда я добавил несколько ролей, как вы это делали. – Intrepid

1

Это не будет масштабироваться, если у вас есть новые роли, вы должны создать это динамически, пожалуйста, проверьте my answer на этот SO вопрос, который очень идентичен для Вашего случая, но проверить, как вы получаете роли пользователей из БД не жесткого кода, то, что вы сейчас делаете, назначает одинаковые роли для всех пользователей, прошедших проверку подлинности, что не имеет смысла.

Я предполагаю, что этот код взят из http://bitoftech.net сообщений об авторизации, если это так, пожалуйста, удалите ниже LOC, какая доза не имеет смысла в вашем случае.

identity.AddClaim(new Claim("sub", context.UserName)); 
+0

Мне действительно нужны роли из базы данных, но не знаю, где и когда это делать. Кроме того, у меня больше возможностей для роли/разрешений, а размер токена доступа увеличивается. Я проверю ур другой ответ спасибо – Gillardo

+0

Проверено ур ответ .. Арент, вы говорите, чтобы сделать это, как я сказал в ответе на этот вопрос? – Gillardo

+0

Идите с динамическим способом, который загружает роли из БД, а не статически назначает их, но наблюдайте размер маркера, если у вас есть несколько ролей. –

0

Я думаю, что у вас есть небольшая проблема с вашим aproach. Любой пользователь будет иметь все роли ...

Мое решение было следующим:

1) Для того, чтобы получить массив претензий через функцию CreateIdentityAsync:

var claims = await _service.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); 

2) Добавить массив претензий к объект идентичности:

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); 
    } 

Вот и все.

Смежные вопросы