概要
Spring Securityでは、認証済みユーザー情報はまずSecurityContextHolderクラスに格納され、最終的にセッションで管理される。
今回は、SecurityContextHolderに格納された認証済みユーザー情報にアクセスする方法についてまとめた。
前提
以下の記事の続きとなる。
概要 ログアウト時に任意のログアウトハンドラを追加する方法についてまとめた。 前提 以下の記事の続きとなる。
実装
認証情報にアクセスする方法について紹介する。
アプリケーション全体
アプリケーション全体(Controller, Service, Dao層など)からSecurityContextHolderを呼び出してアクセスする。
WelcomeController.java
package com.example.prototype.web;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class WelcomeController {
private static final Logger logger = LoggerFactory.getLogger(WelcomeController.class);
@GetMapping(value = "/")
public String home(Model model) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails user = (UserDetails) auth.getPrincipal();
logger.debug("★★認証済みユーザー取得: {}", user);
model.addAttribute("message", "ログイン成功!");
return "home";
}
}
UserDetails user = (UserDetails) auth.getPrincipal();
SecurityContextHolderを直接呼ぶことで、認証済みユーザー情報を取得できる。
ハンドラ引数
コントローラーのハンドラ引数にて認証済みユーザーを取得する。
springMVCContext.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- アノテーションを有効にする -->
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
<!-- コンポーネントを表すアノテーションがついたクラスをスキャンする -->
<context:component-scan base-package="com.example.prototype.web" />
<!-- WEB-INF/viewsフォルダ配下のjspファイルをさがす -->
<mvc:view-resolvers>
<mvc:jsp prefix="/WEB-INF/views/" suffix=".jsp" />
</mvc:view-resolvers>
</beans>
WebアプリケーションコンテキストにAuthenticationPrincipalArgumentResolverを設定する。
WelcomeController.java
package com.example.prototype.web;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class WelcomeController {
private static final Logger logger = LoggerFactory.getLogger(WelcomeController.class);
@GetMapping(value = "/")
public String home(@AuthenticationPrincipal UserDetails user, Model model) {
logger.debug("★★認証済みユーザー取得: {}", user);
model.addAttribute("message", "ログイン成功!");
return "home";
}
}
@AuthenticationPrincipalを付与した認証済みユーザーの型を指定することで、
コントローラーのハンドラにて認証済みユーザーを取得できる。
JSP
JSP側から認証済み情報へアクセスする。
pom.xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.8.5</version>
</dependency>
JSPからSecurityContextHolderにアクセスする場合、「spring-security-taglibs」を導入する。
home.jsp
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>トップページ画面</title>
</head>
<body>
<sec:authentication var="user" property="principal" />
<form action="${pageContext.request.contextPath}/logout" method="post">
<input type="submit" value="ログアウト" />
</form>
<h3>トップページ</h1>
<p>${message}</p>
<p>認証済みユーザー: ${user.username }</p>
</body>
</html>
この宣言により、Spring Securityのタグライブラリが利用可能になる。
Authentication.getPrincipal()に相当する認証済みユーザー情報を、userという名前でpageスコープに格納する。
pageスコープに設定することで、UserDetailsのプロパティへ直接アクセスすることが可能となる。
まとめ
☑ Spring Securityでは、認証されたユーザー情報はセッションを通じてSecurityContextHolderに保存される
☑ 認証済みユーザーの情報を取得したい場合、SecurityContextHolder内のAuthenticationオブジェクトからprincipalを参照する
☑ JSPからアクセスするには、Spring Securityのタグライブラリ(spring-security-taglibs)を導入する必要がある
