ライブサーバー-4-史郎さんを簡単に使用できます

Apacheの史郎は、Javaのセキュリティフレームワークである、主に完了すること:認証、承認、暗号化、セッション管理、キャッシングおよびその他の機能、およびシンプルなAPI、より多くの人々は、フレームワークを使用しています。

Shiro介绍

次のように基本的な機能は以下のとおりです。

史郎基本的な機能の.png

  1. 認証:認証/ログイン、ユーザが対応するIDを持っていることを確認してください。
  2. 認証:認証は、ユーザーがそのようなように、現在のユーザーが持っている権限の背景の管理者の管理となどの特定の権限を持っているかどうかを決定します。
  3. SessionManagerの:セッション管理、前に一度終了していないユーザーがログイン後のセッションは、セッションを介してユーザを識別することです。
  4. 暗号化:暗号化、データのセキュリティを確保するため。
  5. Webサポート:簡単にウェブ環境に統合。
  6. Cacheing:ようにキャッシュ、ユーザーのログイン情報を保存し、アクセス権、および。

Shiro-1.png
ShrioのAPIのコアが対象です。 テーマは、 本体を示し、ユーザがあってもよく、それは要求してもよいです。すべてのサブジェクトがSecurityManager.getSubject()メソッドでのSecurityManagerにバインドされます、あなたは対象の現在のユーザーを獲得することができます。 セキュリティマネージャ :セキュリティマネージャ;つまり、すべての安全関連の操作は、セキュリティマネージャと相互作用し、そしてそれは、すべての件名を管理します。SecurityManagerのは、それのIDと権限を決定する方法ですか?その後、我々が導入べき レルム 、ドメインの概念を、シロはレルムから(例えばアクセス許可)安全性データを取得するセキュリティマネージャを決定するために、ユーザに許可を与えました。

Shiro使用

私たちは、このような管理者、一般ユーザとして、ユーザーごとに異なる権限を、分割したい場合は、上記の導入により、私たちは、学ぶことができます。セッションを管理するために、あなたはこの史郎のセキュリティフレームワークを使用する必要があります。SpringBoot中史郎あなたがレルムを設定すると同時に、コンフィギュレーション・クラスを作成する必要があります。

史郎の設定クラス

史郎の設定クラス、あなたは、レルムを設定し、セキュリティマネージャ、プロセッサのライフサイクルを設定するには、セキュリティマネージャ、AOPの注釈のサポートでShiroFilterフィルタを必要としています。

/**
 * spring-boot集成shiro配置类
 */
@Configuration
public class ShiroConfiguration {
    /**
     * 实例化lifecycleBeanPostProcessor
     * shiro生命周期处理器
     *
     * @return
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 实例化DefaultAdvisorAutoProxyCreator
     *
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }

    /**
     * 实例化自定义realm
     *
     * @return
     */
    @Bean
    public Realm getRealm() {
        return new UserRealm();
    }

    /**
     * 实例化securityManager
     *
     * @return
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(getRealm());
        return securityManager;
    }

    /**
     * 实例化shiroFilter
     *
     * @return
     */
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean() {

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/admin/403");
        return shiroFilterFactoryBean;
    }

    /**
     * 开启shiro aop注解支持.
     * 使用代理方式;所以需要开启代码支持;
     *
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
            org.apache.shiro.mgt.SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}
复制代码

二、レルム

アプリケーションは、1つまたは複数のレルムを有していてもよく、JDBC、メモリを介して達成することができます。この記事シリーズサーバ2-MyBatisの逆世代では、注意深い観察は、私は3つのデータテーブルは、権限、ロールタイプ、役割を持っている権限のタイプを示す許可、役割、役割・権限を作成し、友人を見つけるだろう3つの意味。これらの3つのテーブルとそれがレルム間の関係は何ですか?プロジェクトであるUserRealmユーザ認証、承認インターフェイスを作成しました。具体的なコードは次のよう:

public class UserRealm extends AuthorizingRealm {
    private final String realmName = "UserRealm.class";
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private RoleMapper roleMapper;

    //授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Object principal = principals.getPrimaryPrincipal();
        try {
            if (principal instanceof String) {
                UserExample example = new UserExample();
                UserExample.Criteria criteria = example.createCriteria();
                criteria.andAccountEqualTo((String) principal);
                Integer roleId = userMapper.selectByExample(example).get(0).getRoleId();
                SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
                Role role = roleMapper.selectByPrimaryKey(roleId);
                info.addRole(role.getName());
                Set<PermissionVO> permissions = permissionService.getPermissionsBy(roleId);
                for (PermissionVO permission : permissions) {
                    info.addStringPermission(permission.getName());
                }
                return info;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        Object principal = token.getPrincipal();
        if (principal instanceof String) {
            String phone = (String) principal;
            UserExample example = new UserExample();
            UserExample.Criteria criteria = example.createCriteria();
            criteria.andAccountEqualTo(phone);
            List<User> users = userMapper.selectByExample(example);
            if (null != users && users.size() > 0) {
                User user = users.get(0);
                return new SimpleAccount(user.getAccount(), user.getPassword(), realmName);
            }
        }
        return null;
    }
}
复制代码

あるUserRealmでは、我々が見ることができ、実際には、認証と承認は、ユーザーデータベースの存在を見つけるために、実際には、MyBatisのことで、そのような証明書などのデータベース内のデータ、によって判断される、認証方法は、それがユーザーのアカウントに渡され、参照しますユーザーの役割、およびそのロールを探し、権限、ストレージアカウント、ロール、AuthorizationInfoへのアクセス権情報を、完全なユーザー権限を持っています。

第三に、ユーザー認証

ユーザー認証を完了するために、コードのいくつかのシンプルなラインを次に示します。

Subject subject = SecurityUtils.getSubject();   //获取Subject
AuthenticationToken token = new UsernamePasswordToken(account, MD5Util.encrypt(password)); //根据用户账号、密码获取令牌。
try{
    subject.login(token);
}catch( ..){
  ...
}
复制代码

まず、コードの最初の行、巨大なピットがありgetSubject()は、私は疑うgetSubject()このアプローチは、クッキーとの要求は、すでに存在して新たな対象または対象を決定するかどうかに基づいているクッキーを取らなかった場合は理由リクエスト、それぞれ取得した対象は、矛盾しています。件名が一意でない場合、それはセッションになります唯一のセッションではありません、そして、キーと値のペア(通常はいくつかの状態パラメータ)の保存セッションが異常な機能につながる、使用することはできません。ログイン(ユーザ認証)が失敗した場合、そのようなので、上のUnknownAccountException(アカウントが存在しない)、IncorrectCredentialsException(アカウントのパスワードが一致していない)、LockedAccountException(ログインが許可されていない)となど、さまざまな例外がスローされます。

おすすめ

転載: juejin.im/post/5d5d3a866fb9a06ad54722df