サードパーティの認証サービスによって処理される Web アプリケーションへの認証を備えた既存の Spring Boot アプリケーションがあります。SiteMinder と同様に、サード パーティ サービスは、HTTP 要求にヘッダー (たとえば、USER_HEADER) を挿入します。@AuthenticatedPrincipal
この HTTP ヘッダーを抽出し、結果の Auth オブジェクトを Spring Securityアノテーションを介して MVC レイヤーのコントローラーで使用できるように、既存のアプリを構成することを任されています。
前述のとおり、プロジェクトは Java 8 を使用したバージョン 1.1.9.RELEASE の Spring Boot アプリケーションです。
(以下に示すコードは、機能をミラーリングするテスト プロジェクトからのものです)
このアプリケーションは Java Config のみであることに注意してください。XML は許可されていません (リーダーからの命令)
Spring Security リファレンスやその他のさまざまな記事を掘り下げることで、a を使用しRequestHeaderAuthenticationFilter
てそれをフィルター チェーンに挿入し、リクエスト ヘッダーからユーザー名を取得する必要があることがわかりました。
フィルター:
public class HeaderAuthenticationFilter extends RequestHeaderAuthenticationFilter {
private static final Logger logger = LoggerFactory.getLogger(HeaderAuthenticationFilter.class);
private final String HEADER = "USER_HEADER";
public HeaderAuthenticationFilter() {
super();
this.setPrincipalRequestHeader(HEADER);
// This setting returns an HTTP 404 with no error message instead of an HTTP 500 with the "missing header" exception message
this.setExceptionIfHeaderMissing(false);
}
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
logger.debug("Authorizing URI: " + request.getRequestURI());
try {
return super.getPreAuthenticatedPrincipal(request);
} catch(PreAuthenticatedCredentialsNotFoundException e) {
logger.error("Could not find request header " + HEADER + " in request", e);
return null;
}
}
}
ご覧のとおり、非常に基本的なフィルターです。
私が今持っているコードでは、ユーザーは HTTP 要求から抽出され、PreAuthenticatedAuthenticationToken がカスタム AuthenticationManager によって作成される PreAuthentication プロセスを通過し、User ビジネス オブジェクトがプリンシパルとしてトークンに挿入され、トークンは最終的にSecurityContextHolder.getContext().setAuthentication(principal); で SecurityContext に割り当てられます。
ただし、 Controller メソッドに で注釈を付けると@AuthenticationPrincipal User user
、返される User オブジェクトは null 化された User オブジェクトです。メソッド パラメータを に変更しAuthentication user
て明示的に呼び出すuser.getPrincipal()
と、ユーザー オブジェクトが正常に取得されます。@AuthenticationPrincipal がこのように失敗する理由はありますか?
ありがとうございます。詳細が必要な場合はお知らせください。