spring securityの基本的なひな型プロジェクトの作り方

spring

ログインと認可(権限)をコントロールすることのできるSpring Securityの最低限必要な設定と基本的な使い方を紹介します。

とにかくSpring Securityを動かしたい!Spring Securityの使い方を覚えたい!という人向けの記事です。

[スポンサーリンク]

Spring Securityのバージョンは4.0をJavaのバージョンは8を使っています。2015年7月現在で最新のバージョンを使うようにしています。
バージョン3.0と4.0では設定ファイルの記述方法が違ってくるので気をつけてください。

このページでやること

Spring Securityを使ったひな形プロジェクトのソースを紹介していきます。

今回作成するSpring Securityの動き

adminユーザとuserユーザの2つを作成して、認証とそれぞれのユーザにページごとの権限(ロール)をつけていきます。

今回作ったファイル一覧

Spring Securityを動かすために追加・編集したファイルはこちらです。
spring-security-basically1

pom.xml

dependencyはこの3つを指定して下さい。

<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-core</artifactId>
	<version>4.0.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>4.0.1.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-config</artifactId>
	<version>4.0.1.RELEASE</version>
</dependency>

web.xml

security-context.xmlは、今回作成するSpring Securityの設定ファイルです。

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		/WEB-INF/spring/root-context.xml 
		/WEB-INF/spring/appServlet/security-context.xml
	</param-value>
</context-param>
・
・
<!-- spring security 設定  -->
<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>

security-context.xml

Spring Securityの設定ファイルです。
少し長いのですが、重要なファイルなので全てのせておきます。

<beans:beans xmlns="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.1.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-4.0.xsd">

    <http auto-config="true" >
        <!-- 認可の設定 --> 
        <intercept-url pattern="/top*" access="hasAnyRole('ROLE_ADMIN', 'ROLE_USER')" />
        <intercept-url pattern="/admin*" access="hasRole('ROLE_ADMIN')" />
        <intercept-url pattern="/user*" access="hasRole('ROLE_USER')" />
        
        <!-- 権限なし時の遷移先 -->
        <access-denied-handler error-page="/403" />
        
        <!-- 認証のログイン処理 -->
        <form-login 
            login-page="/" 
            default-target-url="/top" 
            authentication-failure-url="/error" 
            login-processing-url="/j_spring_security_check"/>
        
        <!-- 認証のログアウト処理 -->
        <logout
            logout-url="/logout"
            logout-success-url="/"
            invalidate-session="true"/>
        <!-- anonymousユーザのROLE -->
        <anonymous granted-authority="ROLE_ANONYMOUS" />
    </http>

    <!-- ユーザとROLEを定義 --> 
    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="admin" password="admin" authorities="ROLE_ADMIN" />
                <user name="user" password="user" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
</beans:beans>

TopController.java

今回のサンプルで動かすJavaコントローラクラスです。
ログイン画面やエラー画面のパスを設定しています。

@Controller
public class TopController {

	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String login(Locale locale, Model model) {
		return "login";
	}
	
	@RequestMapping(value = "/top", method = RequestMethod.GET)
	public String top(Locale locale, Model model) {
		return "top";
	}
	
	@RequestMapping(value = "/user", method = RequestMethod.GET)
	public String user(Locale locale, Model model) {
		return "user";
	}

	@RequestMapping(value = "/admin", method = RequestMethod.GET)
	public String admin(Locale locale, Model model) {
		return "admin";
	}

	@RequestMapping(value = "/error", method = RequestMethod.GET)
	public String error(Locale locale, Model model) {
		return "error";
	}

	@RequestMapping(value = "/403", method = RequestMethod.GET)
	public String permission(Locale locale, Model model) {
		return "403";
	}
}

403.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
	<title>403</title>
</head>
<body bgcolor="#FBA848">
<h1>
	403エラーです。権限がありません。
</h1>
</body>
</html>

admin.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
	<title>管理者専用画面</title>
</head>
<body bgcolor="#58BE89">
<h1>
	管理者専用画面です。
</h1>
</body>
</html>

error.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
	<title>error</title>
</head>
<body bgcolor="#F27398">
<h1>
	認証に失敗しました。
</h1>
<input type="button" onclick="javascript: history.back();" value="戻る">
</body>
</html>

login.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
	<title>ログイン</title>
</head>
<body bgcolor="#40AAEF">
<h1>ユーザは2種類あります。</h1>
<ul>
<li>ID:admin</li>
<li>PW:admin</li>
</ul>
<ul>
<li>ID:user</li>
<li>PW:user</li>
</ul>

<form name="f" action="<c:url value='j_spring_security_check'/>" method="post">
ログインID : <input type="text" name="username">
<br/>
ログインPW : <input type="password" name="password">
<br/>
<input type="submit" name="login" value="ログイン">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 
</form>

</body>
</html>

top.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
	<title>メニュー</title>
</head>
<body bgcolor="#40AAEF">
<h1>
	メニュー画面です。
</h1>
<a href="admin">「admin」ユーザのみ遷移出来ます。</a>
<br/><br/>
<a href="user">「user」ユーザのみ遷移出来ます。</a>
</body>
</html>

user.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
	<title>ユーザー専用画面</title>
</head>
<body bgcolor="#ECEEF1">
<h1>
	ユーザ専用画面です。
</h1>
</body>
</html>

springとjavaのバージョン

springframeworknのバージョンは、4.0.1を使っています。
javaは、version 8を使っています。

サンプルコード

EclipseでGitHubからCloneしたら「プロジェクトを右クリック > Configure > Convert to maven project」をしてビルド&実行してください。
GitHubでサンプルソースを公開しています。

さいごに

Spring Securityを使ってみて感じたことは、認可(ロール操作)の設定がすごく楽にできることにメリットを感じました。(正直なところ認証はそこまで便利さを感じませんでした。)

Spring Securityは一番最初の設定こそはめんどくさいものの、それさえ出来れば認証・認可の設定は楽ができるのでオススメのアーキテクトです。もう少しSpring Securityがメジャーになれば嬉しいのですが。

今回ソースコードをGitHub上に公開しています。もし動くものが見たいという方がいましたらメールかtwitterでご連絡頂ければ私が使っているテスト用サーバへアップしますのでお気軽にご連絡下さい。

それでは!