2017-02-13 1 views
1

В моем текущем приложении я использую Service Stack с JWT для обеспечения безопасности. Безопасность была реализована и работает отлично. Проблема в том, что я хотел бы защитить один маршрут от других. Появляется документ, который регистрирует пользователь, я хочу убедиться, что документ, который они извлекают, является его, а не чужой. Это очень чувствительные данные. Я хотел бы защитить его по-другому, потому что что-то вроде PostMan можно использовать с действительным токеном для извлечения любого документа, я хочу предотвратить это. Идентификатор пользователей находится в токене, я хотел бы сопоставить его с документом, который извлекается, если это возможно. В настоящее время безопасность реализована следующим образом:Service Stack - Пользовательская аутентификация по одному маршруту

public class AppHost: AppHostBase 
{ 

    public override void Configure(Funq.Container container) 
    { 
     Plugins.Add(new AuthFeature(() => new AuthUserSession(), 
      new IAuthProvider[] { 
      new JsonWebTokenAuthProvider("myKey", "myAudience"), 
     })); 
    } 
} 

JsonWebTokenAuthProvider это пользовательский класс, где была реализована безопасность, все это прекрасно работает. Вот код:

public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request) 
    { 
     // first validate the token, then get roles from session 
     string header = request.oauth_token; 

     // if no auth header, 401 
     if (string.IsNullOrEmpty(header)) 
     { 
      throw HttpError.Unauthorized(MissingAuthHeader); 
     } 

     string[] headerData = header.Split(' '); 

     // if header is missing bearer portion, 401 
     if (!string.Equals(headerData[0], "BEARER", StringComparison.OrdinalIgnoreCase)) 
     { 
      throw HttpError.Unauthorized(InvalidAuthHeader); 
     } 

     // swap - and _ with their Base64 string equivalents 
     string secret = SymmetricKey.Replace('-', '+').Replace('_', '/'); 
     string token = headerData[1].Replace("\"", ""); 
     // set current principal to the validated token principal 

     Thread.CurrentPrincipal = JsonWebToken.ValidateToken(token, secret, Audience, true, Issuer); 
     string lanId = GetLanID(Thread.CurrentPrincipal.Identity.Name); 
     string proxyAsLanId = request.Meta.ContainsKey(META_PROXYID) ? request.Meta[META_PROXYID] : null; 

     if (HttpContext.Current != null) 
     { 
      // set the current request's user the the decoded principal 
      HttpContext.Current.User = Thread.CurrentPrincipal; 
     } 

     // set the session's username to the logged in user 
     session.UserName = Thread.CurrentPrincipal.Identity.Name; 
     session.Roles = GetApplicableRoles(lanId, proxyAsLanId); 

     authService.Request.SetItem("lanID", lanId); 
     authService.Request.SetItem("proxyAsLanId", proxyAsLanId); 

     return OnAuthenticated(authService, session, null, null); 
    } 

Я посмотрел RequestFilterAttribute нашел here, но я не думаю, что это то, что я хочу. В идеале, если проверка не удалась, я хотел бы вернуть 401 (несанкционированный), если это возможно.

Каков наилучший способ для этого?

ответ

2

Если вы просто хотите, чтобы обработать один маршрут иначе, чем вы можете просто добавить проверку в вашей одной службы, например:

public object Any(MyRequest dto) 
{ 
    var lanId = base.Request.GetItem("lanId"); 
    if (!MyIsValid(lanId)) 
     throw HttpError.Unauthorized("Custom Auth Validation failed"); 
} 

Вы могли бы сделать то же самое в RequestFilter, например:

public class CustomAuthValidationAttribute : RequestFilterAttribute 
{ 
    public override void Execute(IRequest req, IResponse res, object responseDto) 
    { 
     var lanId = req.GetItem("lanId"); 
     if (!MyIsValid(lanId)) 
     { 
      res.StatusCode = (int) HttpStatusCode.Unauthorized; 
      res.StatusDescription = "Custom Auth Validation failed"; 
      res.EndRequest(); 
     } 
    } 
} 

и применить его к одной службы:

[CustomAuthValidation] 
public object Any(MyRequest dto) 
{ 
    //... 
} 

или набор служб, например:

[CustomAuthValidation] 
public class MyAuthServices : Service 
{ 
    public object Any(MyRequest1 dto) 
    { 
     //... 
    } 
    public object Any(MyRequest2 dto) 
    { 
     //... 
    } 
} 
+0

Да, это именно то, что я искал !! Благодарю вас: D – TheMiddleMan

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