4

JSF/Primefaces アプリケーションに単純な認証を実装したいと考えています。私はさまざまなことを試しました。たとえば、Dialog - Login Demoはダイアログで簡単なテストを行いますが、ユーザーをログインさせませんか?

次のようなJavaセキュリティも調べました。

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Protected Area</web-resource-name>
        <url-pattern>/protected/*</url-pattern>
        <http-method>PUT</http-method>
        <http-method>DELETE</http-method>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>REGISTERED_USER</role-name>
    </auth-constraint>
</security-constraint>

これにより、 /protected の下にあるすべてが保護されますが、私が理解している限り、認証のためにサーバーにレルムを定義する必要があります。サーバーでこれを指定したくありませんが、データベースで単純なルックアップを行うだけです。

アプリケーションサーバーで何かを定義せずにユーザーを認証する方法はありますか? または、さまざまなページを認証して保護するための別の簡単なソリューションはありますか?

4

2 に答える 2

7

アプリケーションサーバーで何かを定義せずにユーザーを認証する方法はありますか?

これは長くて非常に厄介な話です。これは、Java EE に対する主な批判の 1 つとしてよく取り上げられます。

この話の核心は、伝統的に Java EE アプリケーションは「未解決の依存関係」でデプロイされることになっているということです。これらの依存関係は、通常、開発者以外の誰かが、多くの場合、ある種の GUI またはコンソールを使用して、アプリケーション サーバーで満たす必要があります。

セキュリティ構成は、未解決の依存関係の 1 つです。

セキュリティ構成がアプリケーション サーバーで行われる場合、これは定義上、常に移植可能ではありません。たとえば、アプリケーション サーバー固有の方法で行う必要があります。Userこの認証にアプリケーション ドメイン モデル (JPA エンティティなど) を使用することは完全に除外されます。

一部のサーバー (JBoss AS など) では、独自のセキュリティ メカニズムをアプリケーション内から構成できます。さらに、「カスタム ログイン モジュール」(この用語はほとんどすべてのサーバーで異なります) をアプリケーションからロードすることもできます。いくつかの小さなハックにより、アプリケーション ドメイン モデルと、アプリケーション自体が認証に使用するのと同じデータ ソースを使用できるようになります。

最後に、アプリケーション内から認証を行う、比較的知られていない移植可能な方法があります。これは、 JASPIまたはJSR 196とも呼ばれるJASPIC SPIを介して行われます。基本的に、このJASPICはあなたが探しているもののようです。

残念ながら、JASPIC は完璧ではありません。Java EE 6 のテクノロジであり、Java EE 7 に近づいていますが、現時点では、さまざまなアプリケーション サーバーでの JASPIC のサポートはまだ不完全です。その上、JASPIC は標準化されていますが、アプリケーション サーバー ベンダーは実際にそれを機能させるために何らかの形で独自の構成を必要としています。

現在の問題をより詳細に説明する JASPIC に関する記事を書きました: JASPIC を使用した Java EE でのコンテナー認証の実装

于 2012-12-29T22:01:52.130 に答える
0

Web フィルターを使用するだけで、適切で簡単な解決策を見つけました。次のように web.xml にフィルターを追加しました

<!-- Authentication Filter -->
<filter>
    <filter-name>AuthenticationFilter</filter-name>
    <filter-class>org.example.filters.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AuthenticationFilter</filter-name>
    <url-pattern>/protected/*</url-pattern>
</filter-mapping>

フィルターはこんな感じ

@WebFilter(filterName="AuthenticationFilter")
public class AuthenticationFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        Cookie[] cookies = ((HttpServletRequest)request).getCookies();

        // Try to find a valid session cookie
        if (cookies != null) {
            String sessionId = null;
            for (Cookie cookie : cookies) {
                if ("sessionId".equals(cookie.getName())) {
                        sessionId = cookie.getValue();
                }
            }

            // Check if we have a valid session
            UserSession session = Backend.getInstance().getSessionGateway().getBySessionId(sessionId);

            if (session != null) {
                chain.doFilter(request, response);
                return;
            } else if (sessionId != null) {
                // Remove the cookie
                Cookie cookie = new Cookie("sessionId", null);
                cookie.setMaxAge(-1);
                ((HttpServletResponse)response).addCookie(cookie);
            }
        }


//      Problem due to relative path!!
//      ((HttpServletResponse)response).sendRedirect("../login.xhtml");
        RequestDispatcher rd = request.getRequestDispatcher("/login.xhtml");
        rd.forward(request, response);
    }
}

したがって、セッション Cookie を認証して設定する Bean を実装するだけで済みました。セキュリティを強化するためにユーザー エージェントを追加しますが、基本的には機能します。

リダイレクトを実行できないという唯一の問題があります。これは、コンテキスト パスを使用していないため、/my_app_context/index.xhtml ではなく /index.xhtml にリダイレクトするだけです。

于 2012-12-31T15:09:41.917 に答える