Spring boot + shiro 跨域配置(解决jsessionid丢失问题)
2017-11-08 17:26
1166 查看
后端部分
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; @Configuration public 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 117b9 ){ 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>
相关文章推荐
- Spring Boot学习总结(6)——SpringBoot解决ajax跨域请求问题的配置
- Spring boot + shiro 解决跨域登陆问题
- Springboot 之 解决IDEA读取properties配置文件的中文乱码问题
- springboot中通过cors协议解决跨域问题
- 解决angular+spring boot的跨域问题
- ajax跨域问题解决(spring boot)
- 加入spring-boot后导致maven的profile多环境配置失效的问题解决
- 解决eclipse创建spring boot项目加载不到application.properties配置文件的问题
- Spring boot中解决跨域问题
- Spring boot项目maven的profile多环境配置不自动替换变量的问题解决
- 解决spring中不同配置文件中存在name或者id相同的bean可能引起的问题
- springboot中通过cors协议解决跨域问题
- 解决angular+spring boot的跨域问题
- Spring Boot : CROS解决跨域问题(七)
- Springboot通过cors解决跨域问题(解决spring security oath2的/oauth/token跨域问题)
- 解决maven工程中使用spring-boot后导致的profile多环境配置失效的问题
- spring boot整合shiro引用配置文件配置是出现的问题
- shiro+spring boot+mybatis启动循环引用问题解决思路和方案
- Springboot 之 解决IDEA读取properties配置文件的中文乱码问题
- Spring boot 项目 maven的profile多环境配置 不自动替换变量的问题解决