发表于: 2018-01-02 15:16:59

1 508


今天完成的事

做了shiro的demo。

目录结构

MyShiroRealm

package com.ptteng;

import com.ptteng.service.UserInfoService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;

/**
* Created by ${MIND-ZR} on 2018/1/2.
*/
public class MyShiroRealm extends AuthorizingRealm {
@Resource
   private UserInfoService userInfoService;

   @Override
   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
       SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
       UserInfo userInfo = (UserInfo)principals.getPrimaryPrincipal();
       for(SysRole role:userInfo.getRoleList()){
authorizationInfo.addRole(role.getRole());
           for(SysPermission p:role.getPermissions()){
authorizationInfo.addStringPermission(p.getPermission());
           }
}
return authorizationInfo;
   }

@Override
   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
       //获取用户的输入的账号.
       String username = (String)token.getPrincipal();
       System.out.println(token.getCredentials());
       //通过username从数据库中查找 User对象,如果找到,没找到.
       //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
       UserInfo userInfo = userInfoService.findByUsername(username);
       System.out.println("----->>userInfo="+userInfo);
       if(userInfo == null){
return null;
       }
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
userInfo, //用户名
               userInfo.getPassword(), //密码
              // ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+salt
               getName() //realm name
       );
       return authenticationInfo;
   }
}


ShiroConfig

package com.ptteng;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* Created by ${MIND-ZR} on 2018/1/2.
*/
@Configuration
public class ShiroConfig {
@Bean
   public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
System.out.println("ShiroConfiguration.shirFilter()");
       ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
       shiroFilterFactoryBean.setSecurityManager(securityManager);
       //拦截器.
       Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
       // 配置不会被拦截的链接 顺序判断
       filterChainDefinitionMap.put("/static/**", "anon");
       //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
       filterChainDefinitionMap.put("/logout", "logout");
       //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
       //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
       filterChainDefinitionMap.put("/**", "authc");
       // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
       shiroFilterFactoryBean.setLoginUrl("/login");
       // 登录成功后要跳转的链接
       shiroFilterFactoryBean.setSuccessUrl("/index");

       //未授权界面;
       shiroFilterFactoryBean.setUnauthorizedUrl("/403");
       shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
       return shiroFilterFactoryBean;
   }

@Bean
   public MyShiroRealm myShiroRealm(){
MyShiroRealm myShiroRealm = new MyShiroRealm();
       return myShiroRealm;
   }


@Bean
   public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
       securityManager.setRealm(myShiroRealm());
       return securityManager;
   }


}

UserInfoController

package com.ptteng.web;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/userInfo")
public class UserInfoController {

/**
    * 用户查询.
    * @return
    */
   @RequestMapping("/userList")
@RequiresPermissions("userInfo:view")//权限管理;
   public String userInfo(){
return "userInfo";
   }

/**
    * 用户添加;
    * @return
    */
   @RequestMapping("/userAdd")
@RequiresPermissions("userInfo:add")//权限管理;
   public String userInfoAdd(){
return "userInfoAdd";
   }

/**
    * 用户删除;
    * @return
    */
   @RequestMapping("/userDel")
@RequiresPermissions("userInfo:del")//权限管理;
   public String userDel(){
return "userInfoDel";
   }
}

HomeController

package com.ptteng.web;

import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@Controller
public class HomeController {
@RequestMapping({"/","/index"})
public String index(){
return"/index";
   }

@RequestMapping("/login")
public String login(HttpServletRequest request, Map<String, Object> map) throws Exception{
System.out.println("HomeController.login()");
       // 登录失败从request中获取shiro处理的异常信息。
       // shiroLoginFailure:就是shiro异常类的全类名.
       String exception = (String) request.getAttribute("shiroLoginFailure");
       System.out.println("exception=" + exception);
       String msg = "";
       if (exception != null) {
if (UnknownAccountException.class.getName().equals(exception)) {
System.out.println("UnknownAccountException -- > 账号不存在:");
               msg = "UnknownAccountException -- > 账号不存在:";
           } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
System.out.println("IncorrectCredentialsException -- > 密码不正确:");
               msg = "IncorrectCredentialsException -- > 密码不正确:";
           } else if ("kaptchaValidateFailed".equals(exception)) {
System.out.println("kaptchaValidateFailed -- > 验证码错误");
               msg = "kaptchaValidateFailed -- > 验证码错误";
           } else {
msg = "else >> "+exception;
               System.out.println("else -- >" + exception);
           }
}
map.put("msg", msg);
       // 此方法不处理登录成功,shiro进行处理
       return "/login";
   }

@RequestMapping("/403")
public String unauthorizedRole(){
System.out.println("------没有权限-------");
       return "403";
   }

}



测试

1、编写好后就可以启动程序,访问index页面,由于没有登录就会跳转到login页面。登录之后就会跳转到index页面,登录后,有直接在浏览器中输入index页面访问,又会跳转到login页面。上面这些操作时候触发MyShiroRealm.doGetAuthenticationInfo()这个方法,也就是登录认证的方法。

2、登录admin账户,访问:http://127.0.0.1:8080/userInfo/userAdd显示用户添加界面,访问http://127.0.0.1:8080/userInfo/userDel显示403没有权限。上面这些操作时候触发MyShiroRealm.doGetAuthorizationInfo()这个方面,也就是权限校验的方法。

3、修改admin不同的权限进行测试

鉴于太菜,只能测试这么点。

收获

熟悉了shiro的权限控制。。。。好用的一比。但我不会!

遇到的问题

使用thymeleaf

首先是引入maven依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

在使用的过程中会发现,他会有严格的html5的校验 ,所以在配置文件application.properties中,添加

去除模板校验

明天的计划

加深理解


返回列表 返回列表
评论

    分享到