SpringSecurityで公開インターフェースカスタム権限検証失敗問題を解決、ソースコード解析も
背景: カスタム権限認証、インターフェースの一部は適切なロール権限を持っている必要があり、インターフェースの一部はすべての訪問者に公開され、インターフェースの一部は誰からもアクセスできないようにします。しかし、SpringSecurityを使う過程で、フレームワークから
URL resource
を傍受することなく、直接
ユーザーログインの認証に成功した後、キャリー
Token
にアクセスしてください。
URL resources
を使用すると、春のセキュリティは
Token (in request header Authorization)
を使用して、異なるユーザーを区別することができます。
ユーザー権限のデータソースは
Map
を使用します。
URL resource
をキーとし
List of roles with access rights to the Key
は値。
使用したところ、インターフェイスに Key があっても Value が null や空の場合、spring security framework が自動的に解放してしまい、パーミッションに失敗する問題が発生することが判明しました。
これを解決する方法は2つあります。
<ブロッククオート第一の方法
デフォルトのrejectPublicInvocationsはfalseです。
パーミッションの制御が必要な方へURL resources
roleListが空で権限検証をスキップしないようにするフラグを追加する。
パブリックパーミッションをNULLに設定し、パーミッションの検証を行わない。
2つ目の方法
rejectPublicInvocationsをtrueに設定する。
この後、roleListは空か見つからない。
URL resource
の場合、アクセスが拒否されます。
コントロールパーミッションを必要とするもの
URL resources
対応するロールが空であっても、パーミッションは検証されます。
公開許可は、許可検証を行わずにすべてのロールおよび匿名ロールに設定される
package org.springframework.security.access.intercept;
/**
* Source code for an abstract class for intercepting security objects (access requests + user bodies)
*/
public abstract class AbstractSecurityInterceptor implements InitializingBean, ApplicationEventPublisherAware, MessageSourceAware {
// ... Other methods omitted
protected InterceptorStatusToken beforeInvocation(Object object) {
Assert.notNull(object, "Object was null");
final boolean debug = logger.isDebugEnabled();
if (!getSecureObjectClass().isAssignableFrom(object.getClass())) {
throw new IllegalArgumentException(
"Security invocation attempted for object "
+ object.getClass().getName()
+ " but AbstractSecurityInterceptor only configured to support secure objects of type: "
+ getSecureObjectClass());
}
// Gets the current
attributes = this.obtainSecurityMetadataSource().getAttributes(object);
// The framework determines here if the list of roles corresponding to the URL resource is empty
if (attributes == null || attributes.isEmpty()) {
// rejectPublicInvocations defaults to false
// can be configured to true, i.e. no release if the role list is empty
if (rejectPublicInvocations) {
throw new IllegalArgumentException(
"Secure object invocation "
+ object
+ " was denied as public invocations are not allowed via this interceptor. "
+ "This indicates a configuration error because the "
+ "rejectPublicInvocations property is set to 'true'");
}
if (debug) {
logger.debug("Public object - authentication not attempted");
}
publishEvent(new PublicInvocationEvent(object));
return null; // no further work post-invocation
}
if (debug) {
logger.debug("Secure object: " + object + "; Attributes: " + attributes);
}
// If the current user permission object is null
if (SecurityContextHolder.getContext().getAuthentication() == null) {
credentialsNotFound(messages.getMessage(
"AbstractSecurityInterceptor.authenticationNotFound",
"An Authentication object was not found in the SecurityContext"),
object, attributes);
}
Authentication authenticated = authenticateIfRequired();
// Attempt authorization, where accessDecisionManager is called for authentication
try {
this.accessDecisionManager.decide(authenticated, object, attributes);
}
catch (AccessDeniedException accessDeniedException) {
publishEvent(new AuthorizationFailureEvent(object, attributes, authenticated,
accessDeniedException));
throw accessDeniedException;
}
if (debug) {
logger.debug("Authorization successful");
}
if (publishAuthorizationSuccess) {
publishEvent(new AuthorizedEvent(object, attributes, authenticated));
}
// Attempt to run as a different user, where you can additionally configure or modify the user's permission object for special scenarios
Authentication runAs = this.runAsManager.buildRunAs(authenticated, object,
runAs = this.runAsManager.buildRunAs(authenticated, object, attributes);
if (runAs == null) {
if (debug) {
logger.debug("RunAsManager did not change Authentication object");
}
// no further work post-invocation
return new InterceptorStatusToken(SecurityContextHolder.getContext(), false,
attributes, object);
}
else {
if (debug) {
logger.debug("Switching to RunAs Authentication: " + runAs);
}
SecurityContext origCtx = SecurityContextHolder.getContext();
SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext());
SecurityContextHolder.getContext().setAuthentication(runAs);
// need to revert to token.Authenticated post-invocation
return new InterceptorStatusToken(origCtx, true, attributes, object);
}
}
// ... Other methods are omitted
}
関連
-
XMLファイル操作時のjava.util.NoSuchElementExceptionを解決する方法。
-
SLF4J: クラス・パスに複数のSLF4Jバインディングが含まれています。
-
JAVA_HOME環境変数が正しく定義されていない問題を解決する
-
が 'X-Frame-Options' を 'sameorigin' に設定したため、フレーム内に存在する。
-
BindException: アドレスはすでに使用中です:バインドエラー解決
-
List list = new ArrayList(); Error: ArrayList は型に解決できません。
-
git pull appears現在のブランチに対するトラッキング情報がありません。
-
テストが空であるかどうかを判断するためのオプションの処理
-
CAS 5.1.8でhttpをサポートし、認証されていない認可サービスエラーのプロンプトが表示される問題を解決した。
-
WeChat小プログラム Bluetooth通信 Bluetoothモジュールデモ
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Javaでよくある構文エラー
-
メモ帳でJavaプログラムをコンパイルして実行すると、Could not find or load main class ...というエラーが表示される。解決方法
-
ApplicationContextの起動エラーです。条件レポートを表示するには、アプリケーションを'de'で再実行します。
-
Javaジェネリックを1つの記事で
-
java マイクロソフト払い戻し予期せぬサーバーからのファイルの終了
-
Junitのユニットテストエラー
-
Web Project JavaでPropertiesファイルを読み込むと、「指定されたファイルがシステムで見つかりません」というソリューションが表示されます。
-
Java:未解決コンパイル問題の解決方法
-
IDEAError:javaの依存性エラー。Annotation processing is not supported for module cycles...(アノテーション処理はモジュールサイクルではサポートされていません。
-
java1.8ソースコード ArrayListソースコード解釈