小程序 整合shiro 多realm 验证 以及 小程序不能保存cookie 解决

小程序和 spring boot+shiro  得整合

  1. 前后端分离,后台验证得方式是账号密码   小程序得验证是能正确获取用户信息  验证方式不同表的存储不同
  2. shiro 在普通得web项目中,是通过设置cookie  来保存sessionid  但是小程序不可以,小程序不允许cookie  得设置,所以无法在正常的cookie 中携带
  3. 说明:项目整体是spring boot +shiro 多是代码配置 spring boot +shiro  得配置不说了,这里只说明更改得地方解决方案:

   一  .是多realm  得配置

  •  新定义一个token  来封装小程序用户带来得信息,也就是openid
import org.apache.shiro.authc.UsernamePasswordToken;


/**
 * 这个是保存opendid  的token
 */
public class OpenidToken extends UsernamePasswordToken {


    private String pswd="ok";

    private  String  openid;

    public OpenidToken(String openid) {
        this.openid = openid;
    }

    @Override
    public Object getPrincipal() {
        return this.openid;
    }

    /**
     * 默认给固定密码
     * @return
     */
    @Override
    public Object getCredentials() {
        return this.pswd;
    }

    /**
     * 默认给记住
     * @return
     */
    @Override
    public boolean isRememberMe() {
        return Boolean.TRUE;
    }
}
  • 除了原来得realm 之外新增一个小程序得realm 来做小程序的登录验证


    /**
     * 认证 小程序v不存在账号密码得比对   能获取到openid  就意味着登陆成功
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //认证是什么意思就是把数据库查询出来封装成认证对象和表单来的数据进行比对
        OpenidToken miniToken=(OpenidToken)token;
        String openid = (String)miniToken.getPrincipal();
        String password = miniToken.getCredentials()+"";
        // 通过用户名到数据库查询用户信息
        MUser user = this.imUserService.getMUserByOpenid(openid);
        if (user == null) {
            MUser inuser=MUser.ConStructor(openid);
            this.imUserService.save(inuser);//不存在用户就给存一个
            user=inuser;
        }
        return new SimpleAuthenticationInfo(user, password, getName());
    }

 

这面其实是和正常得 UsernamePasswordToken 是一样得只是密码设置一样得这样比较简单,不然还要去重写他得验证方式
  • 更改原来得shiro config
    @Bean
    public SecurityManager securityManager(ShiroRealm shiroRealm, MiniRealm miniRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 配置 SecurityManager,并注入 shiroRealm

        //新增部分多realm配置  前端后台不同得验证   @chenkang
        ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();
        //至少成功一个都算认证通过得
        modularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        securityManager.setAuthenticator(modularRealmAuthenticator);
        List realms = new ArrayList<>();
        realms.add(shiroRealm);
        realms.add(miniRealm);
        securityManager.setRealms(realms);
        //新增部分多realm配置  前端后台不同得验证   @chenkang

        //securityManager.setRealm(shiroRealm);
        // 配置 shiro session管理器
        securityManager.setSessionManager(sessionManager());
        // 配置 缓存管理类 cacheManager
        securityManager.setCacheManager(cacheManager());
        // 配置 rememberMeCookie
        securityManager.setRememberMeManager(rememberMeManager());
        return securityManager;
    }

这面.setAuthenticationStrategy 是验证策略 ,shiro  总共提供了三种  自己可以去了解下 应对你自己得业务需求

二. 小程序不能设置cookie  得解决

            整体方案,是通过请求头中设置自定义得属性token  来模拟cookie  得携带

  •  重写DefaultWebSessionManager 原来得配置使用得默认这个,现在我们来重写他,来应对不同得前后端不同得携带方式
/**
 * 因为小程序当中不支持Cookie 重写DefaultWebSessionManager
 */
public class MiniSessionManager extends DefaultWebSessionManager {

    public final static  String token_name="token";

    public final static  String session_id_Source="request_header";

    @Override
    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        String token = WebUtils.toHttp(request).getHeader(token_name); //这个修改就是从请求头里来获取
        if(StringUtils.isEmpty(token)){
            //如果没有携带token参数则按照父类的方式在cookie进行获取
            return super.getSessionId(request, response);
        }else{
            //如果请求头中有 token 则其值为sessionId
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,session_id_Source); //session_id  来源
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID,token);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID,Boolean.TRUE);
            return token;
        }
    }

  • 更改shiro  得配置

    /**
     * session 管理对象
     *
     * @return DefaultWebSessionManager
     */
    @Bean
    public DefaultWebSessionManager sessionManager() {
        //重写DefaultWebSessionManager    @chenkang
        MiniSessionManager sessionManager = new MiniSessionManager();
        //DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        Collection listeners = new ArrayList<>();
        listeners.add(new ShiroSessionListener());
        // 设置 session超时时间
        sessionManager.setGlobalSessionTimeout(febsProperties.getShiro().getSessionTimeout() * 1000L);
        sessionManager.setSessionListeners(listeners);
        sessionManager.setSessionDAO(redisSessionDAO());
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        return sessionManager;
    }

三.登陆分开来写

小程序部分得

小程序 整合shiro 多realm 验证 以及 小程序不能保存cookie 解决_第1张图片

 

剩下得就是小程序部分了

小程序 整合shiro 多realm 验证 以及 小程序不能保存cookie 解决_第2张图片登陆得时候存入Stroage  

 

小程序 整合shiro 多realm 验证 以及 小程序不能保存cookie 解决_第3张图片

请求成功响应数据  token  不对和不存在就会去验证cookie  就像我们得配置至少成功一个就算成功

 

你可能感兴趣的:(spring,boot,配置)