Shrio00 Shiro认证登录、权限管理环境搭建
基础环境准备:
JDK -> java version "1.8.0_101"
MAVEN -> Apache Maven 3.5.0
1 导入依赖
mysql驱动
mybatis
shiro相关
<!--shiro相关-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.20</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>cn.xiangxu</groupId>
<artifactId>apache_shiro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging> <name>apache_shiro</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
<!--<scope>provided</scope>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <!--shiro相关-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.20</version>
</dependency> <!--工具相关-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency> <!--jsp相关-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency> <!--servlet相关-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency> <!--jstl相关-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
2 springboot项目整合mybatis
2.1 全局配置
spring:
datasource: # 数据源配置
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 182838
url: jdbc:mysql://127.0.0.1/auth?characterEncoding=utf-8&useSSL=false
mvc: # JSP页面配置 springboot项目会自动到main下的webapp下去寻找jsp文件
view:
prefix: /pages/
suffix: .jsp mybatis: # mybatis配置
mapper-locations: mappers/*.xml # xml文件位置 放在resources目录下
type-aliases-package: cn.xiangxu.apache_shiro.model # xml文件用到的模型位置
2.2 创建数据库相关表
用户表、角色表、权限表、用户角色表、权限角色表
-- 权限表
CREATE TABLE permission (
pid INT (11) NOT NULL AUTO_INCREMENT,
pname VARCHAR (255) NOT NULL DEFAULT '',
purl VARCHAR (255) DEFAULT '',
PRIMARY KEY (pid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
INSERT INTO permission VALUES ('1', 'add', '');
INSERT INTO permission VALUES ('2', 'delete', '');
INSERT INTO permission VALUES ('3', 'edit', '');
INSERT INTO permission VALUES ('4', 'query', ''); -- 用户表
CREATE TABLE user (
uid INT (11) NOT NULL AUTO_INCREMENT,
username VARCHAR (255) NOT NULL DEFAULT '',
password VARCHAR (255) NOT NULL DEFAULT '',
PRIMARY KEY (uid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
INSERT INTO user VALUES ('1', 'admin', '123');
INSERT INTO user VALUES ('2', 'demo', '123'); -- 角色表
CREATE TABLE role (
rid INT (11) NOT NULL AUTO_INCREMENT,
rname VARCHAR (255) NOT NULL DEFAULT '',
PRIMARY KEY (rid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
INSERT INTO role VALUES ('1', 'admin');
INSERT INTO role VALUES ('2', 'customer'); -- 权限角色关系表
CREATE TABLE permission_role (
rid INT (11) NOT NULL ,
pid INT (11) NOT NULL ,
KEY idx_pid(pid),
KEY idx_rid(rid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
INSERT INTO permission_role VALUES (1, 1);
INSERT INTO permission_role VALUES (1, 2);
INSERT INTO permission_role VALUES (1, 3);
INSERT INTO permission_role VALUES (1, 4);
INSERT INTO permission_role VALUES (2, 1);
INSERT INTO permission_role VALUES (2, 4); -- 用户角色关系表
CREATE TABLE user_role (
uid INT (11) NOT NULL ,
rid INT (11) NOT NULL ,
KEY idx_uid(uid),
KEY idx_rid(rid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
INSERT INTO user_role VALUES (1, 1);
INSERT INTO user_role VALUES (2, 2);
2.3 编写实体类
用户类、角色类、权限类
package cn.xiangxu.apache_shiro.model; import lombok.Data; import java.util.HashSet;
import java.util.Set; @Data
public class User {
private Integer uid;
private String username;
private String password;
private Set<Role> roleSet = new HashSet<>();
}
User
package cn.xiangxu.apache_shiro.model; import lombok.Data; import java.util.HashSet;
import java.util.Set; @Data
public class Role {
private Integer rid;
private String rname;
private Set<User> userSet = new HashSet<>();
private Set<Permission> permissionSet = new HashSet<>();
}
Role
package cn.xiangxu.apache_shiro.model; import lombok.Data; @Data
public class Permission {
private Integer pid;
private String pname;
private String purl; public Permission() {
}
}
Permission
2.3 编写mapper接口
package cn.xiangxu.apache_shiro.mapper; import cn.xiangxu.apache_shiro.model.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository; /**
* User持久层接口
*/
@Repository
public interface UserMapper {
User findByUsername(@Param("username") String username);
}
2.4 编写mapper映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.xiangxu.apache_shiro.mapper.UserMapper">
<resultMap id="userMap" type="cn.xiangxu.apache_shiro.model.User">
<id property="uid" column="uid"></id>
<result property="username" column="username"></result>
<result property="password" column="password"></result>
<collection property="roleSet" ofType="cn.xiangxu.apache_shiro.model.Role">
<id property="rid" column="rid"></id>
<result property="rname" column="rname"></result>
<collection property="permissionSet" ofType="cn.xiangxu.apache_shiro.model.Permission">
<id property="pid" column="pid"></id>
<result property="pname" column="pname"></result>
<result property="purl" column="purl"></result>
</collection>
</collection>
</resultMap> <select id="findByUsername" parameterType="String" resultMap="userMap">
SELECT u.*, p.*, r.*
FROM user u
INNER JOIN user_role ur ON ur.uid = u.uid
INNER JOIN role r ON r.rid = ur.rid
INNER JOIN permission_role pr ON pr.rid = r.rid
inner JOIN permission p ON p.pid = pr.pid
WHERE u.username = #{username}
</select> </mapper>
2.5 编写服务接口及实现
package cn.xiangxu.apache_shiro.service;
import cn.xiangxu.apache_shiro.model.User;
public interface UserService {
User findByUsername(String username);
}
UserService
package cn.xiangxu.apache_shiro.service.serviceImpl; import cn.xiangxu.apache_shiro.mapper.UserMapper;
import cn.xiangxu.apache_shiro.model.User;
import cn.xiangxu.apache_shiro.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper; @Override
public User findByUsername(String username) {
return userMapper.findByUsername(username);
}
}
UserServiceImpl
2.6 编写测试类
package cn.xiangxu.apache_shiro.service.serviceImpl; import cn.xiangxu.apache_shiro.model.User;
import cn.xiangxu.apache_shiro.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.*; @RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserServiceImplTest { @Autowired
private UserService userService; @Test
public void findByUsername() throws Exception {
User user = userService.findByUsername("demo");
System.out.println(user);
if (user != null) {
log.info("获取用户信息成功");
} else {
log.info("获取用户信息失败");
} } }
3 Shiro认证环境搭建
3.1 编写授权、认证登录类
新建一个继承了 AuthorizingRealm 的 AuthRealm类,重写两个 doGetAuthenticationInfo 方法
package cn.xiangxu.apache_shiro; import cn.xiangxu.apache_shiro.model.Permission;
import cn.xiangxu.apache_shiro.model.Role;
import cn.xiangxu.apache_shiro.model.User;
import cn.xiangxu.apache_shiro.service.UserService;
import org.apache.commons.collections.CollectionUtils;
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; import java.util.ArrayList;
import java.util.List;
import java.util.Set; /**
* 自定义授权、认证登录类
*/
public class AuthRealm extends AuthorizingRealm {
@Autowired
private UserService userService; // 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user = (User)principalCollection.fromRealm(this.getClass().getName()).iterator().next(); // 从session中获取用户信息
List<String> permissionList = new ArrayList<>(); // 用于存放用户的权限列表
Set<Role> roleSet = user.getRoleSet(); // 从用户信息中获取用户角色
if (CollectionUtils.isNotEmpty(roleSet)) {
for (Role role : roleSet) {
Set<Permission> permissionSet = role.getPermissionSet();
if (CollectionUtils.isNotEmpty(permissionSet)) {
for (Permission permission : permissionSet) {
permissionList.add(permission.getPname());
}
}
}
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permissionList);
return info;
} // 认证登录(使用用户名和密码进行登录认证)
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)authenticationToken;
String username = usernamePasswordToken.getUsername(); // 取出用户名
User user = userService.findByUsername(username); // 根据用户名到数据库中去获取用户信息
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
}
}
3.2 编写密码比较类
问题:在AuthRealm类中的认证登录方法中进行密码比较时是将用户输入密码和数据库的密码直接进行比较的,用户输入密码是明文的,但是数据库中的密码是经过加密的,是不能够进行比较的
解决:类支持注入一个 CredentialsMatcher 类型的密码比较器,从AuthRealm的父类doGetAuthenticationInfo 的源码中可以看出;只要通过配置文件将自定义的密码比较类依赖注入到AuthRealm即可
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.apache.shiro.realm; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Authorizer;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.permission.PermissionResolver;
import org.apache.shiro.authz.permission.PermissionResolverAware;
import org.apache.shiro.authz.permission.RolePermissionResolver;
import org.apache.shiro.authz.permission.RolePermissionResolverAware;
import org.apache.shiro.authz.permission.WildcardPermissionResolver;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.util.Initializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public abstract class AuthorizingRealm extends AuthenticatingRealm implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware {
private static final Logger log = LoggerFactory.getLogger(AuthorizingRealm.class);
private static final String DEFAULT_AUTHORIZATION_CACHE_SUFFIX = ".authorizationCache";
private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger();
private boolean authorizationCachingEnabled;
private Cache<Object, AuthorizationInfo> authorizationCache;
private String authorizationCacheName;
private PermissionResolver permissionResolver;
private RolePermissionResolver permissionRoleResolver; public AuthorizingRealm() {
this((CacheManager)null, (CredentialsMatcher)null);
} public AuthorizingRealm(CacheManager cacheManager) {
this(cacheManager, (CredentialsMatcher)null);
} public AuthorizingRealm(CredentialsMatcher matcher) {
this((CacheManager)null, matcher);
} public AuthorizingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
if (cacheManager != null) {
this.setCacheManager(cacheManager);
} if (matcher != null) {
this.setCredentialsMatcher(matcher);
} this.authorizationCachingEnabled = true;
this.permissionResolver = new WildcardPermissionResolver();
int instanceNumber = INSTANCE_COUNT.getAndIncrement();
this.authorizationCacheName = this.getClass().getName() + ".authorizationCache";
if (instanceNumber > 0) {
this.authorizationCacheName = this.authorizationCacheName + "." + instanceNumber;
} } public void setName(String name) {
super.setName(name);
String authzCacheName = this.authorizationCacheName;
if (authzCacheName != null && authzCacheName.startsWith(this.getClass().getName())) {
this.authorizationCacheName = name + ".authorizationCache";
} } public void setAuthorizationCache(Cache<Object, AuthorizationInfo> authorizationCache) {
this.authorizationCache = authorizationCache;
} public Cache<Object, AuthorizationInfo> getAuthorizationCache() {
return this.authorizationCache;
} public String getAuthorizationCacheName() {
return this.authorizationCacheName;
} public void setAuthorizationCacheName(String authorizationCacheName) {
this.authorizationCacheName = authorizationCacheName;
} public boolean isAuthorizationCachingEnabled() {
return this.isCachingEnabled() && this.authorizationCachingEnabled;
} public void setAuthorizationCachingEnabled(boolean authenticationCachingEnabled) {
this.authorizationCachingEnabled = authenticationCachingEnabled;
if (authenticationCachingEnabled) {
this.setCachingEnabled(true);
} } public PermissionResolver getPermissionResolver() {
return this.permissionResolver;
} public void setPermissionResolver(PermissionResolver permissionResolver) {
if (permissionResolver == null) {
throw new IllegalArgumentException("Null PermissionResolver is not allowed");
} else {
this.permissionResolver = permissionResolver;
}
} public RolePermissionResolver getRolePermissionResolver() {
return this.permissionRoleResolver;
} public void setRolePermissionResolver(RolePermissionResolver permissionRoleResolver) {
this.permissionRoleResolver = permissionRoleResolver;
} protected void onInit() {
super.onInit();
this.getAvailableAuthorizationCache();
} protected void afterCacheManagerSet() {
super.afterCacheManagerSet();
this.getAvailableAuthorizationCache();
} private Cache<Object, AuthorizationInfo> getAuthorizationCacheLazy() {
if (this.authorizationCache == null) {
if (log.isDebugEnabled()) {
log.debug("No authorizationCache instance set. Checking for a cacheManager...");
} CacheManager cacheManager = this.getCacheManager();
if (cacheManager != null) {
String cacheName = this.getAuthorizationCacheName();
if (log.isDebugEnabled()) {
log.debug("CacheManager [" + cacheManager + "] has been configured. Building " + "authorization cache named [" + cacheName + "]");
} this.authorizationCache = cacheManager.getCache(cacheName);
} else if (log.isInfoEnabled()) {
log.info("No cache or cacheManager properties have been set. Authorization cache cannot be obtained.");
}
} return this.authorizationCache;
} private Cache<Object, AuthorizationInfo> getAvailableAuthorizationCache() {
Cache<Object, AuthorizationInfo> cache = this.getAuthorizationCache();
if (cache == null && this.isAuthorizationCachingEnabled()) {
cache = this.getAuthorizationCacheLazy();
} return cache;
} protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
if (principals == null) {
return null;
} else {
AuthorizationInfo info = null;
if (log.isTraceEnabled()) {
log.trace("Retrieving AuthorizationInfo for principals [" + principals + "]");
} Cache<Object, AuthorizationInfo> cache = this.getAvailableAuthorizationCache();
Object key;
if (cache != null) {
if (log.isTraceEnabled()) {
log.trace("Attempting to retrieve the AuthorizationInfo from cache.");
} key = this.getAuthorizationCacheKey(principals);
info = (AuthorizationInfo)cache.get(key);
if (log.isTraceEnabled()) {
if (info == null) {
log.trace("No AuthorizationInfo found in cache for principals [" + principals + "]");
} else {
log.trace("AuthorizationInfo found in cache for principals [" + principals + "]");
}
}
} if (info == null) {
info = this.doGetAuthorizationInfo(principals);
if (info != null && cache != null) {
if (log.isTraceEnabled()) {
log.trace("Caching authorization info for principals: [" + principals + "].");
} key = this.getAuthorizationCacheKey(principals);
cache.put(key, info);
}
} return info;
}
} protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
return principals;
} protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
if (principals != null) {
Cache<Object, AuthorizationInfo> cache = this.getAvailableAuthorizationCache();
if (cache != null) {
Object key = this.getAuthorizationCacheKey(principals);
cache.remove(key);
} }
} protected abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection var1); private Collection<Permission> getPermissions(AuthorizationInfo info) {
Set<Permission> permissions = new HashSet();
if (info != null) {
Collection<Permission> perms = info.getObjectPermissions();
if (!CollectionUtils.isEmpty(perms)) {
permissions.addAll(perms);
} perms = this.resolvePermissions(info.getStringPermissions());
if (!CollectionUtils.isEmpty(perms)) {
permissions.addAll(perms);
} perms = this.resolveRolePermissions(info.getRoles());
if (!CollectionUtils.isEmpty(perms)) {
permissions.addAll(perms);
}
} return permissions.isEmpty() ? Collections.emptySet() : Collections.unmodifiableSet(permissions);
} private Collection<Permission> resolvePermissions(Collection<String> stringPerms) {
Collection<Permission> perms = Collections.emptySet();
PermissionResolver resolver = this.getPermissionResolver();
if (resolver != null && !CollectionUtils.isEmpty(stringPerms)) {
perms = new LinkedHashSet(stringPerms.size());
Iterator i$ = stringPerms.iterator(); while(i$.hasNext()) {
String strPermission = (String)i$.next();
Permission permission = this.getPermissionResolver().resolvePermission(strPermission);
((Collection)perms).add(permission);
}
} return (Collection)perms;
} private Collection<Permission> resolveRolePermissions(Collection<String> roleNames) {
Collection<Permission> perms = Collections.emptySet();
RolePermissionResolver resolver = this.getRolePermissionResolver();
if (resolver != null && !CollectionUtils.isEmpty(roleNames)) {
perms = new LinkedHashSet(roleNames.size());
Iterator i$ = roleNames.iterator(); while(i$.hasNext()) {
String roleName = (String)i$.next();
Collection<Permission> resolved = resolver.resolvePermissionsInRole(roleName);
if (!CollectionUtils.isEmpty(resolved)) {
((Collection)perms).addAll(resolved);
}
}
} return (Collection)perms;
} public boolean isPermitted(PrincipalCollection principals, String permission) {
Permission p = this.getPermissionResolver().resolvePermission(permission);
return this.isPermitted(principals, p);
} public boolean isPermitted(PrincipalCollection principals, Permission permission) {
AuthorizationInfo info = this.getAuthorizationInfo(principals);
return this.isPermitted(permission, info);
} private boolean isPermitted(Permission permission, AuthorizationInfo info) {
Collection<Permission> perms = this.getPermissions(info);
if (perms != null && !perms.isEmpty()) {
Iterator i$ = perms.iterator(); while(i$.hasNext()) {
Permission perm = (Permission)i$.next();
if (perm.implies(permission)) {
return true;
}
}
} return false;
} public boolean[] isPermitted(PrincipalCollection subjectIdentifier, String... permissions) {
List<Permission> perms = new ArrayList(permissions.length);
String[] arr$ = permissions;
int len$ = permissions.length; for(int i$ = 0; i$ < len$; ++i$) {
String permString = arr$[i$];
perms.add(this.getPermissionResolver().resolvePermission(permString));
} return this.isPermitted((PrincipalCollection)subjectIdentifier, (List)perms);
} public boolean[] isPermitted(PrincipalCollection principals, List<Permission> permissions) {
AuthorizationInfo info = this.getAuthorizationInfo(principals);
return this.isPermitted(permissions, info);
} protected boolean[] isPermitted(List<Permission> permissions, AuthorizationInfo info) {
boolean[] result;
if (permissions != null && !permissions.isEmpty()) {
int size = permissions.size();
result = new boolean[size];
int i = 0; Permission p;
for(Iterator i$ = permissions.iterator(); i$.hasNext(); result[i++] = this.isPermitted(p, info)) {
p = (Permission)i$.next();
}
} else {
result = new boolean[0];
} return result;
} public boolean isPermittedAll(PrincipalCollection subjectIdentifier, String... permissions) {
if (permissions != null && permissions.length > 0) {
Collection<Permission> perms = new ArrayList(permissions.length);
String[] arr$ = permissions;
int len$ = permissions.length; for(int i$ = 0; i$ < len$; ++i$) {
String permString = arr$[i$];
perms.add(this.getPermissionResolver().resolvePermission(permString));
} return this.isPermittedAll((PrincipalCollection)subjectIdentifier, (Collection)perms);
} else {
return false;
}
} public boolean isPermittedAll(PrincipalCollection principal, Collection<Permission> permissions) {
AuthorizationInfo info = this.getAuthorizationInfo(principal);
return info != null && this.isPermittedAll(permissions, info);
} protected boolean isPermittedAll(Collection<Permission> permissions, AuthorizationInfo info) {
if (permissions != null && !permissions.isEmpty()) {
Iterator i$ = permissions.iterator(); while(i$.hasNext()) {
Permission p = (Permission)i$.next();
if (!this.isPermitted(p, info)) {
return false;
}
}
} return true;
} public void checkPermission(PrincipalCollection subjectIdentifier, String permission) throws AuthorizationException {
Permission p = this.getPermissionResolver().resolvePermission(permission);
this.checkPermission(subjectIdentifier, p);
} public void checkPermission(PrincipalCollection principal, Permission permission) throws AuthorizationException {
AuthorizationInfo info = this.getAuthorizationInfo(principal);
this.checkPermission(permission, info);
} protected void checkPermission(Permission permission, AuthorizationInfo info) {
if (!this.isPermitted(permission, info)) {
String msg = "User is not permitted [" + permission + "]";
throw new UnauthorizedException(msg);
}
} public void checkPermissions(PrincipalCollection subjectIdentifier, String... permissions) throws AuthorizationException {
if (permissions != null) {
String[] arr$ = permissions;
int len$ = permissions.length; for(int i$ = 0; i$ < len$; ++i$) {
String permString = arr$[i$];
this.checkPermission(subjectIdentifier, permString);
}
} } public void checkPermissions(PrincipalCollection principal, Collection<Permission> permissions) throws AuthorizationException {
AuthorizationInfo info = this.getAuthorizationInfo(principal);
this.checkPermissions(permissions, info);
} protected void checkPermissions(Collection<Permission> permissions, AuthorizationInfo info) {
if (permissions != null && !permissions.isEmpty()) {
Iterator i$ = permissions.iterator(); while(i$.hasNext()) {
Permission p = (Permission)i$.next();
this.checkPermission(p, info);
}
} } public boolean hasRole(PrincipalCollection principal, String roleIdentifier) {
AuthorizationInfo info = this.getAuthorizationInfo(principal);
return this.hasRole(roleIdentifier, info);
} protected boolean hasRole(String roleIdentifier, AuthorizationInfo info) {
return info != null && info.getRoles() != null && info.getRoles().contains(roleIdentifier);
} public boolean[] hasRoles(PrincipalCollection principal, List<String> roleIdentifiers) {
AuthorizationInfo info = this.getAuthorizationInfo(principal);
boolean[] result = new boolean[roleIdentifiers != null ? roleIdentifiers.size() : 0];
if (info != null) {
result = this.hasRoles(roleIdentifiers, info);
} return result;
} protected boolean[] hasRoles(List<String> roleIdentifiers, AuthorizationInfo info) {
boolean[] result;
if (roleIdentifiers != null && !roleIdentifiers.isEmpty()) {
int size = roleIdentifiers.size();
result = new boolean[size];
int i = 0; String roleName;
for(Iterator i$ = roleIdentifiers.iterator(); i$.hasNext(); result[i++] = this.hasRole(roleName, info)) {
roleName = (String)i$.next();
}
} else {
result = new boolean[0];
} return result;
} public boolean hasAllRoles(PrincipalCollection principal, Collection<String> roleIdentifiers) {
AuthorizationInfo info = this.getAuthorizationInfo(principal);
return info != null && this.hasAllRoles(roleIdentifiers, info);
} private boolean hasAllRoles(Collection<String> roleIdentifiers, AuthorizationInfo info) {
if (roleIdentifiers != null && !roleIdentifiers.isEmpty()) {
Iterator i$ = roleIdentifiers.iterator(); while(i$.hasNext()) {
String roleName = (String)i$.next();
if (!this.hasRole(roleName, info)) {
return false;
}
}
} return true;
} public void checkRole(PrincipalCollection principal, String role) throws AuthorizationException {
AuthorizationInfo info = this.getAuthorizationInfo(principal);
this.checkRole(role, info);
} protected void checkRole(String role, AuthorizationInfo info) {
if (!this.hasRole(role, info)) {
String msg = "User does not have role [" + role + "]";
throw new UnauthorizedException(msg);
}
} public void checkRoles(PrincipalCollection principal, Collection<String> roles) throws AuthorizationException {
AuthorizationInfo info = this.getAuthorizationInfo(principal);
this.checkRoles(roles, info);
} public void checkRoles(PrincipalCollection principal, String... roles) throws AuthorizationException {
this.checkRoles((PrincipalCollection)principal, (Collection)Arrays.asList(roles));
} protected void checkRoles(Collection<String> roles, AuthorizationInfo info) {
if (roles != null && !roles.isEmpty()) {
Iterator i$ = roles.iterator(); while(i$.hasNext()) {
String roleName = (String)i$.next();
this.checkRole(roleName, info);
}
} } protected void doClearCache(PrincipalCollection principals) {
super.doClearCache(principals);
this.clearCachedAuthorizationInfo(principals);
}
}
package cn.xiangxu.apache_shiro; import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher; /**
* 自定义密码比较类
*/
public class CredentialMather extends SimpleCredentialsMatcher {
/**
* 用户密码匹配规则
* @param token 用户输入的先关信息
* @param info 根据用户名到数据库中查询到的用户信息
* @return 如果用户输入的密码和数据库中的密码匹配就返回true
*/
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;
String password = new String(usernamePasswordToken.getPassword()); // 获取用户输入的密码
String dbPassword = (String)info.getCredentials(); // 获取数据库中的密码 return this.equals(password, dbPassword); // 密码比较并返回
}
}
自定义密码比较器
3.3 编写shiro配置类
package cn.xiangxu.apache_shiro; import org.apache.shiro.mgt.SecurityManager;
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.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; /**
* Shiro配置类
*/
@Configuration
public class ShiroConfiguration { @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/login"); // 定义登录的url
shiroFilterFactoryBean.setSuccessUrl("/index"); // 定义登录成功后的url
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); // 没有权限时跳转的url LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // 请求拦截配置
filterChainDefinitionMap.put("/index", "authc");
filterChainDefinitionMap.put("/login", "anon"); // 排除 login 的验证
filterChainDefinitionMap.put("/loginUser", "anon"); // 排除 loginUser 的验证
filterChainDefinitionMap.put("/**", "user"); // 所有请求都必须进行登录过滤
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean;
} @Bean
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(authRealm);
return defaultWebSecurityManager;
} /** 注入自定义密码比较器 */
@Bean
public CredentialMather credentialMather() {
return new CredentialMather();
} /** 注入自定义的授权、认证登录类 */
@Bean
public AuthRealm authRealm(@Qualifier("credentialMather") CredentialMather credentialMather) {
AuthRealm authRealm = new AuthRealm();
authRealm.setCredentialsMatcher(credentialMather);
return authRealm;
} /** Shiro与Spring整合配置 */
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
} }
package cn.xiangxu.apache_shiro; import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher; /**
* 自定义密码比较类
*/
public class CredentialMather extends SimpleCredentialsMatcher {
/**
* 用户密码匹配规则
* @param token 用户输入的先关信息
* @param info 根据用户名到数据库中查询到的用户信息
* @return 如果用户输入的密码和数据库中的密码匹配就返回true
*/
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;
String password = new String(usernamePasswordToken.getPassword()); // 获取用户输入的密码
String dbPassword = (String)info.getCredentials(); // 获取数据库中的密码 return this.equals(password, dbPassword); // 密码比较并返回
}
}
Shrio00 Shiro认证登录、权限管理环境搭建的更多相关文章
- spring boot(十四)shiro登录认证与权限管理
这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...
- Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...
- Springboot-shiro-redis实现登录认证和权限管理
Springboot-shiro-redis实现登录认证和权限管理 在学习之前: 首先进行一下Apache Shiro和Shiro比较: Apache Shiro是一个功能强大.灵活的,开源的安全框架 ...
- Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理
本文是接着上篇博客写的:Spring boot 入门(三):SpringBoot 集成结合 AdminLTE(Freemarker),利用 generate 自动生成代码,利用 DataTable 和 ...
- springboot(十四):springboot整合shiro-登录认证和权限管理
这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...
- spring-boot(八) springboot整合shiro-登录认证和权限管理
学习文章:springboot(十四):springboot整合shiro-登录认证和权限管理 Apache Shiro What is Apache Shiro? Apache Shiro是一个功能 ...
- (转)Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理
http://www.ityouknow.com/springboot/2017/06/26/spring-boot-shiro.html 这篇文章我们来学习如何使用 Spring Boot 集成 A ...
- Spring Boot(十四):spring boot整合shiro-登录认证和权限管理
Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...
- Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理
这篇文章我们来学习如何使用 Spring Boot 集成 Apache Shiro .安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在 Java 领域一般有 Spring S ...
随机推荐
- LUA学习之一 初次接触
对于一个开源工程,开始学习它的第一步自然是编译工程. 使用vc编译lua,在网上已有许多介绍,但“纸上得来终觉浅”,自己走一遍还是有必要的. 步骤如下: 1.下载源代码,从lua.org下载最新源代码 ...
- 11 Python 文件操作
文件操作基本流程 计算机系统分为:计算机硬件,操作系统,应用程序三部分. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知 ...
- Java企业微信开发_Exception_01_"errcode":60011,"errmsg":"no privilege to access/modify contact/party/agent "
微信企业号增加成员时,返回错误信息: jsonObject:{"errcode":60011,"errmsg":"no privilege to ac ...
- hibernate复习第(三)天
今日要点: 1.继承关系映射 一个表对应一个映射树(subclass) 一个子类一个表,子类只有父类没有的字段(joined-subclass) 鉴别器和内连接结合使用(subclass join) ...
- Linux-NoSQL之Redis(三)
一.Redis数据常用操作 1.string常用操作 set key1 aminglinux get key1 set key1 aming //一个key对应一个value,多次赋值,会覆盖前面 ...
- codeforces 627B B. Factory Repairs(线段树)
B. Factory Repairs time limit per test 4 seconds memory limit per test 256 megabytes input standard ...
- JAVA标号与continue,break
可以给语句块加标号赋予它们名称,标号位于语句之前.标号只能被continue和break引用.格式如下: label:statement 语句前只允许加一个标号,标号后面不能跟大括号. ...
- JAVA中的优化技巧(适用Android)
最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...
- VC用MCI播放mp3等音乐文件
VC播放mp3等音乐文件,可以使用MCI.MCI ( Media Control Interface ) ,即媒体控制接口,向基于Windows操作系统的应用程序提供了高层次的控制媒体设备接口的能力. ...
- CH5103 [NOIP2008]传纸条[线性DP]
给定一个 N*M 的矩阵A,每个格子中有一个整数.现在需要找到两条从左上角 (1,1) 到右下角 (N,M) 的路径,路径上的每一步只能向右或向下走.路径经过的格子中的数会被取走.两条路径不能经过同一 ...