2014-10-25 3 views
3

Я занимаюсь созданием собственного webapi в asp.net, используя oauth в качестве поставщика авторизации. Api wil в основном служит поставщиком для разных модулей, как я их называю. Можно быть галереей изображений, другой может быть просто модулем входа пользователя с разными типами пользователей.Webapi с несколькими токенами oauth для разных пользователей

У меня есть часть oauth, работающая нормально. Пользователи Api могут зарегистрироваться, а затем запросить токен, вызывая конечную точку/Token с учетными данными входа.

Однако теперь я хочу создать еще один отдельный пользовательский модуль в api, который доступен только зарегистрированным пользователям. Я хочу, чтобы этот модуль имел другую функцию регистрации и входа в систему и имел свою конечную точку для входа (/ UserModuleToken или что-то в этом роде). Пользователи, поступающие из пользовательского модуля, являются разными пользователями, чем пользователи Api. Таким образом, apiusers являются фактическими разработчиками, которые хотят вызывать определенные модули в моем api, а пользователи из пользовательского модуля - это пользователи, которые регистрируются на сайте, где этот модуль реализован.

Все мои apicontrollers имеют атрибут [Authorize] для пользователя api, и я хочу, чтобы некоторые из них, например, некоторая функция в пользовательском модуле, были украшены атрибутом [UserModuleAuthorize].

Ниже вы можете увидеть мой апите объект пользователя модель:

public class ApiUserEntity : BaseEntity 
{ 
    public string Username { get; set; } 
    public string Password { get; set; } 
    public string Email { get; set; } 
    public string Salt { get; set; } 
    public ApiUserLevel Level { get; set; } 
} 

Функции UserService, которая может проверить-пользователь апи:

public UserLoginResult LoginUser(ApiUserEntityLoginForm userForm) 
{ 
    // retrieve user from database 
    var user = _userRepository.GetUser(userForm.UserName); 

    if(user == null) 
     return _modelStateWrapper.AddError(UserLoginResult.UserNotFound, "User does not exist"); 

    var passwordHash = PasswordHash.HashPassword(user.Salt, userForm.Password); 

    // check if password matches with database. 
    if (passwordHash != user.Password) 
     return _modelStateWrapper.AddError(UserLoginResult.IncorrectPassword, "Incorrect password"); 

    return UserLoginResult.Success; 
} 

И вызов конечной точки/лексем в моем WebAPI будет называть следующая функция от поставщика токенов:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
{ 

    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); 

    // create a userloginform object : 
    var loginForm = new ApiUserEntityLoginForm {UserName = context.UserName, Password = context.Password}; 

    // pass it into the login validation function of the userservice: 
    var loginResult = _userService.LoginUser(loginForm); 

    // if login result was not sucesful, return an error. 
    if (loginResult != UserLoginResult.Success) 
    { 
     var jsonSerialiser = new JavaScriptSerializer(); 
     var json = jsonSerialiser.Serialize(_userService.Errors()); 

     context.SetError("invalid_grant", json); 
     return; 
    } 

    // result was succesful, grant the token. 
    var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
    identity.AddClaim(new Claim("sub", context.UserName)); 
    identity.AddClaim(new Claim("role", "user")); 

    context.Validated(identity); 

} 

i конфигурируйте мой oauth provi дер и определить конечную точку/токен с помощью следующей функции:

public static void ConfigureOAuth(IAppBuilder app, IUnityContainer container) 
{ 

    var simpleAuthorizationServerProvider = container.Resolve<SimpleAuthorizationServerProvider>(); 

    var OAuthServerOptions = new OAuthAuthorizationServerOptions() 
    { 
     AllowInsecureHttp = true, 
     TokenEndpointPath = new PathString("/token"), 
     AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
     Provider = simpleAuthorizationServerProvider 
    }; 

    // Token Generation 
    app.UseOAuthAuthorizationServer(OAuthServerOptions); 
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 

} 

Теперь мой вопрос, если это как-то можно иметь несколько конечных точек маркеров, так что я могу иметь маркер для apiusers, а затем еще один для пользователя, который является используя пользовательский модуль пользователя и защищать определенные функции на основе этих двух пользователей.

Я не смог найти информацию об этом после обширного поиска в Интернете. Поэтому я начинаю полагать, что это не хорошая практика или невозможна. Если кто-нибудь сможет указать мне в правильном направлении, это было бы здорово!

+0

Я считаю, что вы усложняете ситуацию, почему бы вам не справиться с этим через роли, где ваш apis проверяет роли? Я имею в виду, что разработчики, которые хотят получить доступ к вашему apis, будут играть роль, которую вы можете проверить в своем атрибуте authorizarion. –

+0

Прочитайте спецификацию по адресу http://tools.ietf.org/html/rfc6749, она должна прояснить ситуацию. –

+0

Спасибо, ребята, действительно, роли лучше для моих целей. –

ответ

9

Ну, я считаю, вам нужно настроить авторизацию пользователей на основе ролей, то, что вы пытаетесь сделать, просто усложняет ваше решение. Вы можете сделать следующее: внутри метода GrantResourceOwnerCredentials вам нужно получить правильную роль для аутентифицированного пользователя из хранилища DB, то есть «Admin», а затем добавить их в качестве претензий типа «Роль» в качестве кода ниже:

identity.AddClaim(new Claim(ClaimTypes.Role, "Admin")); 
identity.AddClaim(new Claim(ClaimTypes.Role, "Supervisor")); 

Теперь на ваших контроллерах вы хотите, чтобы только пользователь имел роль «Администратор» для доступа; вам необходимо указать [Authorize(Roles="Admin")] или, может быть, несколько ролей. [Authorize(Roles="Admin,User")]

Это самый прямой способ достичь своей цели.

Btw этот код от http://bitoftech.net, справа? Рад видеть, что мои образцы кода были использованы :) Сообщите мне, если вам нужны дополнительные разъяснения.

+0

Ваш гид действительно очень помог мне! Большое спасибо! Я понимаю, что вы подразумеваете, делая это слишком сложным. Роли - это идеальное решение для моей безопасности. Я также очень хочу каким-то образом отличить пользователей, зарегистрированных на сайте, от разработчиков, зарегистрированных в качестве разработчика. Я хочу, чтобы они были разными сущностями и имели разные свойства, но могли получить доступ к моей api с их конкретной ролью. Кажется, что это невозможно сейчас, потому что они входят в систему с одинаковой функциональностью. Но теперь я думаю, что мне нужно решить эту проблему в моей логике входа, а не в api. –

+0

У меня другое требование. Для конкретных запросов я хочу, чтобы конечная точка маркера выдает токен неэкспирации. Это возможно? – Jami

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