zoukankan      html  css  js  c++  java
  • 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"));
    
    
        }
  • 相关阅读:
    .net 自带的oracleclient 的一点小问题
    重新感受Windows 的激情
    三点定面的算法实现
    回归.NET的世界
    .NET 基础题, 可以做面试题, 不断更新 20111
    C#根据字符串生成唯一的数字
    最近看的书
    代码中的注释, 需要面向功能注释,而非使用注释
    html 页面嵌入 Silverlight , Silverlight控件覆盖悬浮HTML元素的解决方法.
    gitlab clone或者pull 仓库
  • 原文地址:https://www.cnblogs.com/bigbigxiao/p/11921455.html
Copyright © 2011-2022 走看看