90

私はSpringとSpringのセキュリティに比較的慣れていません。

Spring セキュリティを使用してサーバー側でユーザーを認証する必要があるプログラムを作成しようとしていましたが、

私は次のことを思いつきました:

public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider{
    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken)
                    throws AuthenticationException
    {
        System.out.println("Method invoked : additionalAuthenticationChecks isAuthenticated ? :"+usernamePasswordAuthenticationToken.isAuthenticated());
    }

    @Override
    protected UserDetails retrieveUser(String username,UsernamePasswordAuthenticationToken authentication) throws AuthenticationException 
    {
        System.out.println("Method invoked : retrieveUser");
        //so far so good, i can authenticate user here, and throw exception if not authenticated!!
        //THIS IS WHERE I WANT TO ACCESS SESSION OBJECT
    }
}

私のユースケースは、ユーザーが認証されたときに、次のような属性を配置する必要があるということです:

session.setAttribute("userObject", myUserObject);

myUserObject は、サーバー コード全体で複数のユーザー リクエストにアクセスできるクラスのオブジェクトです。

4

8 に答える 8

155

ここにいるあなたの友達はorg.springframework.web.context.request.RequestContextHolder

// example usage
public static HttpSession session() {
    ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
    return attr.getRequest().getSession(true); // true == allow create
}

これは、標準の spring mvc ディスパッチ サーブレットによって設定されますが、別の Web フレームワークを使用している場合は、ホルダーを管理するためにorg.springframework.web.filter.RequestContextFilterフィルターとして追加する必要があります。web.xml

EDIT :実際に何をしようとしているのかという副次的な問題として、 aHttpSessionretieveUserメソッドでにアクセスする必要があるかどうかはわかりませんUserDetailsService。Spring セキュリティは、UserDetails オブジェクトをセッションに配置します。以下にアクセスして取得できますSecurityContextHolder

public static UserDetails currentUserDetails(){
    SecurityContext securityContext = SecurityContextHolder.getContext();
    Authentication authentication = securityContext.getAuthentication();
    if (authentication != null) {
        Object principal = authentication.getPrincipal();
        return principal instanceof UserDetails ? (UserDetails) principal : null;
    }
    return null;
}
于 2009-10-27T07:32:40.813 に答える
34

Springを使用しているので、Springを使い続け、他の投稿のように自分でハックしないでください。

Springのマニュアルには次のように書かれています。

セキュリティ上の理由から、HttpSessionを直接操作しないでください。そうする理由はまったくありません。代わりに、常にSecurityContextHolderを使用してください。

セッションにアクセスするための推奨されるベストプラクティスは次のとおりです。

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {
  String username = ((UserDetails)principal).getUsername();
} else {
  String username = principal.toString();
}

ここで重要なのは、SpringとSpring Securityが、セッション固定防止のようなあらゆる種類の優れた機能を提供することです。これらは、Springフレームワークを使用するように設計されているため、使用していることを前提としています。したがって、サーブレットでコンテキストを認識させ、上記の例のようにセッションにアクセスします。

セッションスコープにデータを隠しておく必要がある場合は、この例のようにセッションスコープのBeanを作成して、autowireに魔法をかけてもらいましょう。:)

于 2012-10-17T19:13:24.607 に答える