shiro自定义Realm(数据源)

2.1一样先导包

<!--使用shiro需要先导包-->
<dependencies>
    <!--shiro的核心包-->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.0</version>
    </dependency>
    <!--日志包-->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <!--测试包-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
    </dependency>
</dependencies>

2.2准备自定义Realm

  • 写一个Realm,继承AuthorizingRealm
  • 提供了两个方法,一个是授权doGetAuthorizationInfo,一个是身份认证 doGetAuthenticationInfo

(准备个MyRealm.java文件,填写如下内容 )

public class MyRealm extends AuthorizingRealm {

    //授权认证功能就写在这里面
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
     //获取授权对象 SimpleAuthorizationInfo authorizationInfo
= new SimpleAuthorizationInfo(); //从getRoles()方法中获取角色并放且放到授权对象中,getRoles()方法在下面 Set<String> roles = getRoles(); authorizationInfo.setRoles(roles); //从getPerms()方法中获取权限并放且放到授权对象中,getPerms()方法在下面 Set<String> perms = getPerms(); authorizationInfo.setStringPermissions(perms); return authorizationInfo; } /** * 假设这里获取到当前用户的角色 */ private Set<String> getRoles(){ Set<String> roles = new HashSet<>(); roles.add("admin"); roles.add("it"); return roles; } /** * 假设这里获取到当前用户的权限 */ private Set<String> getPerms(){ Set<String> perms = new HashSet<>(); perms.add("employee:index"); return perms; } /** * 记住:如果这个方法返回null,就代表是用户名错误,shiro就会抛出:UnknownAccountException */ //身份认证(登录)就写在这里面 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //1.拿到令牌(UsernamePasswordToken) UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; //2.拿到用户名,判断这个用户是否存在 // 2.1 拿到传过来的用户名 String username = token.getUsername(); // 2.2 根据用户名从getUsers()方法中拿到密码,getUsers()方法在下面 String password = this.getUsers(username); // 2.3 如果没有拿到密码(没有通过用户名拿到相应的用户->用户不存在) if(password==null){ return null; } //记住:我们只在正常完成这里的功能,shiro会判断密码是否正确 //3.返回 AuthenticationInfo这个对象 /** * 咱们创建对象需要传的参数:SimpleAuthenticatinInof(4个参数顺序解释) * Object principal:主体(可以乱写) -> 登录成功后,你想把哪一个对象存下来 * Object credentials:凭证(就是密码) -> 数据库中的密码 * credentials(密码)Salt:盐值 * String realmName : realm的名称(可以乱写) */ //拿到咱们的盐值对象(ByteSource) ByteSource salt = ByteSource.Util.bytes("itsource"); SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,salt,"myRealm"); return authenticationInfo; } /** * 假设这里是根据用户名进行的查询 * MD5:e10adc3949ba59abbe56e057f20f883e * MD5+10次:4a95737b032e98a50c056c41f2fa9ec6 * MD5+10次+itsource:831d092d59f6e305ebcfa77e05135eac */ public String getUsers(String username){ if("admin".equals(username)){ return "831d092d59f6e305ebcfa77e05135eac"; }else if("zhang".equals(username)){ return "123"; } return null; } }

2.3测试自定义Realm(一定得有import org.junit.Test;才能测试)

 @Test
    public void testMyRealm() throws Exception{
        //一.创建一个SecurityManager对象
        // 1.创建realm对象
        MyRealm myRealm = new MyRealm();
        // 2.创建SecurityManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager(myRealm);
        //②.相当于把SecurityManager放到了当前上下文
        SecurityUtils.setSecurityManager(securityManager);
        //③.拿到当前用户
        Subject subject = SecurityUtils.getSubject();

        //Hashed(哈希)Credentials(认证)Matcher(匹配器)
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //设置哈希算法
        matcher.setHashAlgorithmName("MD5");
        //设置迭代次数
        matcher.setHashIterations(10);
        //把匹配器交给shiro
        myRealm.setCredentialsMatcher(matcher);

        System.out.println("用户是否登录:"+subject.isAuthenticated());
        //④.如果没有登录,让他登录
        if(!subject.isAuthenticated()){
            try {
                UsernamePasswordToken token = new UsernamePasswordToken("admin","123456");
                subject.login(token);
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                System.out.println("用户名错误");
            } catch (IncorrectCredentialsException e) {
                e.printStackTrace();
                System.out.println("密码错误");
            } catch (AuthenticationException e) {
                e.printStackTrace();
                System.out.println("神迷错误");
            }
        }
        System.out.println("用户是否登录:"+subject.isAuthenticated());

        System.out.println("是否是admin角色:"+subject.hasRole("admin"));
        System.out.println("是否是hr角色:"+subject.hasRole("hr"));

        System.out.println("是否有employee:index权限:"+subject.isPermitted("employee:index"));
        System.out.println("是否有employee:save权限:"+subject.isPermitted("employee:save"));
        System.out.println("是否有department:index权限:"+subject.isPermitted("department:index"));


    }

 

posted @ 2019-11-24 10:13  肖镜泽  阅读(488)  评论(0编辑  收藏  举报