spring boot与shiro实现单点登录

1. Shiro框架简介

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

1、  Authentication 认证 ---- 用户登录

2、  Authorization 授权 --- 用户具有哪些权限

3、  Cryptography 安全数据加密

4、  Session Management 会话管理

5、  Web Integration web系统集成

6、  Interations 集成其它应用,spring、缓存框架

2.导入jar包

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3.创建ShiroConfig配置类

package org.jcut.config;

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

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

/**
 * Shiro的配置类
 * @author lenovo
 *
 */
@Configuration
public class ShiroConfig {

    /**
     * 创建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        
        //添加Shiro内置过滤器
        /**
         * Shiro内置过滤器,可以实现权限相关的拦截器
         *    常用的过滤器:
         *       anon: 无需认证(登录)可以访问
         *       authc: 必须认证才可以访问
         *       user: 如果使用rememberMe的功能可以直接访问
         *       perms: 该资源必须得到资源权限才可以访问
         *       role: 该资源必须得到角色权限才可以访问
         */
        Map<String,String> filterMap = new LinkedHashMap<String,String>();
        /*filterMap.put("/add", "authc");
        filterMap.put("/update", "authc");*/
        
        //放行login.html页面
        filterMap.put("/login", "anon");
        filterMap.put("/index.html", "anon");
        //放行静态资源文件和不用拦截的访问
        filterMap.put("/js/**", "anon");
        filterMap.put("/css/**", "anon");
        filterMap.put("/big/**", "anon");
        filterMap.put("/fonts/**", "anon");
        filterMap.put("/images/**", "anon");
        filterMap.put("/Products/**", "anon");
        filterMap.put("/imgs/**", "anon");
        filterMap.put("/comment/**", "anon");
        filterMap.put("/Product_Detailed.html", "anon");
        filterMap.put("/commodity/**", "anon");
        filterMap.put("/pack/**", "anon");
        filterMap.put("/type/**", "anon");
        filterMap.put("/detail/**", "anon");
        filterMap.put("/collect/selectBycId", "anon");
        filterMap.put("/small/**", "anon");
        filterMap.put("/user/select", "anon");
        //授权过滤器
        
        filterMap.put("/**", "authc");
        
        //修改调整的登录页面
        shiroFilterFactoryBean.setLoginUrl("/login.htm");
        //设置未授权提示页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/login.htm");
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        
        
        return shiroFilterFactoryBean;
    }

    
    /**
     * 创建DefaultWebSecurityManager
     */
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    
    /**
     * 创建Realm
     */
    @Bean(name="userRealm")
    public UserRealm getRealm(){
        return new UserRealm();
    }
    

    
}

4.创建认证授权类

package org.jcut.config;
import java.util.List;

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.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.jcut.bean.User;
import org.jcut.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * 自定义Realm
 * @author lenovo
 *
 */
public class UserRealm extends AuthorizingRealm{

    /**
     * 执行授权逻辑
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
        System.out.println("执行授权逻辑");
        return null;
    }
    
    @Autowired
    private UserService userSerivce;

    /**
     * 执行认证逻辑
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
        System.out.println("执行认证逻辑");
        
        ///编写shiro判断逻辑,判断用户名和密码
        //1.判断用户名
        UsernamePasswordToken token = (UsernamePasswordToken)arg0;
        User user=new User();
        user.setTel(token.getUsername());
        user.setPwd(String.valueOf(token.getPassword()));
        List<User> list=userSerivce.select(user);
        if(list.size()==0){
            //用户名不存在
            return null;//shiro底层会抛出UnKnowAccountException
        }
        
        //2.判断密码
       return new SimpleAuthenticationInfo(list.get(0),token.getPassword(),token.getUsername());
    }


}

5.登录Controller

    @RequestMapping(value="/select",params = {"pwd","tel"})
    public Object select(User user) {
        user.setPwd(MD5Util.encode2hex(user.getPwd()));
        /**
         * 使用Shiro编写认证操作
         */
        //1.获取Subject
        Subject subject = SecurityUtils.getSubject();
        
        //2.封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(user.getTel(),user.getPwd());
        
        
            try {
                subject.login(token);
                User user1=service.select(user).get(0);
                List list=new ArrayList<User>();
                list.add(user1);
                redisTemplate.opsForValue().set(user1.getId(), list, 1l, TimeUnit.HOURS);
                data.setData(user1.getId());
                data.setStatus("1");
                data.setMsg("登陆成功!");
            }catch(Exception e) {

                data.setData("0");
                data.setStatus("0");
                data.setMsg("登陆失败!");
            }
        
        return data;
    }

猜你喜欢

转载自www.cnblogs.com/huqi96/p/13199083.html