Spring boot + shiro 跨域配置(解决jsessionid丢失问题)

后端部分

maven 配置shiro,spring boot就不写了

<dependency>
        <groupId>org.apache.shirogroupId>
            <artifactId>shiro-springartifactId>
            <version>1.2.2version>
        dependency>

        <dependency>
            <groupId>org.apache.shirogroupId>
            <artifactId>shiro-coreartifactId>
            <version>1.2.2version>
        dependency>

        <dependency>
            <groupId>org.apache.shirogroupId>
            <artifactId>shiro-ehcacheartifactId>
            <version>1.2.2version>
        dependency>


ShiroConfiguration 配置

import com.pamo.mall.util.PropertiesUtil;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
public class ShiroConfiguration {

    private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean){
        Map filterChainDefinitionMap = new LinkedHashMap<>();

        String[] adminAuths = PropertiesUtil.authRes.getString("admin").split(",");  //加载管理员权限
        String[] serviceAuths = PropertiesUtil.authRes.getString("service").split(","); //加载客服权限
        String[] anonAuths = PropertiesUtil.authRes.getString("anon").split(",");  //加载游客权限

        for(String adminAuth : adminAuths){
            filterChainDefinitionMap.put(adminAuth, "authc,roles[admin]");
        }
        for(String serviceAuth : serviceAuths){
            filterChainDefinitionMap.put(serviceAuth, "authc,roles[service]");
        }
        for(String anonAuth : anonAuths){
            filterChainDefinitionMap.put(anonAuth, "anon");
        }

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    }

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        loadShiroFilterChain(shiroFilterFactoryBean);
        return shiroFilterFactoryBean;
    }


    @Bean
    public EhCacheManager getEhCacheManager() {
        EhCacheManager em = new EhCacheManager();
        em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");  //配置shiro缓存
        return em;
    }

    @Bean(name = "myShiroRealm")
    public MyShiroRealm myShiroRealm(EhCacheManager cacheManager) {
        MyShiroRealm realm = new MyShiroRealm();
        realm.setCacheManager(cacheManager);
        return realm;
    }

    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }

    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(MyShiroRealm myShiroRealm) {
        DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
        dwsm.setRealm(myShiroRealm);
        dwsm.setCacheManager(getEhCacheManager());
        return dwsm;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
        aasa.setSecurityManager(securityManager);
        return aasa;
    }

}

ehcache-shiro.xml


<ehcache updateCheck="false" name="shiroCache">

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
    />
ehcache>

资源文件工具类

import java.util.PropertyResourceBundle;

/**
 * @comment 资源文件工具类
 * @author HE JIA
 * @date 2017年7月6日 下午4:32:02
 */
public class PropertiesUtil {

    public static PropertyResourceBundle authRes = (PropertyResourceBundle) PropertyResourceBundle.getBundle("props/authority");

}

Spring boot + shiro 跨域配置(解决jsessionid丢失问题)_第1张图片

MyShiroRealm配置

import com.pamo.mall.rest.domain.po.Account;
import com.pamo.mall.rest.service.AccountService;
import org.apache.shiro.authc.*;
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.springframework.beans.factory.annotation.Autowired;

/**
 * @Description: realm配置
 * @Author: hj
 * @Date: 14:19 2017/11/8
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private AccountService accountService;

    /**
     * @Description: 授予用户权限
     * @Author: hj
     * @Date: 14:19 2017/11/8
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String loginName = (String)super.getAvailablePrincipal(principalCollection);
        Account account = accountService.findByName(loginName);
        if(account != null){
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            if(account.getType() == 1){  //授予账号类型为1的用户具有admin,service的权限
                info.addRole("admin");
                info.addRole("service");
            }
            if(account.getType() == 2){  //授予账号类型为2的用户具有service的权限
                info.addRole("service");
            }
            return info;
        }
        return null;
    }

    /**
     * @Description: 登陆验证
     * @Author: hj
     * @Date: 14:19 2017/11/8
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token =(UsernamePasswordToken) authenticationToken;

        Account user=  accountService.findByName(token.getUsername());
        if(user!=null){  //自动校验
            return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
        }
        return null;
    }
}

accountService.findByName根据账号获取用户信息就不写了


开始登陆

Controller层

@Autowired
    private AccountService accountService;

    /**
     * 登陆
     * @param loginAccount
     * @return
     */
    @RequestMapping(value = "/login" , method= RequestMethod.POST)
    @ResponseBody
    public String Login(@RequestBody Account loginAccount){
        return accountService.login(loginAccount,getRequest());
    }

    @RequestMapping(value = "/f",method= RequestMethod.POST)
    @ResponseBody
    public String test2(@RequestBody Account loginAccount){
        return "路过";
    }

    /**
     * 修改密码
     * @return
     */
    @RequestMapping(value = "/u",method= RequestMethod.POST)
    @ResponseBody
    public String ModifyPassword(@RequestBody AccountDto accountDto){
        return accountService.ModifyPassword(accountDto,getAccount());
    }

    /**
     * @Description: 测试登陆访问
     * @Author: hj
     * @Date: 9:19 2017/11/8
     */
    @RequestMapping(value = "/d",method= RequestMethod.POST)
    @ResponseBody
    public ResponseMsg test(@RequestBody AccountDto accountDto){
        return new ResponseMsg("[客服]登陆成功");
    }

    /**
     * @Description: 测试登陆权限访问
     * @Author: hj
     * @Date: 9:19 2017/11/8
     */
    @RequestMapping(value = "/p",method= RequestMethod.POST)
    @ResponseBody
    public String test1(@RequestBody AccountDto accountDto){
        return "[管理员]登陆成功";
    }

