web-dev-qa-db-ja.com

JSFでアクセスと権限をどのように制御しますか?

ユーザーがシステムにログインした後、アクセスを制御したいと思います。

例えば:

administrator : can add, delete and give rights to employee
employee : fill forms only
...

そのため、ユーザーがどの権限を持っているかを知り、データベースをチェックインした後、このユーザーが表示および実行できることを制限したいと思います。それを行う簡単な方法はありますか?

[〜#〜]編集[〜#〜]

@WebFilter("/integra/user/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest req = (HttpServletRequest) request;
        Authorization authorization = (Authorization) req.getSession().getAttribute("authorization");

        if (authorization != null && authorization.isLoggedIn()) {
            // User is logged in, so just continue request.
            chain.doFilter(request, response);
        } else {
            // User is not logged in, so redirect to index.
            HttpServletResponse res = (HttpServletResponse) response;
            res.sendRedirect(req.getContextPath() + "/integra/login.xhtml");
        }
    }

    // You need to override init() and destroy() as well, but they can be kept empty.


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {
    }
}
23
Valter Silva

まあ、これはかなり広い主題です。あなたが自作の認証から始めるので、私は自作の承認の答えをターゲットにします。


モデルが賢明に設計されている場合、Java/JSFでのロールチェック自体は比較的単純です。 1人のユーザーが複数の役割を持つことができると想定すると(実際のアプリケーションではよくあることです)、最終的には次のようなものになることを望みます。

public class User {

    private List<Role> roles;

    // ...

    public boolean hasRole(Role role) {
        return roles.contains(role);
    }

}
public enum Role {

    EMPLOYEE, MANAGER, ADMIN;

}

jSFビューで次のように確認できます。

<h:selectManyCheckbox value="#{user.roles}" disabled="#{not user.hasRole('ADMIN')}">
    <f:selectItems value="#{Role}" />
</h:selectManyCheckbox>
<h:commandButton value="Delete" rendered="#{user.hasRole('ADMIN')}" />

そしてあなたのフィルターで:

String path = req.getRequestURI().substring(req.getContextPath().length());

if (path.startsWith("/integra/user/admin/") && !user.hasRole(Role.ADMIN)) {
    res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}

最も困難な部分は、このJavaモデルを適切なDBモデルに変換することです。具体的なビジネス要件に応じていくつかの異なる方法があり、それぞれに独自の(欠点)があります。あるいは、すでにJavaモデル(したがって、ボトムアップ設計が必要))のベースとなるDBモデル?

とにかく、JPA 2.0を使用していて(質問の履歴で少なくともこれが確認されている)、トップダウンで設計できると仮定すると、最も簡単な方法の1つは、rolesプロパティを @ElementCollectionとしてマップすることです。user_rolesテーブルに対して。 Role列挙型を使用しているため、2番目のroleテーブルは必要ありません。繰り返しますが、それは具体的な機能要件とビジネス要件によって異なります。

一般的なSQL用語では、user_rolesテーブルは次のようになります。

CREATE TABLE user_roles (
    user_id BIGINT REFERENCES user(id),
    role VARCHAR(16) NOT NULL,
    PRIMARY KEY(user_id, role)
)

その後、次のようにマッピングされます。

@ElementCollection(targetClass=Role.class, fetch=FetchType.EAGER)
@Enumerated(EnumType.STRING)
@CollectionTable(name="user_roles", joinColumns={@JoinColumn(name="user_id")})
@Column(name="role")
private List<Role> roles;

基本的に、Userエンティティで変更する必要があるのはこれだけです。


自作の認証(ログイン/ログアウト)と承認(ロールチェック)の横には、Java EEが提供する コンテナ管理の認証 を使用して、 j_security_checkまたはHttpServletRequest#login()<security-constraint>web.xmlによってHTTPリクエストをフィルタリングしますログインしたユーザーを#{request.remoteUser} で確認し、 #{request.isUserInRole('ADMIN')} でその役割を確認します。

次に、 PicketLinkSpring SecurityApache Shiro などのサードパーティフレームワークがいくつかあります。しかし、これは問題外です:)

35
BalusC