0

私はSpring Security Frameworkを初めて使用し、ここで解決すべき小さな問題があります。

私はすでに @PreAuthorized("hasPermission('#person', Permission) アノテーションをサービスおよびコントローラーメソッドに使用することができました。これは私にとってはうまく機能しますが、これはドメインクラス全体でのみ機能します。

私の場合、この Person を読み取る権限がないにもかかわらず、ユーザーに表示する必要があるフィールドがいくつかあります。

簡単な例:

  1. ユーザーがログインします。
  2. 彼は、Jon Doe のプロフィール ページにアクセスしたいと考えています。
  3. しかし、ユーザーには Jon Doe を読む権利がありませんでした。
  4. システムは、ユーザーに権限がないことを通知し、「Jon Doe からプロファイルを読み取る権限がありません」のような名前を表示する必要があります。」

これは非常に単純な例です。ユーザーが表示できるフィールドは他にもあります。

私が求めていることを理解していただければ幸いです。

(私の英語が下手ですみません。)

編集

PersonController

 @RequestMapping("/{id}")
 public String get(@PathVariable("id") Long personId, Model model,HttpSession session) {

    Person person = personService.findById(personId);

    /* DO STUFF HERE */

    return "person.show";
}

個人サービス

@PreAuthorize("hasPermission('#personId', <domainClass>, 'read')")
public Person findById(Long personId) {
    return personRepository.findOne(personId);
}
4

1 に答える 1

0

@PreAuthorized("hasPermission('#person', Permission)アノテーションをまったく使用せず、代わりにコードで手動で行うことで明示的に行うことができます...しかし、それはSpring Securityフレームワークを使用する利点を部分的に損なうでしょう!

私はお勧めします:

  • @PreAuthorized("hasPermission('#person', Permission)サービス クラス レイヤーで注釈を使用=> AccessDeniedExceptionis user is not allowed to read that profile
  • AccessDeniedException呼び出し元のコントローラーにハンドラーを追加します。コントローラーのメソッドの実行中に例外がスローされるため、そのハンドラーにはそれを処理する機会が与えられます。パブリック フィールドのみを返し、Jon Doe からプロファイルを読み取る権限がないことを示すビューに転送する、関連するサービス クラスから保護されていないメソッドを呼び出します

その構成では、例外ハンドラーは、元のコントローラー メソッドと同等のパラメーターを取得してアクセスできるようにする必要があります。

  • Principalリクエストの実行
  • 要求されたプロファイルの ID

@RequestMappingただし、例外ハンドラーは、例外自体に加えて、メソッドが行うのとほぼ同じパラメーターを受け入れることができるため、これは問題にはなりません。

編集ごとにpersonId、例外ハンドラーから取得するのが難しいパス変数から取得します。したがって、保護されたサービス メソッドを呼び出して例外ハンドラで取得する前に、リクエスト属性として保存する必要があります。

 @RequestMapping("/{id}")
 public String get(@PathVariable("id") Long personId, Model model,HttpSession session, HttpServletRequest request) {

    request.setAttribute("personId", personId);
    Person person = personService.findById(personId);

    /* DO STUFF HERE */

    return "person.show";
} 

@ExceptionHandler(AccessDeniedException.class)
 public ModelAndView accessDeniedHandler(HttpServletRequest request) {
    ModelAndView mav = new ModelAndView("accessDeniedView");
    Long personId = request.getAttribute("personId");
    // populate your model
    return mav;
}
于 2015-04-22T12:26:09.853 に答える