Service层

/**
     * @Description: 登陆
     * @Author: hj
     * @Date: 9:38 2017/11/8
     */
    public Account login(Account account, HttpServletRequest request) {
        UsernamePasswordToken token = new UsernamePasswordToken(account.getUsername(), account.getPassword());
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);  //这一步开始登陆,并跳转到MyShiroRealm类doGetAuthenticationInfo方法中
        }catch (UnknownAccountException uae){  //账号错误
            throw PExceptionFactory.create("H0003");  //这个是处理错误的方式
        }catch(IncorrectCredentialsException ice){  //密码错误
            throw PExceptionFactory.create("H0004");
        }catch(AuthenticationException ae){  //账号或密码错误
            throw PExceptionFactory.create("H0007");
        }

        Account resultAccount = findByName(account.getUsername());  //根据账号获取用户信息
        resultAccount.setSessionId(request.getSession().getId());   //获取本次会话的sessionid

        return resultAccount;
    }

Account

/**
 * @Description: 账户
 * @Author: hj
 * @Date: 14:43 2017/11/8
 */
public class Account extends SessionIdBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;  //ID

    private String username;  //用户名

    private String password;  //密码-加密

    private Integer type;  //账号类型(1-管理员 2-客服)

    @JSONField(format = "YYYY-MM-dd HH:mm:ss")
    private Date gmtCreate;  //创建时间

    @JSONField(format = "YYYY-MM-dd HH:mm:ss")
    private Date gmtUpdate;  //更新时间

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Date getGmtCreate() {
        return gmtCreate;
    }

    public void setGmtCreate(Date gmtCreate) {
        this.gmtCreate = gmtCreate;
    }

    public Date getGmtUpdate() {
        return gmtUpdate;
    }

    public void setGmtUpdate(Date gmtUpdate) {
        this.gmtUpdate = gmtUpdate;
    }
}

SessionIdBean

/**
 * @Description: SessionId
 * @Author: hj
 * @Date: 14:41 2017/11/8
 */
public class SessionIdBean implements Serializable{

    private String sessionId;

    public String getSessionId() {
        return sessionId;
    }

    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }
}

前端部分

想要记住会话状态必须在登陆后记住会话id,之后每次访问都带上这个id,详情如下

<html>
<head>
<meta charset="utf-8">

<title>测试title>
head>

<body>

    <script type="text/javascript" src="js/jquery-1.8.0.min.js">script>

    <form action="" method="post">
      <table>
         <tr>
            <td>用户名:td>
            <td><input type="text" id="username" name="username"/>td>
         tr>
         <tr>
            <td>密码:td>
            <td><input type="password" id="password" name="password"/>td>
         tr>
         <tr>
            <td colspan="2" align="center">
                <input type="button" id="login" value="登录"/>
                <input type="reset" value="重置"/>
            td>
         tr>
      table>
   form>

   <input type="button" id="test1" value="不登录可以访问"/>
   <input type="button" id="test2" value="客服可以访问"/>
   <input type="button" id="test3" value="管理员可以访问"/>

   <script type="text/javascript">
        var sessionid = "";  //登陆后保存会话id
        $("#test3").click(function(){
            var settings = {
              "xhrFields": "{ withCredentials: true }",
              "async": true,
              "crossDomain": true,
              "url": "http://10.0.0.46:10001/mall-service/account/p;jsessionid="+sessionid,
              "type": "POST",
              "headers": {
                "content-type": "application/json",
                "cache-control": "no-cache"
              },
              "processData": false,
              "data": "{}"
            }

            $.ajax(settings).done(function (response) {
              console.log(response);
            });
        });

        $("#test2").click(function(){
            var settings = {
              "xhrFields": "{ withCredentials: true }",
              "async": true,
              "crossDomain": true,
              "url": "http://10.0.0.46:10001/mall-service/account/d;jsessionid="+sessionid,
              "type": "POST",
              "headers": {
                "content-type": "application/json",
                "cache-control": "no-cache"
              },
              "processData": false,
              "data": "{}"
            }

            $.ajax(settings).done(function (response) {
              console.log(response);
            });
        });

        $("#test1").click(function(){
            var settings = {
              "xhrFields": "{ withCredentials: true }",
              "async": true,
              "crossDomain": true,
              "url": "http://10.0.0.46:10001/mall-service/account/f;jsessionid="+sessionid,
              "type": "POST",
              "headers": {
                "content-type": "application/json",
                "cache-control": "no-cache"
              },
              "processData": false,
              "data": "{}"
            }

            $.ajax(settings).done(function (response) {
              console.log(response);
            });
        });

        $("#login").click(function(){
            var settings = {
              "xhrFields": "{ withCredentials: true }",
              "async": true,
              "crossDomain": true,
              "url": "http://10.0.0.46:10001/mall-service/account/login",
              "type": "POST",
              "headers": {
                "content-type": "application/json",
                "cache-control": "no-cache"
              },
              "processData": false,
              "data": "{username:"+$("#username").val()+",password:"+$("#password").val()+"}"
            }

            $.ajax(settings).done(function (response) {
                sessionid = response.result;
              console.log(response);
            });
        });
   script>

body>
html>

你可能感兴趣的:(spring-boot)