JSF Web アプリケーションの一部の機能のセキュリティをチェックするカスタム アノテーションを作成したいと考えていました。セキュリティのために、私は JaaS で Tomcat セキュリティを使用しているため、自由に使えるアプリケーション管理セキュリティはありません。
実際にやりたいことは、Spring Security (@Secured("role")) のようなバッキング Bean でメソッドのアノテーションを作成することです。私のセキュリティシステムは、すべての機能がロールであり、動的に「ユーザーロール」を作成できるように実装されています。これらはDBに保存され、誰かがログインすると、その「ユーザーロール」のすべての(機能)ロールがTomcatセキュリティに設定されます役割として。
これで、ユーザーが関数にアクセスできるかどうかを確認する次のコードができました。
public static void checkSecurity(final String function) {
final FacesContext facesContext = FacesContext.getCurrentInstance();
try {
if (facesContext.getExternalContext().getRemoteUser() == null) {
facesContext.getExternalContext().redirect("login.xhtml");
return;
}
if (!facesContext.getExternalContext().isUserInRole(function)) {
facesContext.getExternalContext().redirect("restricted.xhtml");
return;
}
} catch (final Exception ex /* Mandatory "IOException e" will be caught + all other exceptions. */) {
facesContext.getExternalContext().setResponseStatus(403); // HTTP Status 403: Forbidden. Can also throw 401.
facesContext.responseComplete();
}
}
これを SecurityUtil.checkSecurity("name_of_function"); と呼ぶ必要があります。あらゆる方法で。しかし、この @CustomSecurity("function_name_role") のような注釈が必要です。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomSecurity {
// Single Element called value.
String value();
}
メソッドにこの注釈がある場合、checkSecurity 関数を自動的に実行する必要があります。したがって、ある時点でこの注釈をスキャンするか、ある種のアクションリスナーを作成する必要があります。JSF にはこれに関するオプションがいくつかあるはずですが、これに関して私が見つけたすべてのフォーラムは実際には役に立ちません。
誰かがいくつかのアイデアを持っていますか?
編集:私はこのブログ を試しましたが、コンポーネントのアクションでのみ機能します(役割がない場合、コンポーネントはレンダリングされません)。人々が JSF 構造にハッキングしようとするとき、これはどれほど安全なのでしょうか。そして、私はむしろすべての方法でそれを実行しています。
public class SecurityActionListener extends ActionListenerImpl implements ActionListener {
private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger();
@SuppressWarnings("unused")
@Override
public void processAction(final ActionEvent event) {
final FacesContext context = FacesContext.getCurrentInstance();
final Application application = context.getApplication();
final ConfigurableNavigationHandler navHandler = (ConfigurableNavigationHandler) application.getNavigationHandler();
// Action stuff
final UIComponent source = event.getComponent();
final ActionSource actionSource = (ActionSource) source;
MethodBinding binding;
binding = actionSource.getAction();
final String expr = binding.getExpressionString();
if (!expr.startsWith("#")) {
super.processAction(event);
return;
}
final int idx = expr.indexOf('.');
final String target = expr.substring(0, idx).substring(2);
final String t = expr.substring(idx + 1);
final String method = t.substring(0, (t.length() - 1));
final MethodExpression expression = new MethodExpressionMethodBindingAdapter(binding);
final ELContext elContext = context.getELContext();
final ExpressionFactory factory = context.getApplication().getExpressionFactory();
final ValueExpression ve = factory.createValueExpression(elContext, "#{" + target + '}', Object.class);
final Object result = ve.getValue(elContext);
// Check if the target method is a secured method
// and check security accordingly
final Method[] methods = result.getClass().getMethods();
for (final Method meth : methods) {
if (meth.getName().equals(method)) {
if (meth.isAnnotationPresent(CustomSecurity.class)) {
final CustomSecurity securityAnnotation = meth.getAnnotation(CustomSecurity.class);
System.out.println("Function to check security on: " + securityAnnotation.value()); // TODO TO LOG
SecurityUtil.checkSecurity(securityAnnotation.value());
} else {
super.processAction(event);
}
break;
}
}
}
}
そして、これはfaces-config.xmlにあります:
<action-listener>
com.nielsr.randompackagebecauseofnda.SecurityActionListener
</action-listener>
このブログも答えになる可能性がありますが、Tomcat lib フォルダーにスタンドアロン JAR としてデプロイされた別のプロジェクトにセキュリティがあるため、JaaS Tomcat セキュリティでどのように機能するかはわかりません。
しかし、実際には、Beans を確保する必要があることを知りません。セキュリティ制約として、Web.xml の 1 ページにあるすべての機能 (別名、上記のロール) を構成したためです。また、そのコンポーネントに対して権限または「function_role」が必要な場合にのみ、ページにコンポーネントをレンダリングします。それで、これは十分に保護されていますか?または、誰かがページ上の機能に対する権利を持っている場合、そのコンポーネントを自分でレンダリングして、私のサイトをハッキングすることはできますか?
私はこれを知るためにJSFに精通していません.コントローラーとビューの間の追加のJSF抽象化レイヤーで何が起こっているのでしょうか? (私はどちらかというと Spring MVC 開発者ですが、要件のために JSF を使用する必要がありますが、知識を広げるのは良いことです。)