基础环境准备:

  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认证登录、权限管理环境搭建的更多相关文章

  1. spring boot(十四)shiro登录认证与权限管理

    这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...

  2. Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...

  3. Springboot-shiro-redis实现登录认证和权限管理

    Springboot-shiro-redis实现登录认证和权限管理 在学习之前: 首先进行一下Apache Shiro和Shiro比较: Apache Shiro是一个功能强大.灵活的,开源的安全框架 ...

  4. Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理

    本文是接着上篇博客写的:Spring boot 入门(三):SpringBoot 集成结合 AdminLTE(Freemarker),利用 generate 自动生成代码,利用 DataTable 和 ...

  5. springboot(十四):springboot整合shiro-登录认证和权限管理

    这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...

  6. spring-boot(八) springboot整合shiro-登录认证和权限管理

    学习文章:springboot(十四):springboot整合shiro-登录认证和权限管理 Apache Shiro What is Apache Shiro? Apache Shiro是一个功能 ...

  7. (转)Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理

    http://www.ityouknow.com/springboot/2017/06/26/spring-boot-shiro.html 这篇文章我们来学习如何使用 Spring Boot 集成 A ...

  8. Spring Boot(十四):spring boot整合shiro-登录认证和权限管理

    Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...

  9. Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理

    这篇文章我们来学习如何使用 Spring Boot 集成 Apache Shiro .安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在 Java 领域一般有 Spring S ...

随机推荐

  1. mail

    mail.php  <?php require_once('class.phpmailer.php'); $mail = new PHPMailer(); //实例化 $mail->IsS ...

  2. Effective java -- 9 并发/序列化

    关于同步的问题,想弄明白java,同步不会是不行的.这不书弄完后还会从<java并发编程实战>和<java并发编程的艺术>选一本或者都看. 第六十六条:同步访问共享的可变数据说 ...

  3. Data Structure Array: Find the two numbers with odd occurrences in an unsorted array

    http://www.geeksforgeeks.org/find-the-two-numbers-with-odd-occurences-in-an-unsorted-array/ #include ...

  4. Java多线程系列 JUC线程池02 线程池原理解析(一)

    转载  http://www.cnblogs.com/skywang12345/p/3509960.html ; http://www.cnblogs.com/skywang12345/p/35099 ...

  5. es5严格模式简谈

    一.用法: 在全局或局部开头加上“use strict”即可 就是一行字符串,不会对不兼容严格模式的浏览器产生影响.二.不再兼容es3的一些不规则语法.使用全新的es5规范.三.两种用法: 全局严格模 ...

  6. hd acm1061

    Problem Description Given a positive integer N, you should output the most right digit of N^N.   Inp ...

  7. Ubuntu下,grep的用法

    grep(Global search Regular Expression and Print out the line)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.U ...

  8. Linux 中 bashrc 中的 rc 是什么意思

    刚刚配置 .bashrc 文件时,突然想,这里面的 rc 是什么意思? 使用了这么长时间,这个都不知道,这是醉了.Google 之,还真有不少人探究过,哈哈. 这个 ubuntu 中文论坛里,有人回答 ...

  9. FOJ 2232 匈牙利算法找二分图最大匹配

    题目链接 简单理解匈牙利算法 简单理解二分图 尽量让每一个随从击败一个对手且随从全部存活,关键是为每一个随从找对手(递归过程),"腾". #include<iostream& ...

  10. Codeforces 455B A Lot of Games:博弈dp【多局游戏】

    题目链接:http://codeforces.com/problemset/problem/455/B 题意: 给你n个字符串,然后进行k局游戏. 每局游戏开始有一个空串,然后双方轮流给这个串的末尾添 ...