2017-02-13 51 views
1

在我目前的应用程序自定义身份验证,我使用的服务栈与智威汤逊的安全。安全性已经得到实施并且完美运作。麻烦的是,我想确保一条路线与其他路线不同。有一个登录用户检索的文档,我想确保他们检索的文档是他们的而不是其他人的文档。这是非常敏感的数据。我想以不同的方式加以保护,因为像PostMan之类的东西可以与有效的令牌一起使用来检索任何文档,所以我想阻止它。用户标识位于标记中,如果可能,我想将其与正在检索的文档进行匹配。目前的安全实现,像这样:服务栈 - 中的一条路径

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