05---shiro基本配置

自定义Realm
  • 自定义类继承AuthorizingRealm
    提供了两个方法,一个是授权doGetAuthorizationInfo,一个是身份认证 doGetAuthenticationInfo
 /*自定义类继承AuthorizingRealm*/
public class MyRealm extends AuthorizingRealm{
    /*授权*/
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //创建一个授权对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //获取并设置角色
        Set<String> roles = setRoles();
        authorizationInfo.setRoles(roles);
        //获取并设置权限
        Set<String> perms = setPerms();
        authorizationInfo.setStringPermissions(perms);

        return authorizationInfo;
    }
    //模拟数据库设置角色
    private Set<String> setRoles(){
        Set<String> roles = new HashSet<String>();
        roles.add("admin");
        return roles;
    }
    //模拟数据库设置权限
    private Set<String> setPerms(){
        Set<String> perms = new HashSet<String>();
        perms.add("*");
        perms.add("employee:save");
        return perms;
    }
    /*
    * 登录功能 返回null代表用户名不存在
    * 密码交给shiro,会自动帮我们判断
    *
    * */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //拿到用户密码 令牌 强转
        UsernamePasswordToken token =(UsernamePasswordToken)authenticationToken;
        //获取用户名
        String username = token.getUsername();
        //判断用户名是否存在
        String password = findUsername(username);
        if(password==null){
            //如果用户名不存在就返回null
            return null;
        }
        //设置盐值
        ByteSource salt = ByteSource.Util.bytes("ok");
        //判断密码是否正确
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,salt,getName());
        return authenticationInfo;
    }

    private String findUsername(String username){
        if (username.equals("admin")){
            return "3e8139cbebae8c69264cb26c8a5dfdcf";
        }else if (username.equals("it")){
            return "123456";
        }
        return null;
    }
}
测试自定义类Realm
public class RealmTest {
    @Test
    public void test(){
        //获取权限管理器对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //创建一个Relam
        MyRealm relam = new MyRealm();

        //创建一个凭证匹配器
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //设置匹配器算法
        matcher.setHashAlgorithmName("MD5");
        //设置迭代的次数
        matcher.setHashIterations(10);
        //设置凭证匹配器
        relam.setCredentialsMatcher(matcher);

        //将relam放在权限管理器中
        securityManager.setRealm(relam);
        //把管理器放在工具中
        SecurityUtils.setSecurityManager(securityManager);
        //拿到当前用户
        Subject subject = SecurityUtils.getSubject();
        //是否登录
        System.out.println("是否登录"+subject.isAuthenticated());

        //如果没登录就进行登录
        if (!subject.isAuthenticated()){
            //拿到令牌
            UsernamePasswordToken token = null;
            try {
                token = new UsernamePasswordToken("admin","123456");
                //登录
                subject.login(token);
            } catch (UnknownAccountException e) {
                System.out.println("用户名不存在");
                e.printStackTrace();
            }catch (IncorrectCredentialsException e){
                System.out.println("密码不正确");
                e.printStackTrace();
            }catch (AuthenticationException e){
                System.out.println("未知错误");
                e.printStackTrace();
            }

            //角色判断
            System.out.println("是否是admin"+subject.hasRole("admin"));
            System.out.println("是否是it"+subject.hasRole("it"));
            //权限判断
            System.out.println("是否是employee:save"+subject.isPermitted("employee:save"));
            System.out.println("是否是employee:delete"+subject.isPermitted("employee:delete"));
            System.out.println("是否是employee:update"+subject.isPermitted("employee:update"));

            //是否登录
            System.out.println("是否登录"+subject.isAuthenticated());
        }
    }
    //加密密码
    @Test
    public void testHash(){
        /*
         * algorthmName 算法
         * source 密码
         * salt 盐值
         * hashIterations 迭代次数
         *
         *           e10adc3949ba59abbe56e057f20f883e
         *    盐值    47fbb266bd4270ef4bc1fcf7e0e8a08a
         *  盐值+10  3e8139cbebae8c69264cb26c8a5dfdcf
         * */
        SimpleHash hash = new SimpleHash("MD5", "123456","ok",10);
        System.out.println(hash.toHex());
    }
}
shiro和Spring集成
  • 导包
<!-- shiro(权限框架)的支持包 -->
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-all</artifactId>
  <version>1.4.0</version>
  <type>pom</type>
</dependency>
<!-- shiro与Spring的集成包 -->
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>1.4.0</version>
</dependency>
  • web.xml中配置代理过滤器
<!--shiro 过滤器 什么都不做
      Delegating 委托给其他地方
      Proxy 这个管理器只是代理,通过名字shiroFilter去找真正做事的
      但是这个过滤器是不可缺的
  -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
      <param-name>targetFilterLifecycle</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  • 自定义类MyRealm
    模拟数据库我们去获取里面的值,在application中需要配置
