2017-02-13 5 views
1

私の現在のアプリケーションでは、セキュリティのためにJWTでサービススタックを使用しています。セキュリティは実装され、完全に機能します。問題は、他のルートとは違ったルートを確保したいということです。ログインしたユーザーが取得したドキュメントがあり、取得しているドキュメントが他のユーザーではなく、自分のドキュメントであることを確認したい。非常に機密性の高いデータです。私はPostManのようなものが有効なトークンを使ってどんなドキュメントをも検索することができるので、違うようにしたいと思っています。私はこれを避けたいのです。ユーザーIDはトークンに含まれています。可能であれば、取得しているドキュメントと照合したいと思います。現在のセキュリティはそうのように実装されている:サービススタック - 1つのルート上のカスタム認証

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

関連する問題