<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>
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");
}
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>