【Spring MVC + Spring Security】認証済み情報にアクセスする方法

概要

Spring Securityでは、認証済みユーザー情報はまずSecurityContextHolderクラスに格納され、最終的にセッションで管理される。
今回は、SecurityContextHolderに格納された認証済みユーザー情報にアクセスする方法についてまとめた。

 

前提

以下の記事の続きとなる。

あわせて読みたい

概要 ログアウト時に任意のログアウトハンドラを追加する方法についてまとめた。   前提 以下の記事の続きとなる。

【Spring MVC + Spring Security】任意のログアウトハンドラを追加する方法

 

実装

認証情報にアクセスする方法について紹介する。

 

アプリケーション全体

アプリケーション全体(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";
    }
}

 

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
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>

 

<bean class=”org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver” />

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";
    }
}

 

public String home(@AuthenticationPrincipal UserDetails user, Model model) {

@AuthenticationPrincipalを付与した認証済みユーザーの型を指定することで、
コントローラーのハンドラにて認証済みユーザーを取得できる。

 

JSP

JSP側から認証済み情報へアクセスする。

 

pom.xml


<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-taglibs</artifactId>
	<version>5.8.5</version>
</dependency>

 

<artifactId>spring-security-taglibs</artifactId>

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>

 

<%@ taglib prefix=”sec” uri=”http://www.springframework.org/security/tags” %>

この宣言により、Spring Securityのタグライブラリが利用可能になる。

 

<sec:authentication var=”user” property=”principal” />

Authentication.getPrincipal()に相当する認証済みユーザー情報を、userという名前でpageスコープに格納する。

 

<p>認証済みユーザー: ${user.username }</p>

pageスコープに設定することで、UserDetailsのプロパティへ直接アクセスすることが可能となる。

 

 

まとめ

 

☑ Spring Securityでは、認証されたユーザー情報はセッションを通じてSecurityContextHolderに保存される

☑ 認証済みユーザーの情報を取得したい場合、SecurityContextHolder内のAuthenticationオブジェクトからprincipalを参照する

☑ JSPからアクセスするには、Spring Securityのタグライブラリ(spring-security-taglibs)を導入する必要がある

 

スポンサーリンク