shiro 权限过滤器 -------(1)

 

ApplicationCode:应用代码,程序员自己编写

Subject:shiro框架提供接口,代表当前“用户”,subject对象有状态;理解:subject包含自定义User对象

Shiro SecurityManager:核心,安全管理器;管理所有用户

Realm:框架提供一些,一般自己编写。通过realm调用dao查询安全数据(用户名密码;用户的权限,角色

 

 

开始认证(登陆)

完善userAction中登陆:applicationCode --->Subject----->securityManager------->自定义realm

 

 

完善realm中认证方法:

 

 

基于shirourl拦截方式权限控制

realm中授权

 

applicationContext.xml

    <!-- 配置shiro 过滤器工厂对象 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 注入安全管理器 -->
        <property name="securityManager" ref="securityManager"></property>
        <!--  private String loginUrl;  当后边配置url,需要当前用户认证通过后才可以访问;如果用户没有登陆,跳转登陆页面
              private String successUrl; 权限不足页面
              private String unauthorizedUrl; -->
        <property name="loginUrl" value="/login.jsp"></property>
        <property name="unauthorizedUrl" value="/unauthorized.jsp"></property>
        <!-- 注入过滤器链:配置系统中url请求拦截规则  注意:配置url拦截规则有顺序
            authc:过滤器工厂产生过滤器之一
                 /**:所有请求
                  当系统发送某url要求当前用户必须认证通过后才能访问
            anon:匿名过滤器:访问url不需要当前用户认证,没有权限可以访问
            perms:权限过滤器:访问url需要当前用户具有某个权限才可以访问
         -->
        <property name="filterChainDefinitions">
            <value>
                /login.jsp = anon
                /css/** = anon
                /js/** = anon
                /images/** = anon
                /validatecode.jsp* = anon
                /userAction_login.action = anon
                /pages/base/standard.jsp = perms["standard_page"]
                /** =  authc
            </value>
        </property>
    </bean>
    
    <!-- 配置安全管理器对象 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"></property>
    </bean>
    
    <!-- 配置realm对象 -->
    <bean id="bosRealm" class="com.itheima.bos.realm.BosRealm"></bean>
    
    <!-- spring提供配置shiro注解扫描
        在servie层方法上使用shiro注解,运行时期此方法所在类产生代理对象
        AutoProxy:自动代理,根据请求自动选择代理技术
            jdk动态代理:基于接口
            cglib动态代理:基于Class
        注意:强制使用cglib动态代理
     -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <property name="proxyTargetClass" value="true"></property>
    </bean>
    <!-- 配置shiro的切面:(切点+通知/增强)  增强:验证当前用户是否有权限 -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></bean>

 

 

public class UserAction extends BaseAction<User> {

    @Autowired
    private UserService userService;
    
    //接收验证码
    private String checkCode;
    public void setCheckCode(String checkCode) {
        this.checkCode = checkCode;
    }

    /**
      * @Description: 基于shiro实现登陆(认证)
      * @return
      * @throws Exception
      *      
     */
    @Action("userAction_login")
    public String login() throws Exception {
        if(StringUtils.isNotBlank(model.getUsername())&& StringUtils.isNoneBlank(model.getPassword())&&StringUtils.isNotBlank(checkCode)){
            //判断验证码
            String realCheckCode = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
            if(checkCode.equals(realCheckCode)){
                //相等,开始通过shiro实现认证
                //通过工具类获取subject对象
                Subject subject = SecurityUtils.getSubject();  //当前“用户”,未认证状态
                //创建认证令牌; 封装页面提交用户名,密码
                AuthenticationToken token = new UsernamePasswordToken(model.getUsername(), Md5Util.encode(model.getPassword()));;
                //logion方法调用安全管理器;
                try {
                    subject.login(token);
                } catch (Exception e) {
                    e.printStackTrace();
                    //认证失败
                    return "login";
                }
                //认证通过
                //从主角中获取用户信息,将用户的信息存Session中
                User user = (User) subject.getPrincipal();
                ServletActionContext.getRequest().getSession().setAttribute("loginUser", user);
                return "index";
            }
        }else{
            return "login";
        }
        return super.execute();
    }
}

 

 

public class BosRealm extends AuthorizingRealm{
    
    @Autowired
    private UserDao userDao;
    /**
      * @Description: 
      * @param token subject.login方法中传 用户名密码令牌
      * @return 
    */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("开始认证");
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        //页面输入的用户名
        //根据用户名查询数据库中真实密码
        String username = usernamePasswordToken.getUsername();
        User user = userDao.findByUsername(username);
        if(user==null){
            //用户名输出错误
            return null;  //当此方法中返回null,shiro会抛出异常 :未知账户异常
        }
        //比对密码工作交给shiro框架
        //p1:主角  p2:令牌/真实密码  p3:当前realm名称
        AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
        return info;
    }


    //授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("开始授权");
        //TODO 后期改造查询数据库中对应的权限,角色
        //返回简单授权信息:包含当前用户有的权限点;角色
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //添加用户权限
        info.addStringPermission("standard_page");
        info.addStringPermission("courier_delete");
        //添加用户角色
        info.addRole("admin");
        return info;
    }

    
}

 

posted on 2017-08-24 17:13  0001  阅读(774)  评论(0编辑  收藏  举报