SpringSecurity権管理[記事]

限りシステムとユーザーが一日に基本的な権利管理、または不適切な操作に対処する必要があるとして、あなたはどのように行うために、データベースを削除します。オープンソースはSpringSecurity、史郎、権利管理モデル等RBAC、ACLを、持っている権利管理フレームワークは、より良いまたはベースの著作権管理モデルが構築された車輪のためのオープンソースのフレームワークを選択することで、すべての最初の調査研究の第一は、同社の事業の適切な実現の選挙について調査しなければなりません波SpringSecurity

この記事によって、あなたは学ぶことができます

  • SpringSecurityいくつかのコアクラス
  • 使用SpringSecurity役割ベースのアクセス許可を確認します
  • SpringSecurity的不足

SpringSecurityコアクラス

のでSpringSecurity学習の研究だけなので、ソースコードを導入そこにはありません。権限の管理が認可、認証され、許可が最初にユーザー情報を取得するためにサインインする必要がありますが、ログイン、ログアウト、分散話をするためにここではありませんsession管理し、学ぶためにコアクラスの認証プロセスをご紹介しますコアクラスはすぐに統合することができるSpringSecurityフレームワークを。

パリティをログに記録
  • UsernamePasswordAuthenticationFilter =>ユーザログイン認証が、このクラスは、ランディングチェックを実行するために実際にはありませんが、providerManagerのことで
  • ProviderManager=>クラスがあるList<AuthenticationProvider>1が通過できる限り、異なるパリティ、。通常の状況下で、我々は、ユーザー名とパスワードが何であるか、この時点値しないAuthenticationProviderクラスを達成するためにAbstractUserDetailsAuthenticationProvider
  • AbstractUserDetailsAuthenticationProvider=>着陸サブクラスチェックすることで得られたadditionalAuthenticationChecks完成方法を
  • DaoAuthenticationProvider=> AbstractUserDetailsAuthenticationProvider私たちは、パスワードを設定している場合のみ、サブカテゴリ、(メモリベースのデータベースに基づいていてもよい)とパスワードの確認を渡すが着陸に失敗したチェックしません。
  • UserDetailsService=>このインタフェースを介して、唯一の方法はloadUserByUsername、このようなユーザー名と(我々が設定したパスワード情報などのユーザーを返すとしてパッケージUserDetails実装クラス

概要:ログインユーザー名パスワード検証我々は(つまり、設定クライアントのユーザー名とパスワードを取得することでUserDetails取得するには、比較のための実装クラス)のユーザ名とパスワードは、当社で設定されているUserDetailsService.loadUserByUsername(String userName)計画の焦点[の実現、一つはしなければなりませんテスト]、達成するためのフレームワークUserDetailsServiceが付属して同じ時間枠であれば、プロジェクトの要件を満たすことができない一般的には、あなたは、手動で達成する必要があるUserDetails要件を満たすことができないクラスの実現、我々はまた、彼のUserDetailsを実現することができます

チェックパーミッション
  • FilterSecurityInterceptor=>役割ベースの許可がブロッカーを確認し、親クラスを呼び出すAbstractSecurityInterceptorbeforeInvocation認証のための方法を
  • AbstractSecurityInterceptor=>コールAccessDecisionManagerの実装クラスdecideの認証のための方法を、どのように認証がクラスを記述して、実装することができる方法をカスタマイズしたいですAccessDecisionManager
  • AffirmativeBased=>デフォルトを使用しAccessDecisionManager、実装クラスを呼び出してAccessDecisionVoter、今投票すると言うことができない、メソッド名は誤解を招く認証方法の実装クラスのための投票を、実際にエンドを追跡することによって権限チェックを返しますが、それはまだ文字列を超えています
  • WebExpressionVoter=>デフォルトの使用AccessDecisionVoterを呼び出し、実装クラスをAuthentication的authentication認証するための方法を
  • SecurityExpressionOperations=>ゲットAuthenticationオブジェクトのインタフェース
  • SecurityExpressionRoot=> SecurityExpressionOperations実装クラス

概要:カスタム認証は、実際には、層の多くを呼び出すの層は、本質的ではあるが、我々は現在のユーザーのリストの権利を決定するために、これらのチューブを必要としないことがあり、一般的な方法ではありません含ま必要なURLへのアクセスを含めるかどうか

SpringBoot統合SpringSecurity

頼ります
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>1.4.1.RELEASE</version>
</dependency>
复制代码
UserDetails実装クラス:UserDTO.java
public class UserDTO implements UserDetails {
    /**
     * 用户名
     * */
    private String username;

    /**
     * 密码
     * */
    private String password;

    /**
     * 角色列表
     * */
    private List<String> roleList;

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<String> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<String> roleList) {
        this.roleList = roleList;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorityList = new ArrayList<>();
        for (String role : roleList) {
            authorityList.add(new SimpleGrantedAuthority(role));
        }

        return authorityList;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}
复制代码

実装クラスは、我々はを調査するインターフェイス、実装する必要がroleListカプセル化された文字列SimpleGrantedAuthorityでは、SimpleGrantedAuthorityそれはGrantedAuthorityデフォルトの実装では、独自の再実装のニーズを満たすことができない場合は、クラスの実現。UserDetailであるSpringSecurity限り、あなたの最後の関係は、ユーザー情報やアクセス権をパッケージ化しますように関係なく、あなたがデータベースを構築する方法、アプリケーションと、間のブリッジUserDetailsSpringSecurityあなたは独自のメカニズムに応じて権限を確認することができます

UserDetailsS​​ervice実装クラス:UserDetailsS​​erviceImpl.java
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    private UsersService usersService;

    /**
     * 根据用户名获取用户信息
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Users users = new Users();
        users.setUsername(username);
        List<Users> usersList = usersService.selectList(users);

        return buildUserDTO(usersList);
    }

    /**
     * 封装UserDTO对象
     *
     * @param usersList
     * @return
     * */
    private UserDTO buildUserDTO(List<Users> usersList) {
        UserDTO userDTO = new UserDTO();
        userDTO.setUsername(usersList.get(0).getUsername());
        userDTO.setPassword(usersList.get(0).getPassword());
        List<String> roleList = new ArrayList<>();
        for (Users users : usersList) {
            roleList.add(String.format("ROLE_%s", users.getRole()));
        }

        userDTO.setRoleList(roleList);
        return userDTO;
    }
}
复制代码

