记录下来一遍以后回顾.
先推荐几个参考项目
https://github.com/Dreampie/jfinal-shiro
http://www.oschina.net/code/snippet_96568_33628
几个主要的文件
Maven pom.xml
<dependency>
<groupId>org.apache.oltu.oauth2</groupId>
<artifactId>org.apache.oltu.oauth2.authzserver</artifactId>
<version>0.31</version>
</dependency>
<dependency>
<groupId>org.apache.oltu.oauth2</groupId>
<artifactId>org.apache.oltu.oauth2.resourceserver</artifactId>
<version>0.31</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>cn.dreampie</groupId>
<artifactId>jfinal-shiro</artifactId>
<version>0.2</version>
</dependency>
客户端
public class IndexController extends Controller {
public void index() {
if (null == getPara("code", null)) {
redirect(ClientRes.getString(ClientRes.LOGIN_URL));
return;
}
try {
// 认证服务器返回授权码,根据授权码,客户端ID,客户端密匙,组装OAuthClientRequest,前往服务端获取访问令牌
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
OAuthClientRequest accessTokenRequest = OAuthClientRequest
.tokenLocation(
ClientRes.getString(ClientRes.ACCESS_TOKEN_URL))
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(ClientRes.getString(ClientRes.CLIENT_ID))
.setClientSecret(
ClientRes.getString(ClientRes.CLIENT_SECRET))
.setCode(getPara("code"))
.setRedirectURI(ClientRes.getString(ClientRes.REDIRECT_URL))
.buildQueryMessage();
OAuthAccessTokenResponse oAuthResponse = oAuthClient.accessToken(
accessTokenRequest, OAuth.HttpMethod.POST);
String accessToken = oAuthResponse.getAccessToken();
// Long expiresIn = oAuthResponse.getExpiresIn();
// 根据访问令牌去资源服务器获取数据
OAuthClientRequest resourceRequest = new OAuthBearerClientRequest(
ClientRes.getString(ClientRes.RESOURCE_URL))
.setAccessToken(accessToken).buildQueryMessage();
OAuthResourceResponse resourceResponse = oAuthClient.resource(
resourceRequest, OAuth.HttpMethod.GET,
OAuthResourceResponse.class);
String username = resourceResponse.getBody();
System.out.println(username);
render(new JsonRender(username).forIE());
} catch (Exception e) {
e.printStackTrace();
}
}
}
配置文件
CLIENT_ID = c1ebe466-1cdc-4bd3-ab69-77c3561b9dee
CLIENT_SECRET = d8346ea2-6017-43ed-ad68-19c0f971738b
ACCESS_TOKEN_URL = http://localhost:8443/accessToken
RESOURCE_URL = http://localhost:8443/resource
REDIRECT_URL = http://localhost:90
#LOGIN_URL = http://localhost:8443/authorize?client_id=c1ebe466-1cdc-4bd3-ab69-77c3561b9dee&response_type=code&redirect_uri=http://localhost:90
LOGIN_URL = http://localhost:8443/authorize?client_id=c1ebe466-1cdc-4bd3-ab69-77c3561b9dee&response_type=code&username=admin&redirect_uri=http://localhost:90
认证服务器
public class AuthorizeController extends Controller {
private static OAuthService oAuthService = new OAuthServiceImpl(
CacheKit.getCacheManager());
public void index() throws OAuthSystemException {
try {
// 构建OAuth授权请求
OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(getRequest());
// 检查传入的客户端id是否正确
if (!oAuthService.checkClientId(oauthRequest.getClientId())) {
OAuthResponse response = OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(OAuthError.TokenResponse.INVALID_CLIENT)
.setErrorDescription(
Constants.INVALID_CLIENT_DESCRIPTION)
.buildJSONMessage();
render(new JsonRender("{\"result\":0,\"msg\":\"客户端id错误!\"}")
.forIE());
return;
}
Subject subject = SecurityUtils.getSubject();
// 如果用户没有登录,跳转到登陆页面
if (!subject.isAuthenticated()) {
if (!login(subject)) {// 登录失败时跳转到登陆页面
render(new JsonRender(
"{\"result\":0,\"msg\":\"用户未登录,请先登录授权!\"}").forIE());
return;
}
}
User user = (User) subject.getPrincipal();
// User user = User.dao.findById(1);
// 生成授权码
String authorizationCode = null;
// responseType目前仅支持CODE,另外还有TOKEN
String responseType = oauthRequest
.getParam(OAuth.OAUTH_RESPONSE_TYPE);
if (responseType.equals(ResponseType.CODE.toString())) {
OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(
new MD5Generator());
authorizationCode = oauthIssuerImpl.authorizationCode();
oAuthService.addAuthCode(authorizationCode,
user.getStr("username"));
}
// 进行OAuth响应构建
OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse
.authorizationResponse(getRequest(),
HttpServletResponse.SC_FOUND);
// 设置授权码
builder.setCode(authorizationCode);
// 得到到客户端重定向地址
String redirectURI = oauthRequest
.getParam(OAuth.OAUTH_REDIRECT_URI);
// 构建响应
final OAuthResponse response = builder.location(redirectURI)
.buildQueryMessage();
redirect(response.getLocationUri(), true);
} catch (OAuthProblemException e) {
// 出错处理
String redirectUri = e.getRedirectUri();
if (OAuthUtils.isEmpty(redirectUri)) {
// 告诉客户端没有传入redirectUri直接报错
render(new JsonRender(
"OAuth callback url needs to be provided by client!!!",
401).forIE());
}
// 返回错误消息(如?error=)
final OAuthResponse response = OAuthASResponse
.errorResponse(HttpServletResponse.SC_FOUND).error(e)
.location(redirectUri).buildQueryMessage();
redirect(response.getLocationUri(), true);
}
}
private boolean login(Subject subject) {
try {
String username = getPara("username", "");
String password = getPara("password", "admin");
if ("".equals(username) || "".equals(password)) {
return false;
}
UsernamePasswordToken token = new UsernamePasswordToken(username,
password);
subject.login(token);
return true;
} catch (UnknownAccountException uae) {
System.out.println("账户不存在!");
} catch (IncorrectCredentialsException ice) {
System.out.println("密码不正确!");
} catch (LockedAccountException lae) {
System.out.println("账户被禁了!");
} catch (AuthenticationException ae) {
System.out.println("认证错误!");
}
return false;
}
}
public class AccessTokenController extends Controller {
private static OAuthService oAuthService = new OAuthServiceImpl(
CacheKit.getCacheManager());
public void index() throws URISyntaxException, OAuthSystemException {
try {
// 构建OAuth请求
OAuthTokenRequest oauthRequest = new OAuthTokenRequest(getRequest());
// 检查提交的客户端id是否正确
if (!oAuthService.checkClientId(oauthRequest.getClientId())) {
OAuthResponse response = OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(OAuthError.TokenResponse.INVALID_CLIENT)
.setErrorDescription(
Constants.INVALID_CLIENT_DESCRIPTION)
.buildJSONMessage();
render(new JsonRender(response).forIE());
return;
}
// 检查客户端安全KEY是否正确
if (!oAuthService.checkClientSecret(oauthRequest.getClientSecret())) {
OAuthResponse response = OAuthASResponse
.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
.setError(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)
.setErrorDescription(
Constants.INVALID_CLIENT_DESCRIPTION)
.buildJSONMessage();
render(new JsonRender(response).forIE());
return;
}
String authCode = oauthRequest.getParam(OAuth.OAUTH_CODE);
// 检查验证类型,此处只检查AUTHORIZATION_CODE类型,其他的还有PASSWORD或REFRESH_TOKEN
if (oauthRequest.getParam(OAuth.OAUTH_GRANT_TYPE).equals(
GrantType.AUTHORIZATION_CODE.toString())) {
if (!oAuthService.checkAuthCode(authCode)) {
OAuthResponse response = OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(OAuthError.TokenResponse.INVALID_GRANT)
.setErrorDescription("错误的授权码").buildJSONMessage();
render(new JsonRender(response).forIE());
return;
}
}
// 生成Access Token
OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(
new MD5Generator());
final String accessToken = oauthIssuerImpl.accessToken();
oAuthService.addAccessToken(accessToken,
oAuthService.getUsernameByAuthCode(authCode));
// 生成OAuth响应
OAuthResponse response = OAuthASResponse
.tokenResponse(HttpServletResponse.SC_OK)
.setAccessToken(accessToken)
.setExpiresIn(String.valueOf(oAuthService.getExpireIn()))
.buildJSONMessage();
// 根据OAuthResponse生成ResponseEntity
render(new JsonRender(response.getBody()).forIE());
} catch (OAuthProblemException e) {
// 构建错误响应
OAuthResponse response = OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST).error(e)
.buildJSONMessage();
render(new JsonRender(response).forIE());
}
}
}
public class ResourceController extends Controller {
private static OAuthService oAuthService = new OAuthServiceImpl(
CacheKit.getCacheManager());
public void index() throws OAuthSystemException {
try {
// 构建OAuth资源请求
OAuthAccessResourceRequest oauthRequest = new OAuthAccessResourceRequest(
getRequest(), ParameterStyle.QUERY);
// 获取Access Token
String accessToken = oauthRequest.getAccessToken();
// 验证Access Token
if (!oAuthService.checkAccessToken(accessToken)) {
// 如果不存在/过期了,返回未验证错误,需重新验证
OAuthResponse response = OAuthRSResponse
.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
.setRealm(Constants.RESOURCE_SERVER_NAME)
.setError(OAuthError.ResourceResponse.INVALID_TOKEN)
.buildHeaderMessage();
render(new JsonRender(response).forIE());
return;
}
// 返回用户名
String username = oAuthService
.getUsernameByAccessToken(accessToken);
render(new JsonRender(username).forIE());
} catch (OAuthProblemException e) {
// 检查是否设置了错误码
String errorCode = e.getError();
if (OAuthUtils.isEmpty(errorCode)) {
OAuthResponse response = OAuthRSResponse
.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
.setRealm(Constants.RESOURCE_SERVER_NAME)
.buildHeaderMessage();
render(new JsonRender(response).forIE());
}
OAuthResponse response = OAuthRSResponse
.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
.setRealm(Constants.RESOURCE_SERVER_NAME)
.setError(e.getError())
.setErrorDescription(e.getDescription())
.setErrorUri(e.getUri()).buildHeaderMessage();
render(new JsonRender(response).forIE());
}
}
}
<ehcache name="shiro">
<diskStore path="java.io.tmpdir/shiro-ehcache" />
<defaultCache maxElementsInMemory="1000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
diskSpoolBufferSizeMB="50" />
<!-- 登录记录缓存 锁定10分钟 -->
<cache name="passwordRetryCache" maxEntriesLocalHeap="2000"
eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"
overflowToDisk="false" statistics="true">
</cache>
<cache name="authorizationCache" maxEntriesLocalHeap="2000"
eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"
overflowToDisk="false" statistics="true">
</cache>
<cache name="authenticationCache" maxEntriesLocalHeap="2000"
eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"
overflowToDisk="false" statistics="true">
</cache>
<cache name="shiro-activeSessionCache" maxEntriesLocalHeap="2000"
eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"
overflowToDisk="false" statistics="true">
</cache>
<cache name="code-cache" maxEntriesLocalHeap="2000" eternal="false"
timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false"
statistics="true">
</cache>
</ehcache>
[main]
authc = cn.dreampie.shiro.ShiroFormAuthenticationFilter
authc.useCaptcha = false
#默认登陆数据提交路径
authc.loginUrl = /signin
#分角色登录提交配置
#authc.loginUrlMap = R_ADMIN:/admin/signin
#默认或者successUrlMap没有该角色时
authc.successUrl = /order
#不同角色登陆到不同的url,R_USER:/order可以不配置,会默认使用successUrl
authc.successUrlMap = R_USER:/order,R_MEMBER:/order/region,R_MANAGER:/order/branch,R_ADMIN:/order/branch
authc.failureUrl = /
#不同角色登陆失败跳转的路径
#authc.failureUrlMap =R_ADMIN:/admin/login
signout = cn.dreampie.shiro.ShiroLogoutFilter
#默认的退出url,redirectUrlMap里没有该角色使用该url
signout.redirectUrl = /
#如果你要区分不同角色推出到不同的url,使用map
#signout.redirectUrlMap = R_ADMIN:/admin/index
#realm
myRealm = com.tbynet.sooeso.realm.ShiroDbRealm
securityManager.realm = $myRealm
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordMatcher = cn.dreampie.shiro.ShiroPasswordMatcher
passwordMatcher.passwordService = $passwordService
myRealm.credentialsMatcher = $passwordMatcher
#cache
shiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
shiroCacheManager.cacheManagerConfigFile = classpath:ehcache-shiro.xml
securityManager.cacheManager = $shiroCacheManager
#session
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionDAO.activeSessionsCacheName = shiro-activeSessionCache
sessionManager.sessionDAO = $sessionDAO
securityManager.sessionManager = $sessionManager
sessionListener = cn.dreampie.shiro.listeners.ShiroSessionListener
securityManager.sessionManager.sessionListeners = $sessionListener
securityManager.sessionManager.globalSessionTimeout = 1200000
securityManager.sessionManager.sessionValidationSchedulerEnabled = false
securityManager.sessionManager.deleteInvalidSessions = false
[urls]
/** = anon
/authorize/**=anon
/accessToken/**=anon
/userInfo/**=anon
/*
SQLyog v10.2
MySQL - 5.5.40 : Database - oauth2
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`oauth2` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `oauth2`;
/*Table structure for table `oauth2_client` */
DROP TABLE IF EXISTS `oauth2_client`;
CREATE TABLE `oauth2_client` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`client_name` varchar(100) DEFAULT NULL,
`client_id` varchar(100) DEFAULT NULL,
`client_secret` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_oauth2_client_client_id` (`client_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*Data for the table `oauth2_client` */
insert into `oauth2_client`(`id`,`client_name`,`client_id`,`client_secret`) values (1,'chapter17-client','c1ebe466-1cdc-4bd3-ab69-77c3561b9dee','d8346ea2-6017-43ed-ad68-19c0f971738b');
/*Table structure for table `oauth2_user` */
DROP TABLE IF EXISTS `oauth2_user`;
CREATE TABLE `oauth2_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`salt` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_oauth2_user_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*Data for the table `oauth2_user` */
insert into `oauth2_user`(`id`,`username`,`password`,`salt`) values (1,'admin','d3c59d25033dbf980d29554025c23a75','8d78869f470951332959580424d4bf4f');
/*Table structure for table `sec_permission` */
DROP TABLE IF EXISTS `sec_permission`;
CREATE TABLE `sec_permission` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '名称',
`value` varchar(50) NOT NULL COMMENT '值',
`url` varchar(255) DEFAULT NULL COMMENT 'url地址',
`intro` varchar(255) DEFAULT NULL COMMENT '简介',
`pid` bigint(20) DEFAULT '0' COMMENT '父级id',
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='权限';
/*Data for the table `sec_permission` */
insert into `sec_permission`(`id`,`name`,`value`,`url`,`intro`,`pid`,`created_at`,`updated_at`,`deleted_at`) values (1,'管理员目录','P_D_ADMIN','/admin/**','',0,'2015-05-07 16:44:40',NULL,NULL),(2,'角色权限管理','P_ROLE','/admin/role/**','',1,'2015-05-07 16:44:40',NULL,NULL),(3,'用户管理','P_USER','/admin/user/**','',1,'2015-05-07 16:44:40',NULL,NULL),(4,'总部目录','P_D_MEMBER','/member/**','',0,'2015-05-07 16:44:40',NULL,NULL),(5,'分部目录','P_D_USER','/user/**','',0,'2015-05-07 16:44:40',NULL,NULL),(6,'用户处理','P_USER_CONTROL','/user/branch**','',5,'2015-05-07 16:44:40',NULL,NULL),(7,'订单','P_ORDER','/order/**','',0,'2015-05-07 16:44:40',NULL,NULL),(8,'订单处理','P_ORDER_CONTROL','/order/deliver**','',7,'2015-05-07 16:44:40',NULL,NULL),(9,'订单更新','P_ORDER_UPDATE','/order/update**','',7,'2015-05-07 16:44:40',NULL,NULL),(10,'支部订单','P_ORDER_BRANCH','/order/branch**','',7,'2015-05-07 16:44:40',NULL,NULL),(11,'区域支行处理','P_REGION_CONTROL','/order/region**','',7,'2015-05-07 16:44:40',NULL,NULL),(12,'收货地址','P_Address','/address/**','',0,'2015-05-07 16:44:40',NULL,NULL);
/*Table structure for table `sec_role` */
DROP TABLE IF EXISTS `sec_role`;
CREATE TABLE `sec_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '名称',
`value` varchar(50) NOT NULL COMMENT '值',
`intro` varchar(255) DEFAULT NULL COMMENT '简介',
`pid` bigint(20) DEFAULT '0' COMMENT '父级id',
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='角色';
/*Data for the table `sec_role` */
insert into `sec_role`(`id`,`name`,`value`,`intro`,`pid`,`created_at`,`updated_at`,`deleted_at`) values (1,'超级管理员','R_ADMIN','',0,'2015-05-07 16:44:40',NULL,NULL),(2,'系统管理员','R_MANAGER','',1,'2015-05-07 16:44:40',NULL,NULL),(3,'总部','R_MEMBER','',2,'2015-05-07 16:44:40',NULL,NULL),(4,'分部','R_USER','',2,'2015-05-07 16:44:40',NULL,NULL);
/*Table structure for table `sec_role_permission` */
DROP TABLE IF EXISTS `sec_role_permission`;
CREATE TABLE `sec_role_permission` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id` bigint(20) NOT NULL,
`permission_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8 COMMENT='角色权限';
/*Data for the table `sec_role_permission` */
insert into `sec_role_permission`(`id`,`role_id`,`permission_id`) values (1,1,1),(2,1,2),(3,1,3),(4,1,4),(5,1,5),(6,1,6),(7,1,7),(8,1,8),(9,1,9),(10,1,10),(11,1,11),(12,1,12),(13,2,1),(14,2,3),(15,2,4),(16,2,5),(17,2,6),(18,2,7),(19,2,8),(20,2,9),(21,2,10),(22,2,11),(23,2,12),(24,3,4),(25,3,5),(26,3,6),(27,3,11),(28,4,5),(29,4,7),(30,4,9),(31,4,12);
/*Table structure for table `sec_user` */
DROP TABLE IF EXISTS `sec_user`;
CREATE TABLE `sec_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '登录名',
`providername` varchar(50) NOT NULL COMMENT '提供者',
`email` varchar(200) DEFAULT NULL COMMENT '邮箱',
`phone` varchar(50) DEFAULT NULL COMMENT '联系电话',
`password` varchar(200) NOT NULL COMMENT '密码',
`hasher` varchar(200) NOT NULL COMMENT '加密类型',
`salt` varchar(200) NOT NULL COMMENT '加密盐',
`avatar_url` varchar(255) DEFAULT NULL COMMENT '头像',
`first_name` varchar(10) DEFAULT NULL COMMENT '名字',
`last_name` varchar(10) DEFAULT NULL COMMENT '姓氏',
`full_name` varchar(20) DEFAULT NULL COMMENT '全名',
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户';
/*Data for the table `sec_user` */
insert into `sec_user`(`id`,`username`,`providername`,`email`,`phone`,`password`,`hasher`,`salt`,`avatar_url`,`first_name`,`last_name`,`full_name`,`created_at`,`updated_at`,`deleted_at`) values (1,'admin','shengmu','wangrenhui1990@gmail.com','15611434500','$shiro1$SHA-256$500000$OBABsRNo28z7O839AycvrQ==$yn8q8rQ0siF5Leie0YyNax4w6upzkKNVQt2bfprGx8I=','default_hasher','','','管理员','圣牧','圣牧.管理员','2015-05-07 16:44:41',NULL,NULL);
/*Table structure for table `sec_user_info` */
DROP TABLE IF EXISTS `sec_user_info`;
CREATE TABLE `sec_user_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL COMMENT '用户id',
`creator_id` bigint(20) DEFAULT NULL COMMENT '创建者id',
`gender` int(11) DEFAULT '0' COMMENT '性别0男,1女',
`province_id` bigint(20) DEFAULT NULL COMMENT '省id',
`city_id` bigint(20) DEFAULT NULL COMMENT '市id',
`county_id` bigint(20) DEFAULT NULL COMMENT '县id',
`street` varchar(500) DEFAULT NULL COMMENT '街道',
`zip_code` varchar(50) DEFAULT NULL COMMENT '邮编',
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户信息';
/*Data for the table `sec_user_info` */
insert into `sec_user_info`(`id`,`user_id`,`creator_id`,`gender`,`province_id`,`city_id`,`county_id`,`street`,`zip_code`,`created_at`,`updated_at`,`deleted_at`) values (1,1,0,0,1,2,3,'人民大学',NULL,'2015-05-07 16:44:41',NULL,NULL);
/*Table structure for table `sec_user_role` */
DROP TABLE IF EXISTS `sec_user_role`;
CREATE TABLE `sec_user_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`role_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户角色';
/*Data for the table `sec_user_role` */
insert into `sec_user_role`(`id`,`user_id`,`role_id`) values (1,1,1);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
public class ShiroDbAuthzService implements JdbcAuthzService {
@Override
public Map<String, AuthzHandler> getJdbcAuthz() {
// 加载数据库的url配置
// 按长度倒序排列url
Map<String, AuthzHandler> authzJdbcMaps = Collections
.synchronizedMap(new TreeMap<String, AuthzHandler>(
new Comparator<String>() {
public int compare(String k1, String k2) {
int result = k2.length() - k1.length();
if (result == 0) {
return k1.compareTo(k2);
}
return result;
}
}));
// 遍历角色
List<Role> roles = Role.dao.find("select * from sec_role");
List<Permission> permissions = null;
for (Role role : roles) {
// 角色可用
if (role.getDate("daleted_at") == null) {
permissions = Permission.dao.findByRoleId(role.get("id"));
// 遍历权限
for (Permission permission : permissions) {
// 权限可用
if (permission.getDate("daleted_at") == null) {
if (permission.getStr("url") != null
&& !permission.getStr("url").isEmpty()) {
authzJdbcMaps.put(
permission.getStr("url"),
new JdbcPermissionAuthzHandler(permission
.getStr("value")));
}
}
}
}
}
return authzJdbcMaps;
}
}
public class ShiroDbRealm extends AuthorizingRealm {
/**
* 登录认证
*
* @param token
* @return
* @throws org.apache.shiro.authc.AuthenticationException
*/
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
User user = null;
String username = userToken.getUsername();
if (ValidateKit.isEmail(username)) {
user = User.dao
.findFirst(
"SELECT id,username,providername,email,phone,password,hasher,salt,avatar_url,first_name,last_name,full_name,created_at,updated_at,deleted_at FROM sec_user WHERE email=? AND deleted_at IS NULL",
username);
} else if (ValidateKit.isMobile(username)) {
user = User.dao
.findFirst(
"SELECT id,username,providername,email,phone,password,hasher,salt,avatar_url,first_name,last_name,full_name,created_at,updated_at,deleted_at FROM sec_user WHERE phone=? AND deleted_at IS NULL",
username);
} else {
user = User.dao
.findFirst(
"SELECT id,username,providername,email,phone,password,hasher,salt,avatar_url,first_name,last_name,full_name,created_at,updated_at,deleted_at FROM sec_user WHERE username=? AND deleted_at IS NULL",
username);
}
if (user != null) {
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,
user.getStr("password"), getName());
return info;
} else {
return null;
}
}
/**
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
*
* @param principals
* 用户信息
* @return
*/
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
String loginName = ((User) principals.fromRealm(getName()).iterator()
.next()).get("username");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Set<String> roleSet = new LinkedHashSet<String>(); // 角色集合
Set<String> permissionSet = new LinkedHashSet<String>(); // 权限集合
List<Role> roles = null;
User user = User.dao
.findFirst(
"SELECT id,username,providername,email,phone,PASSWORD,hasher,salt,avatar_url,first_name,last_name,full_name,created_at,updated_at,deleted_at FROM sec_user WHERE username=? AND deleted_at IS NULL",
loginName);
if (user != null) {
// 遍历角色
roles = Role.dao.findByUserId(user.getLong("id"));
} else {
SubjectKit.getSubject().logout();
}
loadRole(roleSet, permissionSet, roles);
info.setRoles(roleSet); // 设置角色
info.setStringPermissions(permissionSet); // 设置权限
return info;
}
/**
* @param roleSet
* @param permissionSet
* @param roles
*/
private void loadRole(Set<String> roleSet, Set<String> permissionSet,
List<Role> roles) {
List<Permission> permissions;
for (Role role : roles) {
// 角色可用
if (role.getDate("deleted_at") == null) {
roleSet.add(role.getStr("value"));
permissions = Permission.dao.findByRoleId(role.getLong("id"));
loadAuth(permissionSet, permissions);
}
}
}
/**
* @param permissionSet
* @param permissions
*/
private void loadAuth(Set<String> permissionSet,
List<Permission> permissions) {
// 遍历权限
for (Permission permission : permissions) {
// 权限可用
if (permission.getDate("deleted_at") == null) {
permissionSet.add(permission.getStr("value"));
}
}
}
/**
* 更新用户授权信息缓存.
*/
public void clearCachedAuthorizationInfo(Object principal) {
SimplePrincipalCollection principals = new SimplePrincipalCollection(
principal, getName());
clearCachedAuthorizationInfo(principals);
}
/**
* 清除所有用户授权信息缓存.
*/
public void clearAllCachedAuthorizationInfo() {
Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
if (cache != null) {
for (Object key : cache.keys()) {
cache.remove(key);
}
}
}
}