3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Struts2にSpringSecurityを適用する方法

Posted at

認証機能をSpringSecurityに任せる

Struts2は特に認証用の機能はありません。
サーブレット標準の認証(JAAS)を使いログイン/ログアウトを構築できますが、それよりも高度な機構を備えるSpringSecurityを組み合わせることで、認証ならびにアクセス制御をSpringSecurityに任せ、ログイン後やログアウト後の追加処理をStruts2で実装することも可能です。

必要なjarファイルたち(mavenで設定)

以下の設定はSpringSecurity-4.0.0.CI版のものですが、正式リリース後はCIをRELEASEに置き換えるだけです。

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>archetype.group.id</groupId>
	<artifactId>artifactId</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<properties>
		<java.version>1.7</java.version>
		<spring-security.version>4.0.0.CI-SNAPSHOT</spring-security.version>
		<struts2.version>2.3.20</struts2.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>${struts2.version}</version>
		</dependency>
		<dependency>
 			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-convention-plugin</artifactId>
			<version>${struts2.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>${spring-security.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>${spring-security.version}</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<encoding>UTF-8</encoding>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<name>appname</name>
	<url>http://your.domain/appname</url>
	<description>descriptions....</description>
</project>

設定ファイルの修正・追加

SpringSecurityのサーブレットフィルタを有効にします。以下のxmlファイルを編集します。

  • web.xml
  • applicationContext-security.xml(ファイル名はweb.xmlに記載したもの)

web.xml

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="app_id" version="3.0"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<display-name>appname</display-name>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/applicationContext.xml,classpath:spring/applicationContext-*.xml</param-value>
	</context-param>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>
</web-app>

applicationContext-security.xml

この例では別途 Springの定義で、JDBCのデータソースを dataSourceの名前で定義が必要です。web.xmlにて、配置名をclasspath:spring/applicationContext.xml,classpath:spring/applicationContext-*.xml と宣言しています。配置場所はお好みでどうぞ。

私の場合はspringディレクトリを作成し、その中に applicationContext-security.xml を配置します。

applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
  xmlns:sec="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security.xsd">

  <sec:http auto-config='true'>
    <!-- CSRF回避チェックを有効 -->
    <sec:csrf/>

    <!-- アクセス制御をしないURLを定義 -->
    <sec:intercept-url pattern="/login*" access="permitAll"/>
    <sec:intercept-url pattern="/css/**" access="permitAll" />
    <sec:intercept-url pattern="/fonts/**" access="permitAll"/>
    <sec:intercept-url pattern="/images/**" access="permitAll"/>
    <sec:intercept-url pattern="/js/**" access="permitAll"/>
    <sec:intercept-url pattern="/templates/**" access="permitAll"/>

    <!-- ロールに ROLE_ADMIN を持つユーザID(USERNAME)のみアクセス許可 -->
    <sec:intercept-url pattern="/*" access="hasRole('ROLE_ADMIN')" />

    <!-- FORM認証の振る舞い -->
    <sec:form-login
        login-page="/login.action"
        login-processing-url="/j_spring_security_check"
        username-parameter="j_username"
        password-parameter="j_password"
        authentication-failure-url="/loginFailure.action" />

    <!-- ログアウト時の振る舞い -->
    <sec:logout 
        logout-url="/logout"
        logout-success-url="/logout.action"
        invalidate-session="true" />
  </sec:http>

  <!-- データベースを使った認証管理 -->
  <sec:authentication-manager alias="authManager">
    <sec:authentication-provider>
      <sec:jdbc-user-service data-source-ref="dataSource"
        users-by-username-query="
          SELECT
            USERNAME
          , PASSWORD
          , ENABLED
          FROM
            USERTABLE
          WHERE
            USERNAME = ?"
        authorities-by-username-query="
          SELECT
            USERNAME 
          , AUTHORITY 
          FROM 
            ROLETABLE 
          WHERE 
            USERNAME = ?"
      />
    </sec:authentication-provider>
  </sec:authentication-manager>
  <beans:bean 
    id="sessionRegistry" 
    class="org.springframework.security.core.session.SessionRegistryImpl" />
</beans:beans>

認証するための情報を取得する先は、<sec:authentication-manager alias="authManager">\で定義します。この例ではSQLを発行してデータベースに問い合わせます。データベース接続はSpring管理下にある dataSource の名前で管理されたSpring-beanです。
dataSourceの設定例をおまけで次に紹介します。

applicationContext-dataSource.xml

Spring管理下でdataSourceを作ります。

applicationContext-dataSource.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
default-autowire="byName"
>
    <!-- Springトランザクション管理クラス -->
    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource"><ref bean="dataSource"/></property>
    </bean>

    <!-- トランザクション定義でSpringアノテーション利用を宣言する。 -->
	<tx:annotation-driven transaction-manager="transactionManager"
      proxy-target-class="true" />

    <!-- JNDIルックアップ -->
	<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/dbcon"></jee:jndi-lookup>
</beans>

この例では、データベース接続のソースをTomcatなどのコンテナから拝借します。その際、JNDIで定義した命名で指定します。

データソースを使う場合には、pom.xmlにて必要なSpring frameworkを追加します。
以下は追加例です。

pom.xml(断片)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
    <artifactId>artifactId</artifactId>
    <name>appname</name>
    <properties>
        <!-- ここから追加 -->
        <spring.version>4.1.3.RELEASE</spring.version>
        <!-- ここまで -->
    </properties>
    <dependencies>
        <!-- ここから追加 -->
        <dependency>
        	<groupId>org.springframework</groupId>
        	<artifactId>spring-core</artifactId>
        	<version>${spring.version}</version>
        </dependency>
        <dependency>
        	<groupId>org.springframework</groupId>
        	<artifactId>spring-web</artifactId>
        	<version>${spring.version}</version>
        </dependency>
        <dependency>
        	<groupId>org.springframework</groupId>
        	<artifactId>spring-beans</artifactId>
        	<version>${spring.version}</version>
        </dependency>
        <dependency>
        	<groupId>org.springframework</groupId>
        	<artifactId>spring-context</artifactId>
        	<version>${spring.version}</version>
        </dependency>
        <dependency>
        	<groupId>org.springframework</groupId>
        	<artifactId>spring-context-support</artifactId>
        	<version>${spring.version}</version>
        </dependency>
        <dependency>
        	<groupId>org.springframework</groupId>
        	<artifactId>spring-tx</artifactId>
        	<version>${spring.version}</version>
        </dependency>
        <!-- ここまで -->
    </dependencies>
</project>
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?