结构
概念介绍
-
Subject 我们把用户或者程序称为主体(如用户,第三方服务,cron作业),主体去访问系统或者资源 SecurityManager 安全管理器,Subject的认证和授权都要在安全管理器下进行 -
Authenticator 认证器,主要负责Subject的认证 Realm 数据域,Shiro和安全数据的连接器,好比jdbc连接数据库; 通过realm获取认证授权相关信息 -
Authorizer 授权器,主要负责Subject的授权, 控制subject拥有的角色或者权限 -
Cryptography
加解密,Shiro的包含易于使用和理解的数据加解密方法,简化了很多复杂的api
缓存管理器,比如认证或授权信息,通过缓存进行管理,提高性能
代码
-项目结构
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0-M1</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>shiro_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shiro_demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
package com.example.shiro_demo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;
public class QuickStartTest02 {
private SimpleAccountRealm accountRealm = new SimpleAccountRealm();
private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
@Before
public void init(){
accountRealm.addAccount("lihw", "123");
accountRealm.addAccount("chendan", "456");
defaultSecurityManager.setRealm(accountRealm);
}
@Test
public void testAuthentication(){
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("chendan", "456");
subject.login(token);
System.out.println("认证结果:"+ subject.isAuthenticated());
}
}
package com.example.shiro_demo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;
public class QuickStartTest03 {
private SimpleAccountRealm accountRealm = new SimpleAccountRealm();
private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
@Before
public void init(){
accountRealm.addAccount("lihw", "123","root", "admin");
accountRealm.addAccount("chendan", "456", "user");
defaultSecurityManager.setRealm(accountRealm);
}
@Test
public void testAuthentication(){
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("chendan", "456");
subject.login(token);
System.out.println("认证结果:"+ subject.isAuthenticated());
System.out.println("是否有对应角色:"+ subject.hasRole("user"));
System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
subject.logout();
System.out.println("---------------退出之后---------------------");
System.out.println("认证结果:"+ subject.isAuthenticated());
System.out.println("是否有对应角色:"+ subject.hasRole("root"));
System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
}
}
package com.example.shiro_demo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Before;
import org.junit.Test;
public class QuickStartTesTxt {
@Before
@Test
public void testAuthentication(){
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("jack", "456");
subject.login(token);
System.out.println("认证结果:"+ subject.isAuthenticated());
System.out.println("是否有对应角色:"+ subject.hasRole("user"));
System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
System.out.println("是否有video:find权限:"+ subject.isPermitted("video:find"));
subject.logout();
System.out.println("---------------退出之后---------------------");
System.out.println("认证结果:"+ subject.isAuthenticated());
System.out.println("是否有对应角色:"+ subject.hasRole("root"));
System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
}
}
# 格式 name=password,role1,role2,..roleN
[users]
# user 'root' with password 'secret' and the 'admin' role,
jack = 456, user
# user 'guest' with the password 'guest' and the 'guest' role
xdcalss = 123, root
# 格式 role=permission1,permission2...permissionN 也可以用通配符
# 下面配置user的权限为所有video:find,video:buy,如果需要配置video全部操作crud 则 user = video:*
[roles]
user = video:find,video:buy
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
package com.example.shiro_demo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Before;
import org.junit.Test;
public class QuickStartTesCustomRealm {
@Before
@Test
public void testAuthentication(){
CustomRealm customRealm = new CustomRealm();
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
defaultSecurityManager.setRealm(customRealm);
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("jack", "123");
subject.login(token);
System.out.println("认证结果:"+ subject.isAuthenticated());
System.out.println("是否有对应角色:"+ subject.hasRole("user"));
System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
System.out.println("是否有video:find权限:"+ subject.isPermitted("video:find"));
subject.logout();
System.out.println("---------------退出之后---------------------");
System.out.println("认证结果:"+ subject.isAuthenticated());
System.out.println("是否有对应角色:"+ subject.hasRole("root"));
System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
}
}
package com.example.shiro_demo;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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 java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class CustomRealm extends AuthorizingRealm {
private final Map<String, String> userInfoMap = new HashMap<>();
{
userInfoMap.put("jack", "123");
userInfoMap.put("lhw", "456");
}
private final Map<String, Set<String>> permissionMap = new HashMap<>();
{
Set<String> set1 = new HashSet<>();
Set<String> set2 = new HashSet<>();
set1.add("video:find");
set1.add("video:buy");
set2.add("video:add");
set2.add("video:delete");
permissionMap.put("jack", set1);
permissionMap.put("lihw", set2);
}
private final Map<String, Set<String>> roleMap = new HashMap<>();
{
Set<String> set1 = new HashSet<>();
Set<String> set2 = new HashSet<>();
set1.add("role1");
set1.add("role2");
set2.add("root");
roleMap.put("jack", set1);
roleMap.put("lihw", set2);
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权认证 doGetAuthorizationInfo");
String name = (String) principalCollection.getPrimaryPrincipal();
Set<String> permissions = getPermisstionsByNameFromDb(name);
Set<String> roles = getRoleByNameFromDb(name);
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.setRoles(roles);
simpleAuthorizationInfo.setStringPermissions(permissions);
return simpleAuthorizationInfo;
}
private Set<String> getRoleByNameFromDb(String name) {
return roleMap.get(name);
}
private Set<String> getPermisstionsByNameFromDb(String name) {
return permissionMap.get(name);
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("登录认证 doGetAuthenticationInfo");
String name = (String) authenticationToken.getPrincipal();
String pwd = userInfoMap.get(name);
if(pwd == null || "".equals(pwd)) {
return null;
}
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, pwd, this.getName());
return simpleAuthenticationInfo;
}
}
|