このクラスアクションは、データベースからパッケージへの適切な情報とユーザ情報を検索することであるUserDetailsリターン

アクセス権の設定クラス:WebSecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法级安全验证
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated() //任何请求,登录后可以访问
                .and().formLogin().permitAll(); //登录页面用户任意访问

        // 关闭CSRF跨域
        http.csrf().disable();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 设置拦截忽略文件夹,可以对静态资源放行
        web.ignoring().antMatchers("/css/**", "/js/**", "/templates/**");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //1.设置自定义userDetailService
        //2.校验时指定密码解码方式
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }
}
复制代码

このクラスはよくランディングページや、着陸後の任意の要求へのアクセスなど、いくつかの簡単なアクセス許可の設定、装備されている、誰もがログインページにアクセスすることができます。理由により@EnableGlobalMethodSecurityアノテーションのレベルを検証するopenメソッド、メソッドレベルの許可は、この方法で構成されていません。自分の指定することで実現同時にUserDetailsServiceパスワードを指定しない場合は、道をデコードすると、パスワードを最新の解読の仕方にスローされますSpringSecurityバージョンを

制御層のアノテーションを使用します

@RestController
@RequestMapping("/api/user")
public class UsersController {
    @GetMapping("/guest")
    @PreAuthorize("hasAnyRole('guest')")
    public Object guest() {
        return "hello guest";
    }

    @PreAuthorize("hasAnyRole('admin')")
    @GetMapping("/admin")
    public Object admin() {
        return "hello admin";
    }
}
复制代码

@PreAuthorizeコントロールにアクセスするには、hasAnyRoleAPIへのアクセスが許可(役割)を持って使用することに加えて、書かれている@PreAuthorizeあなたも使用することができ、ノートを@Secured@PostAuthorize注釈を

不足SpringSecurityフレームワーク

  • プロジェクトコードが侵入しました

  • 十分に一般的ではない、すべての必要な権限の検証システムは、統合が必要ですSpringSecurityフレームワークは、異なるアプリケーションシステムのデータベース設計は、UserDetailそれは一般的に自分自身を達成するのにかかる[単なる一例を、実際の開発プロセスは、おそらくより多くのクラスを書き換えます]

  • 役割ダイナミックでなければなりません、しかしによってSpringSecurity静的であるロール設定、データベース内のコードを変更する必要がありますが、それ以外の場合は使用できない、新しい役割を追加しました

  • ないRBAC設計モデルが、ACLあなたがに基づいて必要な場合のモデルは、特に明確ではない役割権限の明確化、権限の役割は、例えば、RBAC自分のパーミッションチェックの方法を再書き込みしなければならない権限チェック

  • 権利管理の粒度は、権限のレベルをチェックするために、このような方法をサポートすることができない、十分に詳細に説明されていない、私は自分のチェック権限を記述する必要があり、よりきめの細かい権限をサポートしたいです

  • それぞれ設けられたキャッシュユーザー情報には3つの方法NullUserCacheEhCacheBasedUserCacheSpringCacheBasedUserCache永遠まずreturn null、キャッシュを使用していないのと同等後者の二つのメモリキャッシュされ、キャッシュヒット率は、分散配置で表示され、キャッシュの矛盾、キャッシュを実装する必要があります

    欠陥のある場合にのみ、彼の意見のいくつかは、私を修正してください

最終添付ファイル:プロジェクトソース

おすすめ

転載: juejin.im/post/5d7516f951882559c4162b05