Shiro 的基本配置


Shiro是一个Java安全框架,提供了身份认证、授权、加密、会话管理等安全功能,可以用于保护Java Web应用、REST服务、消息队列等系统。

下面是Shiro的配置步骤:

  1. 添加Shiro依赖:在你的项目中添加Shiro的依赖,例如在Maven中,可以在pom.xml文件中添加以下内容:
1
2
3
4
5
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.1</version>
</dependency>
  1. 配置Shiro安全管理器:在Shiro中,安全管理器是所有安全功能的核心。你需要创建一个安全管理器并配置相关的安全功能,例如Realm、Session管理器等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm());
securityManager.setSessionManager(sessionManager());
return securityManager;
}

@Bean
public Realm myRealm() {
return new MyRealm();
}

@Bean
public SessionManager sessionManager() {
return new DefaultWebSessionManager();
}

上面的代码中,创建了一个安全管理器DefaultWebSecurityManager,并设置了MyRealm作为认证和授权的数据源,DefaultWebSessionManager作为会话管理器。

  1. 配置Shiro过滤器:Shiro过滤器用于保护Web应用中的资源,例如URL、Controller等。你需要创建一个过滤器链并设置过滤器的顺序和参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Bean
public FilterRegistrationBean<DelegatingFilterProxy> filterRegistrationBean() {
FilterRegistrationBean<DelegatingFilterProxy> registration = new FilterRegistrationBean<>();
registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
registration.addUrlPatterns("/*");
registration.setName("shiroFilter");
registration.setOrder(1);
return registration;
}

@Bean
public ShiroFilterFactoryBean shiroFilter() {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager());
shiroFilter.setLoginUrl("/login");
shiroFilter.setUnauthorizedUrl("/unauthorized");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/**", "authc");
shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilter;
}

上面的代码中,创建了一个Shiro过滤器链,DelegatingFilterProxy用于代理ShiroFilter,ShiroFilterFactoryBean用于配置Shiro过滤器链。将所有URL映射到authc过滤器,表示需要进行身份认证。除了/login以外的URL都需要进行认证。

  1. 配置Shiro数据源:Shiro的认证和授权数据来源于Realm,你需要实现Realm接口并提供相应的认证和授权逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class MyRealm extends AuthorizingRealm {

// 在此方法中完成授权逻辑
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取当前用户的角色和权限信息
String username = (String) principals.getPrimaryPrincipal();
List<String> roles = getRolesByUsername(username);
List<String> permissions = getPermissionsByUsername(username);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addRoles(roles);
authorizationInfo.addStringPermissions(permissions);
return authorizationInfo;
}

// 在此方法中完成身份认证逻辑
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取用户提交的用户名和密码
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 根据用户名从数据库中获取用户信息
User user = getUserByUsername(username);
if (user == null) {
throw new UnknownAccountException("用户名不存在");
}
// 对比用户输入的密码和数据库中的密码
if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException("密码不正确");
}
// 返回身份认证信息
return new SimpleAuthenticationInfo(username, password, getName());
}

private User getUserByUsername(String username) {
// 从数据库中获取用户信息
// ...
}

private List<String> getRolesByUsername(String username) {
// 从数据库中获取用户角色信息
// ...
}

private List<String> getPermissionsByUsername(String username) {
// 从数据库中获取用户权限信息
// ...
}
}