28

すべての場合に安全なフラグを使用してJSESSIONIDCookieを作成するようにTomcat7を構成する方法はありますか?

通常の構成では、httpsを介して接続が確立されている場合にのみ、TomcatがセキュアフラグでセッションCookieにフラグを立てます。ただし、私の実稼働シナリオでは、Tomcatはhttps接続を処理(および終了)し、http経由でtomcatに接続するリバースプロキシ/ロードバランサーの背後にあります。

プレーンhttpを介して接続されている場合でも、TomcatとのセッションCookieに安全なフラグを強制することはできますか?

4

3 に答える 3

47

最終的に、最初のテストとは反対に、Tomcat 7 では web.xml ソリューションが機能しました。

たとえば、このスニペットを web.xml に追加すると、リバース プロキシがプレーン HTTP 経由で Tomcat に接続する場合でも、セッション Cookie が安全であるとマークされます。

<session-config>
    <cookie-config>
        <http-only>true</http-only>
        <secure>true</secure>
    </cookie-config>
</session-config>
于 2013-03-08T10:55:48.797 に答える
8

ServletContext.getSessionCookieConfig().setSecure(true)

于 2013-02-20T21:04:50.433 に答える
1

マークと同様の別のアプローチは、を使用することSessionCookieConfigですが、JNDI 構成からコンテキスト リスナーに設定します。

コード:

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.SessionCookieConfig;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class JndiSessionCookieConfigListener implements ServletContextListener {
    private static final Logger logger = LoggerFactory.getLogger( JndiSessionCookieConfigListener.class );

    private volatile Context jndiSessionCookieConfig;
    private volatile SessionCookieConfig sessionCookieConfig;

    @Override
    public void contextInitialized( ServletContextEvent sce ) {
        String listenerName = getClass().getSimpleName();
        try {
            logger.info( "JNDI override session cookie config found for {}", listenerName );
            jndiSessionCookieConfig = (Context) new InitialContext().lookup(
                    "java:comp/env/" + listenerName );
        }
        catch ( NamingException e ) {
            logger.info( "No JNDI override session cookie config found for {}", listenerName );
        }

        sessionCookieConfig = sce.getServletContext().getSessionCookieConfig();

        String comment = getString( "comment" );
        if ( comment != null ) {
            logger.debug( "\t[comment]: [{}]", comment );
            sessionCookieConfig.setComment( comment );
        }

        String domain = getString( "domain" );
        if ( domain != null ) {
            logger.debug( "\t[domain]: [{}]", domain );
            sessionCookieConfig.setDomain( domain );
        }

        Boolean httpOnly = getBoolean( "http-only" );
        if ( httpOnly == null ) {
            sessionCookieConfig.setHttpOnly( true );
        }
        else {
            logger.debug( "\t[http-only]: [{}]", httpOnly );
            sessionCookieConfig.setHttpOnly( httpOnly );
        }

        Integer maxAge = getInteger( "max-age" );
        if ( maxAge != null ) {
            sessionCookieConfig.setMaxAge( maxAge );
        }

        String name = getString( "name" );
        if ( name != null ) {
            logger.debug( "\t[name]: [{}]", name );
            sessionCookieConfig.setName( name );
        }

        String path = getString( "path" );
        if ( path != null ) {
            logger.debug( "\t[path]: [{}]", path );
            sessionCookieConfig.setPath( path );
        }

        Boolean secure = getBoolean( "secure" );
        if ( secure == null ) {
            sessionCookieConfig.setSecure( true );
        }
        else {
            logger.debug( "\t[secure]: [{}]", secure );
            sessionCookieConfig.setSecure( secure );
        }
    }

    @Override
    public void contextDestroyed( ServletContextEvent sce ) {
    }

    private Boolean getBoolean( String name ) {
        Object value;
        try {
            value = jndiSessionCookieConfig.lookup( name );
            if ( value instanceof Boolean ) {
                return (Boolean)value;
            }
            else {
                return Boolean.valueOf( value.toString() );
            }
        }
        catch ( NamingException e ) {
            return null;
        }
    }

    private Integer getInteger( String name ) {
        Object value;
        try {
            value = jndiSessionCookieConfig.lookup( name );
            if ( value instanceof Integer ) {
                return (Integer)value;
            }
            else {
                return Integer.valueOf( value.toString() );
            }
        }
        catch ( NamingException e ) {
            return null;
        }
    }

    private String getString( String name ) {
        Object value;
        try {
            value = jndiSessionCookieConfig.lookup( name );
            return value.toString();
        }
        catch ( NamingException e ) {
            return null;
        }
    }
}

web.xml 内:

...
  <listener>
    <listener-class>
      org.mitre.caasd.servlet.init.JndiSessionCookieConfigListener
    </listener-class>
  </listener>
...

あなたのcontext.xmlで:

...
<Environment name="JndiSessionCookieConfigListener/secure"
  type="java.lang.String"
  override="false"
  value="true" />
...

これにより、デプロイメント環境で実行時にすべてのセッション Cookie 構成を設定できます。したがって、同じ webapp (war ファイル) を使用して、ローカル (https を持たない場所) で開発を行うことも、常に https が必要な本番環境で行うこともできます

このアプローチはOWASP のドキュメントに記載されていることに注意してください。

于 2016-06-17T14:17:51.323 に答える