この記事では、Java でのカスタム Spring Security 権限制御の例を主に紹介します (実践記事)。興味のある方は参考にしてください。
背景説明
このプロジェクトには、URL + httpmethod (十分な休息を満足させる、たとえば http://www.php.cn/、一部のロールは表示 (HTTP GET) のみ) のような細かい権限制御が必要です。 、追加、変更、または削除 (POST、PUT、DELETE) する権限はありません)。
テーブルデザイン
疑惑を避けるために、使用される主要なフィールドのみがリストされています。残りはご自身で理解してください。
1.admin_user 管理者ユーザー テーブル、キー フィールド (id、role_id)。
2.t_role ロールテーブル、キーフィールド (id、privilege_id)。
3.t_privilege権限テーブル、キーフィールド(id、url、メソッド)
3つのテーブルの関係は言うまでもなく、フィールドを見れば一目で分かります。
実装前分析
逆に考えることができます:
ニーズを実現するには、最も重要なステップは、リクエストされた URL + httpmethod がデータベース内の設定と一致するかどうかを Spring Security の AccessDecisionManager に判断させることです。ただし、AccessDecisionManager は同様のニーズを持つ関連投票者を判断しません。そのため、投票者実装をカスタマイズする必要があります (デフォルトで登録されている AffirmativeBased 戦略では、投票者が ACCESS_GRANTED 投票を行う限り、それは合格と判断され、これは一致しています)。私たちの必要に応じて)。投票者を実装した後、主要なパラメータ (コレクション) があります。
1. 投票者実装をカスタマイズします
3. SecurityMetadataSource 実装をカスタマイズします。 . 認証には User インスタンスが含まれます (言うまでもなく、これは誰もがすでに行っているはずです)
プロジェクトの実装 1. カスタマイズされた GrantedAuthority の実装2. カスタム認証ユーザー インスタンス
3. カスタム UrlConfigAttribute の実装
4.
public class UrlGrantedAuthority implements GrantedAuthority { private final String httpMethod; private final String url; public UrlGrantedAuthority(String httpMethod, String url) { this.httpMethod = httpMethod; this.url = url; } @Override public String getAuthority() { return url; } public String getHttpMethod() { return httpMethod; } public String getUrl() { return url; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UrlGrantedAuthority target = (UrlGrantedAuthority) o; if (httpMethod.equals(target.getHttpMethod()) && url.equals(target.getUrl())) return true; return false; } @Override public int hashCode() { int result = httpMethod != null ? httpMethod.hashCode() : 0; result = 31 * result + (url != null ? url.hashCode() : 0); return result; } }
5. 投票者の実装をカスタマイズします
public class SystemUser implements UserDetails { private final Admin admin; private List<MenuOutput> menuOutputList; private final List<GrantedAuthority> grantedAuthorities; public SystemUser(Admin admin, List<AdminPrivilege> grantedPrivileges, List<MenuOutput> menuOutputList) { this.admin = admin; this.grantedAuthorities = grantedPrivileges.stream().map(it -> { String method = it.getMethod() != null ? it.getMethod().getLabel() : null; return new UrlGrantedAuthority(method, it.getUrl()); }).collect(Collectors.toList()); this.menuOutputList = menuOutputList; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return this.grantedAuthorities; } @Override public String getPassword() { return admin.getPassword(); } @Override public String getUsername() { return null; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } public Long getId() { return admin.getId(); } public Admin getAdmin() { return admin; } public List<MenuOutput> getMenuOutputList() { return menuOutputList; } public String getSalt() { return admin.getSalt(); } }
6. カスタム FilterSecurityInterceptor の実装
プロファイルキーの設定
public class UrlConfigAttribute implements ConfigAttribute { private final HttpServletRequest httpServletRequest; public UrlConfigAttribute(HttpServletRequest httpServletRequest) { this.httpServletRequest = httpServletRequest; } @Override public String getAttribute() { return null; } public HttpServletRequest getHttpServletRequest() { return httpServletRequest; } }
それでは、Spring Security 権限を正しく制御する旅をお楽しみください。