/*自定义类继承AuthorizingRealm*/
public class MyRealm extends AuthorizingRealm{
    /*授权*/
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //创建一个授权对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //获取并设置角色
        Set<String> roles = setRoles();
        authorizationInfo.setRoles(roles);
        //获取并设置权限
        Set<String> perms = setPerms();
        authorizationInfo.setStringPermissions(perms);

        return authorizationInfo;
    }
    //模拟数据库设置角色
    private Set<String> setRoles(){
        Set<String> roles = new HashSet<String>();
        roles.add("admin");
        return roles;
    }
    //模拟数据库设置权限
    private Set<String> setPerms(){
        Set<String> perms = new HashSet<String>();
        perms.add("employee:index");
        return perms;
    }
    /*
    * 登录功能 返回null代表用户名不存在
    * 密码交给shiro,会自动帮我们判断
    *
    * */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //拿到用户密码 令牌 强转
        UsernamePasswordToken token =(UsernamePasswordToken)authenticationToken;
        //获取用户名
        String username = token.getUsername();
        //判断用户名是否存在
        String password = findUsername(username);
        if(password==null){
            //如果用户名不存在就返回null
            return null;
        }
        //设置盐值
        ByteSource salt = ByteSource.Util.bytes("ok");
        //判断密码是否正确
        /*
        *第一个参数  username 登录成功后可以在任何地方拿的数据
        *第二个参数  password 从数据库查询出来的密码
        *第三个参数  salt 盐值
        *第四个参数  当前realm的名字
        *
        * */
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,salt,"myRealm");
        return authenticationInfo;
    }

    private String findUsername(String username){
        if (username.equals("admin")){
            return "3e8139cbebae8c69264cb26c8a5dfdcf";
        }else if (username.equals("it")){
            return "123456";
        }
        return null;
    }
}
  • 自定义类工厂返回权限

1.返回的Map值是有顺序的;
2. 修改后要重启(热启动无效);
3.解决在xml中配置权限繁琐的问题,以后通过读取数据库内容来设置权限。

public class FilterChainDefinitionsMapFactory {
    public Map<String,String> createMap(){
        //返回权限数据
        Map<String,String> map = new LinkedHashMap<>();
        //添加不拦截的数据
        map.put("/login","anon");
        //添加权限拦截数据
        map.put("/employee/index","perms[employee:index]");
        map.put("/department/index","perms[department:index]");
        //拦截所有
        map.put("/**","authc");
        return map;
    }
}
  • applicationContext-shiro.xml的配置
    需要在 applicationContext.xml 中引入它 < import
resource="classpath:applicationContext-shiro.xml" /> 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!--shiro的核心管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="MyRealm"/>
    </bean>

   <!-- 创建相应的Realm(拿权限数据的对象)
    AisellRealm realm = new AisellRealm();-->
    <bean id="MyRealm" class="cn.itsource.aisell.web.shiro.MyRealm">
        <!--名称-->
        <property name="name" value="MyRealm"/>
        <!--凭证匹配器 realm.setCredentialsMatcher(..) -->
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!--加密算法-->
                <property name="hashAlgorithmName" value="MD5"/>
                <!--迭代次数-->
                <property name="hashIterations" value="10"/>
            </bean>
        </property>
    </bean>

    <!--可以支持注解权限控制-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>


    <!--
        shiro真实的权限过滤器(这个名字必需和shiro过滤器的名字一致)
     -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!--引入权限管理器-->
        <property name="securityManager" ref="securityManager"/>
        <!--没有登录就会进入这个路径-->
        <property name="loginUrl" value="/s/login.jsp"/>
        <!--登录成功后进入页面-->
        <property name="successUrl" value="/s/success.jsp"/>
        <!--没有权限进入的页面-->
        <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>

        <!--
            filterChainDefinitions:过滤器描述(有顺序)
                anon:不登录也可以访问(游客可以访问的页面)
                authc:必需登录才可以访问
          -->
       <!-- <property name="filterChainDefinitions">
            <value>
                /login= anon
                /s/permission.jsp = perms[employee:index]
                /department/index = perms[department:index]
                /** = authc
            </value>
        </property>-->
        <property name="filterChainDefinitionMap" ref="filterChainDefinitionsMap"></property>
    </bean>

    <!--把工厂中的方法返回值也变成一个bean-->
    <bean id="filterChainDefinitionsMap" factory-bean="filterChainDefinitionsMapFactory" factory-method="createMap"/>
    <!--创建工厂bean-->
    <bean id="filterChainDefinitionsMapFactory" class="cn.itsource.aisell.web.shiro.FilterChainDefinitionsMapFactory"/>

</beans>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值