スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Spring MVC ヘッダ画面にログインユーザーを表示する

前回・前々回の記事で、Spring Securityを使ってログイン画面を作成し、Tilesでヘッダ/フッタ画面をレイアウトした。
せっかくなので、ヘッダ画面によくあるログインユーザー名を表示させてみた。
なお、認証はDBを使った「Spring MVC Spring Securityを使ってみる(その2)」の記事をベースとしている。

■前回までの関連記事
Spring MVC Tilesを使って画面をレイアウトする
Spring MVC Spring Securityを使ってみる(その2)

◎動作検証にあたっての各バージョンは以下の通り
  • SpringFramework 3.2.8.RELEASE
  • Java 1.7
  • Tomcat 7.0

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

<sec:http auto-config="true">
<sec:intercept-url pattern="/book/*" access="ROLE_ADMIN"/>
<sec:form-login login-page="/login.jsp" default-target-url="/book"
authentication-failure-url="/login.jsp?error=true"/>
<sec:logout logout-url="/logout"
logout-success-url="/login.jsp" />
<sec:access-denied-handler error-page="/error.jsp" />
</sec:http>

<sec:authentication-manager>
<sec:authentication-provider>
<sec:jdbc-user-service data-source-ref="dataSource"/>
</sec:authentication-provider>
</sec:authentication-manager>

<bean id="webExpressionHandler"
class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />

</beans>

変更点は2点。
①「sec:intercept-url」タグの「pattern」属性の値を「/book/**」 → 「/book/*」に変更。
  理由:ログインのリンクより認証を行うため、「/book」で認証処理が実行されないようにした。
②最後に定義した「bean id="webExpressionHandler"」の追加。
  理由:このBean定義をしないと、URL「http://localhost:8080/SpringWebSample/book」で、「java.io.IOException: No visible WebSecurityExpressionHandler instance could be found in the application context. There must be at least one in order to support expressions in JSP 'authorize' tags.」の例外が発生する。

2.header.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec"%>
<link href="<c:url value="/css/bootstrap.min.css" />" rel="stylesheet">
<link href="<c:url value="/css/bootstrap-theme.min.css" />" rel="stylesheet">
<script src="<c:url value="/js/bootstrap.min.js" />"></script>

<title>header</title>
</head>
<body>
<div class="container-fluid">
<div class="col-sm-3 text-left">
<font size="5">Book</font>
</div>
<div class="col-sm-6">
</div>
<div class="col-sm-3 text-right">

<!-- パターン1 -->
<sec:authorize access="isAuthenticated()" var="isAuthenticated">
Welcome! <sec:authentication property="principal.username"/>
<a href="${pageContext.request.contextPath}/logout"><u>Logout</u></a>
</sec:authorize>
<c:if test="${!isAuthenticated}">
<a href="${pageContext.request.contextPath}/login.jsp"><u>Login</u></a>
</c:if>

<!-- パターン2 -->
<!--
<sec:authorize access="isAuthenticated()">
Welcome! <sec:authentication property="principal.username"/>
<a href="${pageContext.request.contextPath}/logout"><u>Logout</u></a>
</sec:authorize>
<sec:authorize access="!isAuthenticated()">
<a href="${pageContext.request.contextPath}/login.jsp"><u>Login</u></a>
</sec:authorize>
</div>
  -->

</div>
</body>
</html>

2パターン検証してみた。
・パターン1・・・「sec:authorize」タグを使い、「isAuthenticated()」で認証済の場合、「principal.username」でログインユーザー名を表示させる。また、「ログアウト」もあわせて表示させている。ポイントは認証済みか否かを「var」属性を使って、「isAuthenticated」変数に保持させ、「c:if test="${!isAuthenticated}"」にて「認証されていない場合」を判定している。「isAuthenticated」の前に「!」を付与しているが、これが否定を表している。
・パターン2・・・「var」属性を使わないパターン。「!isAuthenticated」が記載できるので、「!isAuthenticated()」も記載できるのではと検証してみた結果、ちゃんと動作した。
どちらがよいのか考えた場合、メソッドを毎回動作させるパターン2より、結果を変数に保持するパターン1の方が適切かと思われる。(また、そもそもパターン2「!isAuthenticated()」の記載方法を見たことがない。。できることが分かって良かった。)

3.動作確認
①ログイン前



②ログイン後
Login後


画面は「ROLE_GUEST」所属のtestuserでログインしているが、「ROLE_ADMIN」所属のtestadminでも勿論ログイン可能だ。
ここでsecurity.xmlの「sec:intercept-url」タグが関係してくる。
<sec:intercept-url pattern="/book/*" access="ROLE_ADMIN"/>
と「pattern」属性値を変更したことを先に説明したが、URL「http://localhost:8080/SpringWebSample/book」では、「ROLE_ADMIN」に所属していなくてもログインできる。しかし、画面の「Create」ボタンをクリックすると「http://localhost:8080/SpringWebSample/book/create」とマッピングされ、認証されていなければログイン画面が表示される。「Create」処理は、「ROLE_ADMIN」所属ユーザーしか認めていないため、「ROLE_GUEST」所属のtestuserはここでは認証エラーとなる。(「access」属性値の「ROLE_ADMIN」所属ユーザーでなければ「Create」処理できない。)

Webサイトでよく見るヘッダー画面にログイン/ログアウトを実装できた。
今回は、実践的な内容だったと思う。

■過去のSpring関連記事
Spring関連記事 Index

スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

bookmount8

Author:bookmount8
システムエンジニア。サーバーサイドでjavaを扱うことが多い。最近は、ミドルやフロント周りも関心あり。

最新記事
カテゴリ
検索フォーム
最新コメント
月別アーカイブ
これまでの訪問者数
ブロとも申請フォーム

この人とブロともになる

RSSリンクの表示
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。