実際に認証と認可をWEBにつけるには? | Java Springの逆引きメモ

Java Springの逆引きメモ

JavaのSpring frameworkのメモを書いていきます!
初心者の勉強ノートなので間違いがあるかもしれませんが、何かヒントになることがあれば幸いです。

ここでは、SpringSecurityの簡単な使用方法をみてみます。

設定ファイルにログイン情報(ユーザと権限)を設定するやり方です。


まず、こちらの記事を先に読んで全体を把握しておいた方がいいかと思います。

 ・SpringSecurityの機能について



【web.xmlの設定】

以下の記述を記述します。

SpringSecurityはフィルターで実現している機能ですので、フィルターの設定になります。

フィルターの最初の方で動作するように、最初の方に記述します。

キャラクタのエンコードのフィルター を設定している場合は、その後ろに記述します。


<!-- WEBの設定です --> 
<display-name>sample</display-name>
<welcome-file-list>
   <welcome-file>/login.jsp</welcome-file>
</welcome-file-list> 

<!-- Springの設定です --> 
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/applicationContext.xml /WEB-INF/applicationSecurity.xml </param-value>
</context-param>
 
<!-- SpringSecurityのフィルター設定です -->
<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>



【SpringSecurityの設定(applicationSecurity.xml)】

SpringSecurityは、Springの設定ファイルで設定します。

たいていの場合は、SpringSecurityの設定だけでファイルを分けた方がいいと思います。

ここでもファイルを分けた設定例を記述します。

<?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:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:sec="http://www.springframework.org/schema/security" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd "> <!-- 認証と認可の設定です --> <sec:http auto-config="true" access-denied-page="/403.jsp" > <!-- 認可のURL設定 --> <sec:intercept-url pattern="/secure/sys*" access="ROLE_ADMIN"/> <sec:intercept-url pattern="/secure/usr*" access="ROLE_ADMIN,ROLE_USER"/> <sec:intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_FULLY"/> <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/> <!-- 認証の設定 --> <sec:form-login login-page="/login.jsp" default-target-url="/top.jsp" authentication-failure-url="/error.jsp"/> <sec:logout logout-url="/logout" logout-success-url="/login.jsp" invalidate-session="true"/> <sec:anonymous granted-authority="ROLE_ANONYMOUS"/> </sec:http> <!-- ログインユーザの情報の設定。SQL文を指定してDBから取得する方法もあります。 --> <sec:authentication-provider> <sec:user-service> <sec:user password="admin" name="admin" authorities="ROLE_ADMIN"/> <sec:user password="user" name="user" authorities="ROLE_USER"/> </sec:user-service> </sec:authentication-provider> </beans>




【画面の作成例】

必要な画面は、以下のものです。ここでは単純なサンプルを書きます。


<ログイン画面(login.jsp)>

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>ログイン</title>
</head>
<body>


<form name="f" action="<c:url value='j_spring_security_check'/>" method="post">
<table class="login">
<tr>
<th>ログインID</th>
<td><input type="text" name="j_username"></td>
</tr>
<tr>
<th>ログインPW</th>
<td><input type="text" name="j_password"></td>
</tr>
</table>

<input type="submit" name="login" value="ログイン">
</form>


</body>
</html>


<認証エラー(error.jsp)>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<title>Insert title here</title>
</head>
<body>
認証に失敗しました。<br>
<input type="button" onclick="javascript: history.back();" value="戻る">
</body>
</html>



<権限エラー(403.jsp)>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<title>Insert title here</title>
</head>
<body>
閲覧権限がありません。<br>
<input type="button" onclick="javascript: history.back();" value="戻る">
</body>
</html>






【ファイル構成】

上記のそれぞれのファイルの置き場所を記述します。

WebContent

  ├403.jsp

  ├error.jsp

  ├login.jsp

  ├WEB-INF

     ├applicationContext.xml

     ├applicationSecurity.xml

     ├web.xml




【設定の説明】

上記の設定をすればなんとか動くかと思います。


web.xml

設定は、フィルターに設定します。

SpringSecurityはSpringの設定ファイルで設定するため、Springで読み込むファイルとしてcontext-paramに設定をします。

url-patternには、SpringSecurityの機能を適用したいパスを設定します。

