1. 概要

このチュートリアルでは、SpringSecurityでユーザーの詳細を取得する方法を示します。

現在認証されているユーザーは、Springのさまざまなメカニズムを通じて利用できます。 最初に、最も一般的なソリューションであるプログラムによるアクセスについて説明します。

2. Beanでユーザーを取得する

現在認証されているプリンシパルを取得する最も簡単な方法は、SecurityContextHolderへの静的呼び出しを使用することです。

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();

このスニペットの改善点は、アクセスを試みる前に、認証されたユーザーがいるかどうかを最初に確認することです。

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
    String currentUserName = authentication.getName();
    return currentUserName;
}

もちろん、このような静的な呼び出しを行うことには欠点があり、コードのテスト容易性の低下は、より明白なものの1つです。 代わりに、この非常に一般的な要件の代替ソリューションを検討します。

3. コントローラでユーザーを取得する

@Controller注釈付きBeanには追加のオプションがあります。

プリンシパルをメソッド引数として直接定義でき、フレームワークによって正しく解決されます。

@Controller
public class SecurityController {

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserName(Principal principal) {
        return principal.getName();
    }
}

または、認証トークンを使用することもできます。

@Controller
public class SecurityController {

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserName(Authentication authentication) {
        return authentication.getName();
    }
}

Authentication クラスのAPIは非常にオープンであるため、フレームワークは可能な限り柔軟に保たれます。 このため、 Spring Securityプリンシパルはオブジェクトとしてのみ取得でき、正しいUserDetailsインスタンスにキャストする必要があります

UserDetails userDetails = (UserDetails) authentication.getPrincipal();
System.out.println("User has authorities: " + userDetails.getAuthorities());

そして最後に、HTTPリクエストから直接を示します。

@Controller
public class GetUserWithHTTPServletRequestController {

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserNameSimple(HttpServletRequest request) {
        Principal principal = request.getUserPrincipal();
        return principal.getName();
    }
}

4. カスタムインターフェイスを介してユーザーを取得する

Springの依存性注入を完全に活用し、 @Controller Beans だけでなく、あらゆる場所で認証を取得できるようにするには、静的アクセスを単純なファサードの背後に隠す必要があります。

public interface IAuthenticationFacade {
    Authentication getAuthentication();
}
@Component
public class AuthenticationFacade implements IAuthenticationFacade {

    @Override
    public Authentication getAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }
}

ファサードは、静的状態を非表示にし、コードを分離して完全にテスト可能に保ちながら、Authenticationオブジェクトを公開します。

@Controller
public class GetUserWithCustomInterfaceController {
    @Autowired
    private IAuthenticationFacade authenticationFacade;

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserNameSimple() {
        Authentication authentication = authenticationFacade.getAuthentication();
        return authentication.getName();
    }
}

5. JSPでユーザーを取得する

現在認証されているプリンシパルは、Spring Security Taglibサポートを利用して、JSPページからもアクセスできます。

まず、ページでタグを定義する必要があります。

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

次に、プリンシパルを参照できます。

<security:authorize access="isAuthenticated()">
    authenticated as <security:authentication property="principal.username" /> 
</security:authorize>

6. Thymeleafでユーザーを取得する

Thymeleaf は、最新のサーバー側Webテンプレートエンジンであり、SpringMVCフレームワークとの優れた統合を備えています。

Thymeleafエンジンを使用してページで現在認証されているプリンシパルにアクセスする方法を見てみましょう。

まず、thymeleaf-spring5thymeleaf-extras-springsecurity5の依存関係を追加して、ThymeleafをSpringSecurityと統合する必要があります。

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>

これで、 sec:authorize属性を使用してHTMLページのプリンシパルを参照できます。

<html xmlns:th="https://www.thymeleaf.org" 
  xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<body>
    <div sec:authorize="isAuthenticated()">
      Authenticated as <span sec:authentication="name"></span></div>
</body>
</html>

7. 結論

この記事では、Springアプリケーションでユーザー情報を取得する方法を示しました。まず、一般的な静的アクセスメカニズムから始めて、プリンシパルを挿入するためのより良い方法をいくつか紹介しました。

これらの例の実装は、GitHubプロジェクトにあります。 これはEclipseベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。 プロジェクトをローカルで実行する場合、ここからホームページのHTMLにアクセスできます。

http://localhost:8080/spring-security-rest-custom/foos/1