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

来源:互联网 发布:java脱壳工具 编辑:程序博客网 时间:2024/06/07 01:39

后端部分

maven 配置shiro,spring boot就不写了

<dependency>        <groupId>org.apache.shiro</groupId>            <artifactId>shiro-spring</artifactId>            <version>1.2.2</version>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-core</artifactId>            <version>1.2.2</version>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-ehcache</artifactId>            <version>1.2.2</version>        </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;@Configurationpublic class ShiroConfiguration {    private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean){        Map<String, String> 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

<?xml version="1.0" encoding="UTF-8"?><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");}

这里写图片描述

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>
原创粉丝点击