ここでは、/*になっているのですべてのパスに対して適用されます。



applicationSecurity.xml

独自の拡張が必要ない場合、2つのタグを設定するだけです。


<httpタグの主な属性>

属性名 概要
auto-config

コンフィグを自分の設定で行うかどうか。

独自の拡張をしない場合はtrueにします。

独自の拡張をする場合はfalseを設定して、entry-point-ref属性を設定したり、form-loginタグを削除するなどいくつか設定を変えないといけません。

設定値:true(デフォルト値)/false

access-denied-page

認可が失敗したとき(表示権限がないとき)に表示する画面を指定する。

設定例:/403.jsp

entry-point-ref

独自の機能を追加する場合に指定します。

SpringSecurityでは機能を細かく分解していて、それらをチェーンして順番に適用していくという方式を取っています。ですので、独自の機能をつけるときもそのうちの一つとして実装します。(これをフィルターと呼んでいます。tomcatのフィルターと同じものです。)

このとき、どの位置に自作の機能を入れるかを決めるのがこの属性です。

設定例:authenticationProcessingFilterEntryPoint

(独自機能自体はbeanで設定し、そのbean名をこの属性で指定します)

path-type

intercept-urlタグで認可のパスを指定するときに、どのような形式で指定するか。

ant・・・ant形式です(デフォルト値。*,**,?など使用できます)

regex・・・正規表現形式です。




<httpタグ内で使用できる主なタグ>

タグ名 概要
intercept-url

認可のパス名と閲覧を許す権限を指定します。

上記のpath-type属性で指定の仕方は変更できます。

属性:

pattern・・・パス名を指定します。(上記のpath-type属性参照)

access・・・閲覧を許すロール名を指定します。

      必ず先頭に"ROLE_"が付いている必要があります

      付いていない場合、設定エラーになります。

      また、予約語※も存在し、それを使用すると設定が楽に

      なります。

method・・・アクセス時のメソッドを指定します。

      設定値:GET, DELETE, HEAD, OPTIONS, POST, PUT

      何も指定しなければ「なんでも良い」、となります。

requires-channel・・・指定したアクセスでないとエラーにします。

      設定値:http, https, any(デフォルト値)

form-login

ログインのための情報を設定します。

SpringSecurityではURLを指定する場合、必ず/を頭につけることを忘れないでください。

属性:

login-page・・・ログイン画面を指定します。

default-target-url・・・認証成功後に表示する画面。

authentication-failure-url・・・認証失敗時に表示する画面。

always-use-default-target・・・ログイン後の画面を強制的に 

  default-target-urlで指定した画面に遷移するかを設定します。

  通常は、最初にアクセスしたURLに遷移します。

  最初にアクセスしたのがログイン画面のときに

  default-target-urlで指定した画面に遷移します。

  設定値: true/false(デフォルト値)

logout

ログアウトのための情報を設定します。

属性:

logout-url・・・ログアウト処理をするURLを指定します。

logout-success-url・・・ログアウト成功後に表示する画面。

invalidate-session・・・ログアウト時にセッションを無効にするか?

         設定値: true(デフォルト値)/false

anonymous

anonymousユーザの設定をします。

属性:

granted-authority・・・ロール名を指定します。ここで設定したロール名がanonymousユーザになります。

デフォルト値は"ROLE_ANONYMOUS"。

concurrent-session-control

1ユーザが持てるセッション数を制限します。

属性:

max-sessions・・・1ユーザが持てるセッション数

exception-if-maximum-exceeded・・・trueにするとセッション数を制限するようになります。


※予約語 (主な予約語は以下のとおりです)

IS_AUTHENTICATED_FULLY ・・・認証されたユーザすべて

IS_AUTHENTICATED_ANONYMOUSLY・・・認証されたユーザと認証されていないユーザすべて




<authentication-providerタグの主な属性>

属性名 概要
user-service-ref

ユーザサービスを指定します。

通常は必要ありません。




<authentication-providerタグ内で使用できるの主なタグ>

タグ名 概要
user-service

このタグ内でユーザとロールを設定できます。

つまり、このタグでログインユーザ情報を設定を記述できます。

(DBなどを使用することなく)

jdbc-user-service

DBからユーザとロールの設定を取得します。

属性:

authorities-by-username-query・・・認証を許可するユーザを取得するSQL文を記述します。

group-authorities-by-username-query・・・認可の設定を取得するSQL文を記述します。

password-encoder

パスワードを暗号化するかどうかを設定します。

具体的には、パスワードをハッシュなどで変換した後の値に対して認証をするのかを設定します。

この設定をする場合、パスワードの設定値はハッシュ値を設定することになります。

-

-




【JSPのtaglibについて】

SpringSecurityでは、独自のtaglibを用意しています。

これを使用することで、JSP上で閲覧を許しているロールに対してだけリンクを表示するなど、様々なことができます。

また、別の記事で書こうと思います。



【注意点】

・SpringSecurityでは、ログイン成功後の画面の表示にはリダイレクトを使用しています。

 ログイン画面の閲覧権限を許可していなかったり、設定を誤ると、無限リダイレクトループすることがあります。

 その場合は、単なる設定誤りなので、慎重に分析して設定ファイルを修正しましょう。


・設定のURLは必ず先頭にスラッシュ"/"をつけます。入れないとうまく動きません。


・ロール名には、必ず先頭に"ROLE_"をつけます。つけないと設定エラーになって起動がうまく行きません。





ここでは、独自の拡張をしない場合で、DBも使用しない簡単な例を見ました。

DBを使用する場合、独自の拡張をする場合はまた別の記事で見てみようと思います。


また、SpringSecurityの概要は以下の参考を読んでみてください。



参考:

・SpringSecurityの機能について

・DBのユーザ情報を使用して認証するには? (実践編:DBを使用する方法)

taglibの利用例:

・ログイン後の画面にログインしたユーザを表示するには? (ログイン情報の表示方法)

・ロール(権限)によって画面のリンクの表示/非表示を制御するには?

・閲覧許可がある画面のリンクのみ表示するには?

外部リンク:

SpringSecurityの本家HP(設定で使用できるタグ)