ユーザーがシステムにログインした後、アクセスを制御したいと思います。
例えば:
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() {
}
}
まあ、これはかなり広い主題です。あなたが自作の認証から始めるので、私は自作の承認の答えをターゲットにします。
モデルが賢明に設計されている場合、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')}
でその役割を確認します。
次に、 PicketLink 、 Spring Security 、 Apache Shiro などのサードパーティフレームワークがいくつかあります。しかし、これは問題外です:)