1、添加Shiro的Maven依赖

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.5.3</version>
        </dependency>

2、Shiro核心操作说明

        Subject 用户
        SecurityManager 管理所有用户
        Realm 连接数据

//当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//执行登录方法,如果没有异常就说明OK了
subject.login(token);
//退出登录
subject.logout();
//getPrincipal() 获取到的SimpleAuthenticationInfo中的第一个参数
new SimpleAuthenticationInfo(user,user.getPassword(),"");
User user= (User) subject.getPrincipal();

3、创建UserRealm

public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;
   //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        System.out.println("执行了授权认证=>doGetAuthorizationInfo");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取当前用户对象
        Subject subject = SecurityUtils.getSubject();
        User user= (User) subject.getPrincipal();
        //设置当前用户权限
        info.addStringPermission(user.getRole());

        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了登录认证=>doGetAuthenticationInfo");

     //从token中获取用户输入的账号密码
        UsernamePasswordToken usertocken=(UsernamePasswordToken)token;

        //连接真实数据库
        User user = userService.selectByName(usertocken.getUsername());

        if(user==null){
            //如果用户名不一样,返回null 会自动抛出异常
            return  null;
        }

        //密码认证,shiro做
        //可以将user放入  Subject subject = SecurityUtils.getSubject(); 中,在授权里面获取
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

token中的账号密码来源:

//在控制器或者接收用户输入账号密码的地方使用如下代码
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
SecurityUtils.getSubject().login(token);

4、创建Shiro配置类,并设定需要拦截的请求

@Configuration
public class ShiroConfig {

    //shiroFileterFactoryBean
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager manager){

        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(manager);

        //添加shiro的内置过滤器
        /*
        * anno:无需认证就可以访问
        * authc:必须认证才能访问
        * user:必须拥有 记住我才能用
        * perms:拥有对某个资源的权限才能访问
        * role:拥有某个角色的权限才能访问
        * */

        Map<String,String> fileter=new LinkedHashMap<String,String>();

        //正常情况下未授权,会跳转到没有授权页面
        fileter.put("/user/add","perms[admin]");  
        fileter.put("/user/update","authc");
        bean.setFilterChainDefinitionMap(fileter);

        //设置登录请求拦截 跳转的路径
        bean.setLoginUrl("/tologin");

        //未授权拦截 
        bean.setUnauthorizedUrl("/nopermission");
        return bean;

    }


    //DefaultWebSecurityManager
    @Bean
    public DefaultWebSecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager manager=new DefaultWebSecurityManager();

        //关联UserRealm
        manager.setRealm(userRealm);
        return manager;
    }

    //创建 realm 对象, 需要自定义
    //用户认证会放到UserRealm下
    //@Bean 默认情况下方法名为对象名
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //整合ShiroDialect 用来整合:shiro thymeleaf
    //getShiroDialect
    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

5、Controller中的登录操作

@RequestMapping("/user/login")
    public String login(String username,String password,Model model){

        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登录数据
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        try{
            //执行登录方法,如果没有异常就说明OK了
            subject.login(token);
            model.addAttribute("msg","登录成功");
            return "/index";
        }catch (UnknownAccountException ex){
            model.addAttribute("msg","用户名错误");
            return "/user/login";
        }catch (IncorrectCredentialsException ex){
            model.addAttribute("msg","密码错误");
            return "/user/login";
        }catch (Exception e){
            model.addAttribute("msg","未知错误");
            return "/user/login";
        }

    }

 

posted on 2021-03-08 10:44  harrietszhang  阅读(69)  评论(0编辑  收藏  举报